SO3LR - pronounced Solar - is a pretrained machine-learned force field for (bio)molecular simulations. It integrates the fast and stable SO3krates neural network for semi-local interactions with universal pairwise force fields designed for short-range repulsion, long-range electrostatics, and dispersion interactions.
First clone the repository and install by doing
git clone https://github.com/general-molecular-simulations/so3lr.git
cd so3lr
pip install .
To get an Atomic Simulation Environment (ASE) calculator with energies and forces predicted from SO3LR just do
import numpy as np
from so3lr import So3lrCalculator
from ase import Atoms
atoms = Atoms(...)
calc = So3lrCalculator(
calculate_stress=False,
dtype=np.float32
)
atoms.calc = calc
energy = atoms.get_potential_energy()
forces = atoms.get_forces()
print('Energy and forces in ASE')
print('Energy = ', energy)
print('Forces = ', forces)
Large scale simulations can be performed via jax-md which is a molecular dynamics library optimized for GPUs. Here we
give a small example for a structure in vacuum. For realistic simulations with periodic water boxes take a look at the
./examples/
folder.
import jax
import jax.numpy as jnp
import numpy as np
from ase import Atoms
from jax_md import space
from jax_md import quantity
from so3lr import to_jax_md
from so3lr import So3lrPotential
atoms = Atoms(...)
assert np.asarray(
atoms.get_pbc()
).all().item() is False, "Readme example assumes no box. See `examples/` folder for simulations in box."
positions = jnp.array(atoms.get_positions())
atomic_numbers = jnp.array(atoms.get_atomic_numbers())
# We assume there is no box.
box = None
displacement, shift = space.free()
neighbor_fn, neighbor_fn_lr, energy_fn = to_jax_md(
potential=So3lrPotential(),
displacement_or_metric=displacement,
box_size=box,
species=atomic_numbers,
capacity_multiplier=1.25,
buffer_size_multiplier_sr=1.25,
buffer_size_multiplier_lr=1.25,
minimum_cell_size_multiplier_sr=1.0,
disable_cell_list=True,
fractional_coordinates=False
)
# Energy and force functions.
energy_fn = jax.jit(energy_fn)
force_fn = jax.jit(quantity.force(energy_fn))
# Initialize the short and long-range neighbor lists.
nbrs = neighbor_fn.allocate(
positions,
box=box
)
nbrs_lr = neighbor_fn_lr.allocate(
positions,
box=box
)
energy = energy_fn(
positions,
neighbor=nbrs.idx,
neighbor_lr=nbrs_lr.idx,
box=box
)
forces = force_fn(
positions,
neighbor=nbrs.idx,
neighbor_lr=nbrs_lr.idx,
box=box
)
print('Energy and forces in JAX-MD')
print('Energy = ', np.array(energy))
print('Forces = ', np.array(forces))
To obtain a potential energy function which is not specifally tailored for jax-md
we provide a convenience
interface. You can do
from so3lr import So3lrPotential
from so3lr import Graph
graph = Graph(...)
so3lr_potential = So3lrPotential()
energy = so3lr_potential(graph)
The Graph
object is a collections.namedtuple
which abstracts the molecule as a graph common practice in the
context of message passing neural networks. The So3lrPotential
is a pure python
function which takes a graph as
an input and returns a potential energy. It is compatible with common jax
transformations as jax.jit
, jax.vmap
,
jax.grad
, ...
. Its use targets developers, interested in integrating SO3LR into their own MD code base. From a
high-level perspective, all that needs to be done is to define some function system_to_graph
which transforms
whatever input structure one has to a Graph
object. Passed to so3lr_potential
one gets the potential energy of
the system.
- Upload the used datasets
- Add FHI-aims calculation example
- Fix typos in tutorial notebooks
- Add functionality to extract observables (dipole moments etc) on a higher level
If you use parts of the code please cite
@article{kabylda2024molecular,
title={Molecular Simulations with a Pretrained Neural Network and Universal Pairwise Force Fields},
author={Kabylda, A. and Frank, J. T. and Dou, S. S. and Khabibrakhmanov, A. and Sandonas, L. M.
and Unke, O. T. and Chmiela, S. and M{\"u}ller, K.R. and Tkatchenko, A.},
journal={ChemRxiv},
year={2024},
doi={10.26434/chemrxiv-2024-bdfr0}
}
@article{frank2024euclidean,
title={A Euclidean transformer for fast and stable machine learned force fields},
author={Frank, Thorben and Unke, Oliver and M{\"u}ller, Klaus-Robert and Chmiela, Stefan},
journal={Nature Communications},
volume={15},
number={1},
pages={6539},
year={2024}
}