A few years ago, running molecular dynamics with ab-initio quality forces meant scheduling time on a supercomputer, submitting to a SLURM queue, and waiting overnight for a few picoseconds of trajectory. In 2026, you can run an equivalent simulation on your laptop in a coffee shop. The enabling technology is the universal machine learning potential, and MACE-MP-0 is the most mature example. This tutorial walks through setting it up.
What you will build
By the end of this tutorial you will have:
- A working Python environment with MACE and ASE.
- A 200-atom silicon supercell at 300 K.
- A 5 picosecond molecular dynamics trajectory.
- A plot of temperature and energy versus time.
No GPU, no cluster, no submission script. If you can run Python, you can run this.
Step 1: Install the tools
The Python packages you need are MACE itself, ASE for the simulation engine, and a recent PyTorch.
python3 -m venv .venv
source .venv/bin/activate
pip install torch
pip install mace-torch
pip install aseThe first install pulls PyTorch, which is the biggest piece. Expect a gigabyte or so of downloads. The rest is small.
Step 2: Set up the calculator
ASE uses the concept of a calculator to delegate energy and force evaluation to whatever engine you want. With MACE, the calculator loads the model once and then responds to structure queries.
from mace.calculators import mace_mp
# The foundation checkpoint, loaded from the MACE package
calc = mace_mp(model="medium", device="cpu")The first time you run this, the MACE package downloads the foundation checkpoint. After that it is cached locally.
Step 3: Build a silicon supercell
We will use ASE's bulk function to build a diamond silicon supercell. 216 atoms (3x3x3 conventional cells) is a good size for laptop MD.
from ase.build import bulk
# 3x3x3 silicon supercell, diamond structure, 5.43 Angstrom lattice
atoms = bulk("Si", "diamond", a=5.43, cubic=True).repeat((3, 3, 3))
atoms.calc = calc
print(f"Number of atoms: {len(atoms)}")
print(f"Initial energy: {atoms.get_potential_energy():.3f} eV")That last line is where the model actually runs. You should see a number in the tens of electronvolts come back. If you see an error about missing packages or CUDA, double-check that the calculator was created with device="cpu".
Step 4: Set up NVT dynamics
We will use a Langevin thermostat to equilibrate the silicon at 300 K. The time step should be 1 femtosecond for a diamond lattice.
from ase.md.langevin import Langevin
from ase import units
import numpy as np
# Set up the dynamics
dyn = Langevin(
atoms,
timestep=1.0 * units.fs,
temperature_K=300,
friction=0.01,
)
# Logging
log_step = []
log_temp = []
log_energy = []
def log():
log_step.append(len(log_step))
log_temp.append(atoms.get_temperature())
log_energy.append(atoms.get_potential_energy())
dyn.attach(log, interval=10)
# Run 5000 steps = 5 picoseconds
dyn.run(5000)On a modern laptop, this will take a few minutes. The per-step time is dominated by the MACE forward pass, which for 216 silicon atoms runs in tens of milliseconds on CPU.
Step 5: Plot the results
After the run completes, you can plot temperature and energy over time to confirm that equilibration looks reasonable.
import matplotlib.pyplot as plt
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(8, 6), sharex=True)
ax1.plot(log_step, log_temp)
ax1.axhline(300, color="red", linestyle="--", label="Target 300 K")
ax1.set_ylabel("Temperature (K)")
ax1.legend()
ax2.plot(log_step, log_energy)
ax2.set_xlabel("Step")
ax2.set_ylabel("Potential energy (eV)")
plt.tight_layout()
plt.savefig("md_equilibration.png", dpi=150)
print("Saved md_equilibration.png")You should see the temperature fluctuate around 300 K after the first few hundred steps, and the potential energy should stabilize at a value corresponding to the thermal excitation of the silicon lattice.
Step 6: Run something more interesting
Once you have the silicon simulation working, try these variations:
- Change the temperature to 1500 K and watch the root mean square displacement grow. You can see premelting if you push hard enough.
- Swap silicon for diamond carbon or germanium. MACE-MP-0 handles all three without changing anything except the element symbol.
- Introduce a vacancy by deleting one atom, then watch its neighborhood relax.
- Try a 2D material like hexagonal boron nitride built with ASE's atoms module.
For a taste of what a slightly more ambitious project looks like, see our battery materials guide.
When you outgrow the laptop
If you need larger systems or longer trajectories than a laptop CPU can handle, two options are easy upgrades. First, run the same Python on a machine with a GPU. The MACE calculator accepts device="cuda" and runs tens of times faster. Second, call MACE through the SciRouter Materials studio which exposes the same model through a hosted API, so you do not need your own GPU at all.
Bottom line
A few picoseconds of DFT-quality molecular dynamics on your laptop, with five commands and no cluster allocation. This was science fiction in 2019. It is a tutorial in 2026. If you have been putting off trying MLIPs because you thought they were exotic or hardware-intensive, try this walkthrough over a coffee break. You will be surprised how much you can do without ever leaving your local Python interpreter.