Download md.py from OneScience-Group/eSEN: direct link, hf CLI and curl.
- Browser
- Download file 2.75 kB
-
https://huggingface.co/OneScience-Group/eSEN/resolve/main/md.py
- Command line
-
hf download hf://OneScience-Group/eSEN/md.py
-
curl -L -o md.py https://huggingface.co/OneScience-Group/eSEN/resolve/main/md.py
2.75 kB
| """Run a short NVT molecular-dynamics trajectory with eSEN.""" | |
| from __future__ import annotations | |
| import argparse | |
| import os | |
| os.environ.setdefault( | |
| "ONESCIENCE_ESEN_JD_PATH", | |
| os.path.join(os.path.dirname(__file__), "weight", "Jd.pt"), | |
| ) | |
| import numpy as np | |
| from ase import units | |
| from ase.build import bulk | |
| from ase.io import read | |
| from ase.io.trajectory import Trajectory | |
| from ase.md.langevin import Langevin | |
| from ase.md.velocitydistribution import MaxwellBoltzmannDistribution, Stationary | |
| from onescience.utils.esen import eSENCalculator | |
| def default_checkpoint() -> str: | |
| return os.path.join(os.path.dirname(__file__), "weight", "esen_30m_mptrj.pt") | |
| def load_structure(path: str | None, repeat: tuple[int, int, int] | None): | |
| if path: | |
| atoms = read(path) | |
| else: | |
| atoms = bulk("Si", "diamond", a=5.43).repeat((2, 2, 2)) | |
| return atoms.repeat(repeat) if repeat else atoms | |
| def main() -> None: | |
| parser = argparse.ArgumentParser(description=__doc__) | |
| parser.add_argument("--checkpoint", default=default_checkpoint()) | |
| parser.add_argument("--input", help="CIF, POSCAR, XYZ, or another ASE-readable structure") | |
| parser.add_argument( | |
| "--repeat", | |
| type=int, | |
| nargs=3, | |
| metavar=("NX", "NY", "NZ"), | |
| help="repeat the input structure along its three cell vectors", | |
| ) | |
| parser.add_argument("--steps", type=int, default=10) | |
| parser.add_argument("--temperature", type=float, default=300.0) | |
| parser.add_argument("--timestep", type=float, default=1.0, help="time step in fs") | |
| parser.add_argument( | |
| "--friction", type=float, default=0.01, help="Langevin friction in 1/fs" | |
| ) | |
| parser.add_argument("--seed", type=int, default=0) | |
| parser.add_argument("--output", default="md.traj") | |
| parser.add_argument("--device", default="cuda") | |
| args = parser.parse_args() | |
| repeat = tuple(args.repeat) if args.repeat else None | |
| atoms = load_structure(args.input, repeat) | |
| atoms.calc = eSENCalculator.from_checkpoint(args.checkpoint, device=args.device) | |
| rng = np.random.default_rng(args.seed) | |
| MaxwellBoltzmannDistribution(atoms, temperature_K=args.temperature, rng=rng) | |
| Stationary(atoms) | |
| dynamics = Langevin( | |
| atoms, | |
| timestep=args.timestep * units.fs, | |
| temperature_K=args.temperature, | |
| friction=args.friction / units.fs, | |
| ) | |
| trajectory = Trajectory(args.output, "w", atoms) | |
| dynamics.attach(trajectory.write, interval=1) | |
| dynamics.run(args.steps) | |
| trajectory.close() | |
| print("formula:", atoms.get_chemical_formula()) | |
| print("atoms:", len(atoms)) | |
| print("steps:", dynamics.nsteps) | |
| print("energy (eV):", atoms.get_potential_energy()) | |
| if __name__ == "__main__": | |
| main() | |