Skip to main content

Overview

The MD task drives ASE molecular dynamics simulations in the NVE, NVT, or NPT ensemble. It supports temperature and pressure schedules (time-varying control), trajectory restart, and multiple integrators per ensemble. The task is registered in Prefect as MD with a TASK_SOURCE + INPUTS cache policy.

Function signature

from mlip_arena.tasks.md import run as MD

result = MD(
    atoms,
    calculator,
    ensemble="nvt",
    dynamics="langevin",
    time_step=None,
    total_time=1000,
    temperature=300.0,
    pressure=None,
    dynamics_kwargs=None,
    velocity_seed=None,
    zero_linear_momentum=True,
    zero_angular_momentum=True,
    traj_file=None,
    traj_interval=1,
    restart=True,
)

Parameters

body.atoms
ase.Atoms
required
The input atomic structure. A copy is made internally.
body.calculator
ase.calculators.calculator.BaseCalculator
required
ASE-compatible calculator for energy and force evaluations.
body.ensemble
string
default:"nvt"
Statistical ensemble for the simulation. Accepted values:
ValueDescription
"nve"Microcanonical — constant energy, volume
"nvt"Canonical — constant temperature, volume
"npt"Isothermal-isobaric — constant temperature, pressure
body.dynamics
string | MolecularDynamics
default:"langevin"
Integrator string name or an ASE MolecularDynamics subclass. Available string values per ensemble:
EnsembleAccepted strings
nve"velocityverlet"
nvt"langevin", "nose-hoover", "andersen", "berendsen"
npt"nose-hoover", "berendsen"
String matching is case-insensitive.
body.time_step
number | None
default:"None"
Integration time step in femtoseconds. When None, defaults to 0.5 fs if the structure contains hydrogen isotopes, or 2.0 fs otherwise.
body.total_time
number
default:"1000"
Total simulation time in femtoseconds. The number of MD steps is computed as int(total_time / time_step).
body.temperature
number | Sequence | np.ndarray | None
default:"300.0"
Temperature target in Kelvin.
  • Scalar (float): constant temperature throughout the run.
  • Sequence / 1-D array: linearly interpolated onto all MD steps to create a temperature schedule (ramp or arbitrary profile).
  • None / ignored for "nve" ensemble.
body.pressure
number | Sequence | np.ndarray | None
default:"None"
External pressure in eV/ų.
  • Scalar (float): constant pressure throughout the run.
  • Sequence / 1-D array: linearly interpolated to create a pressure schedule.
  • Required only for "npt" ensemble; ignored for "nve" and "nvt".
body.dynamics_kwargs
dict | None
default:"None"
Extra keyword arguments forwarded to the integrator constructor. For the Langevin integrator, friction defaults to 10.0 ps⁻¹ (same default as VASP) when not specified. For NPT, the special key fraction_traceless (default 1.0) controls the traceless part of the stress.
body.velocity_seed
number | None
default:"None"
Integer seed for numpy.random.default_rng used to draw the initial Maxwell–Boltzmann velocity distribution. Set for reproducible runs.
body.zero_linear_momentum
boolean
default:"true"
Remove net linear momentum from initial velocities using ASE Stationary.
body.zero_angular_momentum
boolean
default:"true"
Remove net angular momentum from initial velocities using ASE ZeroRotation.
body.traj_file
string | Path | None
default:"None"
Path to an ASE trajectory file (.traj) for writing simulation frames. Parent directories are created automatically. When None, no trajectory is written.
body.traj_interval
number
default:"1"
Write a frame to the trajectory file every traj_interval steps.
body.restart
boolean
default:"true"
When True and traj_file already exists, the simulation resumes from the last frame (positions and momenta are restored). If reading the existing trajectory fails, the run starts fresh.

Return value

{
    "atoms":   Atoms,    # final structure after the simulation
    "runtime": timedelta, # wall-clock time of the MD loop
    "n_steps": int,      # number of steps actually performed
}
atoms
ase.Atoms
Final atomic structure with positions and momenta from the last MD step.
runtime
datetime.timedelta
Wall-clock duration of the MD integration loop.
n_steps
int
Number of MD steps performed (may be less than total_time / time_step when restarting from a partially completed trajectory).

Examples

from ase.build import bulk
from mlip_arena.models import MLIPEnum
from mlip_arena.tasks.md import run as MD
from mlip_arena.tasks.utils import get_calculator

atoms = bulk("Cu", "fcc", a=3.6).repeat(3)
calculator = get_calculator(MLIPEnum["MACE-MP(M)"])

# Microcanonical simulation — no thermostat
result = MD(
    atoms=atoms,
    calculator=calculator,
    ensemble="nve",
    dynamics="velocityverlet",
    time_step=2.0,
    total_time=5000,  # 5 ps
    temperature=300.0,  # used only for initial velocity distribution
    velocity_seed=42,
)

print(f"Simulated {result['n_steps']} steps in {result['runtime']}")
For NPT dynamics the cell is transformed to upper triangular form automatically (required by the ASE NPT implementation). If you supply a non-upper-triangular cell, it will be rotated; the physical geometry is preserved.