ASE calculator¶
FlashCartCalculator evaluates energies,
forces, and stress with ASE. Provide a trained
checkpoint and a structure containing only elements supported by that model.
Reference labels are not required for prediction. The calculator does not
convert units. The examples below use models trained with energies in eV and
positions in Å.
from ase.io import read
from flashcart.calculators import FlashCartCalculator
atoms = read("water_256.extxyz")
atoms.calc = FlashCartCalculator(checkpoint="models/my_run/best", skin=1.0)
energy = atoms.get_potential_energy()
forces = atoms.get_forces()
Calculator options¶
Checkpoints are loaded on CPU by default. Set device="cuda" to use a GPU.
The calculator accepts PyTorch device names. In training configurations,
device: gpu selects GPU execution.
add_atomic_offsets=Truerestores the per-element energy shifts subtracted from the reference energies during training. It changes the total energy but not forces or stress. The default isFalse.skinadds a buffer to the neighbor-list radius without changing the model cutoff. For a fixed cell, the list can be reused until an atom moves byskin / 2from its position when the list was built. Changes to the cell or other atomic properties can also require rebuilding.compile_mode="reduce-overhead"enablestorch.compileand graph padding. Padding keeps input shapes unchanged while the graph fits within the allocated capacities. Larger graphs increase those capacities and can require recompilation. Compilation adds an initial cost but can reduce the time required for repeated evaluations.
Molecular dynamics¶
The repository includes examples/md/ase_md.py, a Langevin molecular dynamics
script. From the repository root, provide a checkpoint directory and an initial
structure:
python examples/md/ase_md.py models/my_run/best structure.extxyz \
--temperature 300 --timestep 0.5 --steps 2000
This runs 1 ps with a time step of 0.5 fs and a target temperature of 300 K.
The script uses the calculator’s CPU default. Every 100 steps, it prints
potential, kinetic, and total energies per atom and writes a frame to md.traj.
Initial velocities are sampled at the requested temperature. The script does not relax the structure before starting dynamics.
To use a GPU or compilation, adjust the calculator construction in the script using the options above.
"""Run Langevin molecular dynamics with ASE and a trained FlashCart model.
python ase_md.py models/i3c3f64l2_s0/best water/water_256.extxyz --steps 2000
Prints the potential, kinetic, and total energy every 100 steps and writes
every 100th frame to md.traj (view it with ``ase gui md.traj``). The water
box comes from water/build_box.py.
"""
import argparse
from ase import units
from ase.io import read
from ase.io.trajectory import Trajectory
from ase.md.langevin import Langevin
from ase.md.velocitydistribution import MaxwellBoltzmannDistribution
from flashcart.calculators import FlashCartCalculator
def main():
parser = argparse.ArgumentParser(description=__doc__.splitlines()[0])
parser.add_argument("checkpoint", help="checkpoint directory, e.g. <output_path>/best")
parser.add_argument("structure", help="any file ASE can read")
parser.add_argument("--steps", type=int, default=2000)
parser.add_argument("--temperature", type=float, default=300.0, help="K")
parser.add_argument("--timestep", type=float, default=0.5, help="fs")
args = parser.parse_args()
atoms = read(args.structure)
atoms.calc = FlashCartCalculator(checkpoint=args.checkpoint, skin=1.0)
MaxwellBoltzmannDistribution(atoms, temperature_K=args.temperature)
dyn = Langevin(
atoms, args.timestep * units.fs, temperature_K=args.temperature, friction=0.01 / units.fs, fixcm=False
)
traj = Trajectory("md.traj", "w", atoms)
def report():
epot, ekin = atoms.get_potential_energy(), atoms.get_kinetic_energy()
n = len(atoms)
print(f"step {dyn.nsteps:6d} Epot {epot / n:9.4f} Ekin {ekin / n:7.4f} Etot {(epot + ekin) / n:9.4f} eV/atom")
dyn.attach(report, interval=100)
dyn.attach(traj.write, interval=100)
dyn.run(args.steps)
if __name__ == "__main__":
main()