A universal material graph interatomic potential with three-body interactions
This repository contains the M3GNet
interatomic potential for the periodic
table. The model has been developed for inorganic crystals using the
Materials Project relaxation trajectory as training data.
Inferences using the pre-trained models can be ran on any standard computer. For model training, the GPU memory needs to be > 18 Gb for a batch size of 32 using the crystal training data. In our work, we used single RTX 3090 GPU for model training.
The package has been tested on the following systems:
- macOS: Monterey 12.1
- Linux: Ubuntu 18.04 (with tensorflow==2.7.0)
- Windows: 11
The following dependencies are needed
pymatgen==2022.2.10
pandas==1.4.1
tensorflow==2.7.0
numpy==1.22.2
monty==2022.3.12
sympy==1.9
ase==3.22.0
cython==0.29.26
m3gnet
can be installed via source code installation by cloning the code from github
git clone git@github.com:JonathanSchmidt1/m3gnet.git
cd m3gnet
pip install -r requirements.txt
python setup.py install
The installation time should be less than 1 minute.
Here is an example of how to run m3gnet
relaxation of any crystals.
from pymatgen.core import Structure, Lattice
from m3gnet.models import Relaxer
# Init a Mo structure with stretched lattice (DFT lattice constant ~ 3.168)
mo = Structure(Lattice.cubic(3.3),
["Mo", "Mo"], [[0., 0., 0.], [0.5, 0.5, 0.5]])
relaxer = Relaxer() # this loads the default model
relax_results = relaxer.relax(mo)
final_structure = relax_results['final_structure']
final_energy = relax_results['trajectory'].energies[-1] / 2
print(f"Relaxed lattice parameter is {final_structure.lattice.abc[0]: .3f} Å")
print(f"Final energy is {final_energy.item(): .3f} eV/atom")
We will see output
Relaxed lattice parameter is 3.169 Å
Final energy is -10.859 eV/atom
The original lattice parameter of
3.3 Å
was successfully relaxed to 3.169 Å
, close to the DFT value of 3.168 Å
.
The final energy -10.859 eV/atom
is also close to DFT value of -10.8456 eV/atom
.
The relaxation takes less than 20 seconds.
Molecular dynamics simulations can be easily performed as well.
from pymatgen.core import Structure, Lattice
from m3gnet.models import MolecularDynamics
# Init a Mo structure with stretched lattice (DFT lattice constant ~ 3.168)
mo = Structure(Lattice.cubic(3.3),
["Mo", "Mo"], [[0., 0., 0.], [0.5, 0.5, 0.5]])
md = MolecularDynamics(
atoms=mo,
temperature=1000, # 1000 K
ensemble='nvt', # NVT ensemble
timestep=1, # 1fs,
trajectory="mo.traj", # save trajectory to mo.traj
logfile="mo.log", # log file for MD
loginterval=100, # interval for record the log
)
md.run(steps=1000)
After the run, mo.log
contains thermodynamic information similar to the
following
Time[ps] Etot[eV] Epot[eV] Ekin[eV] T[K]
0.0000 -21.3307 -21.3307 0.0000 0.0
0.1000 -21.3307 -21.3307 0.0000 0.0
0.2000 -21.2441 -21.3087 0.0645 249.7
0.3000 -21.0466 -21.2358 0.1891 731.6
0.4000 -20.9702 -21.1149 0.1447 559.6
0.5000 -20.9380 -21.1093 0.1713 662.6
0.6000 -20.9176 -21.1376 0.2200 850.9
0.7000 -20.9016 -21.1789 0.2773 1072.8
0.8000 -20.8804 -21.1638 0.2835 1096.4
0.9000 -20.8770 -21.0695 0.1925 744.5
1.0000 -20.8908 -21.0772 0.1864 721.2
The MD run takes less than 1 minute.
The potential model can be trained using the PotentialTrainer
in m3gnet.trainers
.
The training dataset can be
- structures, a list of pymatgen Structures
- energies, a list of energy floats
- forces, a list of nx3 force matrix, where
n
is the number of atom in each structure.n
does not need to be the same for all structures. - stresses, a list of 3x3 stress matrix.
where the stresses
is optional.
For the stresses
, we use the convention that compressive stress gives
negative values. VASP
stress should change signs to work directly with
the model.
We use validation dataset to select the stopping epoch number. The dataset has similar format as the training dataset.
A minimal example of model training is shown below.
from m3gnet.models import M3GNet, Potential
from m3gnet.trainers import PotentialTrainer
import tensorflow as tf
m3gnet = M3GNet(is_intensive=False)
potential = Potential(model=m3gnet)
trainer = PotentialTrainer(
potential=potential, optimizer=tf.keras.optimizers.Adam(1e-3)
)
trainer.train(
structures,
energies,
forces,
stresses,
validation_graphs_or_structures=val_structures,
val_energies=val_energies,
val_forces=val_forces,
val_stresses=val_stresses,
epochs=100,
fit_per_element_offset=True,
save_checkpoint=False,
)
The training data MPF.2021.2.8
is hosted on figshare
with DOI 10.6084/m9.figshare.19470599
.
This package is the result from our recent paper
Chi Chen, and Shyue Ping Ong. "A Universal Graph Deep Learning Interatomic Potential for the Periodic Table." arXiv preprint arXiv:2202.02450 (2022).