ASE interface

The easiest way to obtain potentials and forces from established codes is to use the interfaces implemented in ASE.

We provide the AdiabaticASEModel which wraps an ASE atoms object and its associated calculator to implement the required potential and derivative functions.

Note

The interface works by calling the relevant Python functions using PyCall. To use PyCall, you must make sure that your python version contains all the relevant packages, such as ase. PyCall can be configured to use a particular pre-installed Python or install its own. Refer to the PyCall README for installation and configuration instructions.

Example

First, it is necessary to import ase and create the ase.Atoms object and attach the desired calculator. This works exactly as in Python:

using PythonCall: pyimport, pylist
using ASEconvert

emt = pyimport("ase.calculators.emt")

h2 = ase.Atoms("H2", pylist([(0, 0, 0), (0, 0, 0.74)]))
h2.calc = emt.EMT()
    CondaPkg Found dependencies: /home/runner/.julia/packages/ASEconvert/yMJC2/CondaPkg.toml
    CondaPkg Found dependencies: /home/runner/.julia/packages/PythonCall/bb3ax/CondaPkg.toml
    CondaPkg Dependencies already up to date

Next, the AdiabaticASEModel is created by passing the ase.Atoms object directly to the model:

julia> using NQCModels
julia> model = AdiabaticASEModel(h2)AdiabaticASEModel{PythonCall.Core.Py}(<py Atoms(symbols='H2', pbc=False, calculator=EMT(...))>)

Now the model can be used in the same way as any of the previously introduced analytic models.

julia> potential(model, rand(3, 2))ERROR: MethodError: no method matching *(::PythonCall.Core.Py, ::Unitful.FreeUnits{(eV,), 𝐋^2 𝐌 𝐓^-2, nothing})

Closest candidates are:
  *(::Any, ::Any, ::Any, ::Any...)
   @ Base operators.jl:587
  *(::PythonCall.Core.Py, ::PythonCall.Core.Py)
   @ PythonCall ~/.julia/packages/PythonCall/bb3ax/src/Core/Py.jl:382
  *(::PythonCall.Core.Py, ::Number)
   @ PythonCall ~/.julia/packages/PythonCall/bb3ax/src/Core/Py.jl:413
  ...
julia> derivative(model, rand(3, 2))ERROR: MethodError: no method matching adjoint(::PythonCall.Core.Py) Closest candidates are: adjoint(::SciMLOperators.IdentityOperator) @ SciMLOperators ~/.julia/packages/SciMLOperators/Kto0y/src/basic.jl:22 adjoint(::Graphs.DefaultDistance) @ Graphs ~/.julia/packages/Graphs/czpTe/src/distance.jl:24 adjoint(::SciMLOperators.NullOperator) @ SciMLOperators ~/.julia/packages/SciMLOperators/Kto0y/src/basic.jl:115 ...
Tip

In theory, this should work with any of the ASE calculators that correctly implement the get_potential_energy and get_forces functions. For instance, you can use SchNetPack (SPK) by passing their ASE calculator to the AdiabaticASEModel. Take a look at Neural network models to learn more.