Introduction to foundational models for molecular dynamics

Authors:

Paolo Pegolo @ppegolo

Foundational (or universal) machine-learning interatomic potentials are trained once on broad, chemically diverse datasets, with the goal of describing essentially any system without specific re-parameterization. This recipe illustrates the concept: we take a single foundational model, PET-MAD-XS (which spans 102 elements of the periodic table), and use it, unchanged, to run molecular dynamics on four qualitatively different aqueous systems:

  • pure liquid water

  • a NaCl aqueous solution

  • an ethanol-water mixture

  • superionic water, an exotic phase found deep inside the ice-giant planets

For each system we provide the LAMMPS input that drives a short constant-temperature simulation through the metatomic pair style. The first three (water, NaCl, ethanol-water) are light enough to run live; the fourth (superionic water) is more demanding, so for it we analyze a pre-computed trajectory.

# sphinx_gallery_thumbnail_number = 3

Setup

We download a small archive with the data we need: the starting structures and the pre-computed trajectory for the superionic system (the first three runs are launched live below). The LAMMPS dump format stores the full cell information together with unwrapped Cartesian coordinates (xu yu zu), which makes part of the analysis below straightforward.

from zipfile import ZipFile
import numpy as np
import matplotlib.pyplot as plt
import ase.io
from ase.geometry.rdf import get_rdf
import chemiscope
import upet
from atomistic_cookbook_utils import download_with_retry, run_command

download_with_retry(
    "https://github.com/ppegolo/labcosmo_ictp_school/raw/refs/heads/tmp/water-md.zip",
    "data.zip",
)

with ZipFile("data.zip", "r") as z:
    z.extractall(".")

PET-MAD-XS through metatomic

PET-MAD is a foundational potential trained on the MAD (Massive Atomic Diversity) dataset, version 1.5, a deliberately heterogeneous collection of structures spanning 102 elements. PET-MAD-XS (“extra small”) is the lightest and fastest version: it trades some accuracy for speed, but the same recipe works unchanged with the larger versions (S, M, L).

The model ships as a single file and is coupled to a simulation engine through metatomic, the software that exposes the same potential to several simulation engines, including i-PI, LAMMPS, gromacs, and ASE through a common API. In every LAMMPS input below the potential is loaded with a single line:

pair_style metatomic pet-mad-xs-v1.5.0.pt device cpu

(use device cuda to run on a GPU instead).

We fetch the model once with upet and save it to the file the LAMMPS inputs load (pet-mad-xs-v1.5.0.pt); every run below picks it up through the metatomic pair style.

model_path = "pet-mad-xs-v1.5.0.pt"
upet.save_upet(model="pet-mad", size="xs", version="1.5.0", output=model_path)
Warning: You are sending unauthenticated requests to the HF Hub. Please set a HF_TOKEN to enable higher rate limits and faster downloads.
WARNING:huggingface_hub.utils._http:Warning: You are sending unauthenticated requests to the HF Hub. Please set a HF_TOKEN to enable higher rate limits and faster downloads.
/home/runner/work/atomistic-cookbook/atomistic-cookbook/.nox/water-md/lib/python3.12/site-packages/metatrain/pet/model.py:1031: UserWarning: the 'non_conservative_forces' output name is deprecated, please update the model to use 'non_conservative_force' instead
  return AtomisticModel(self.eval(), metadata, capabilities)
/home/runner/work/atomistic-cookbook/atomistic-cookbook/.nox/water-md/lib/python3.12/site-packages/metatrain/pet/model.py:1031: UserWarning: the 'non_conservative_forces' output name is deprecated, please update the model to use 'non_conservative_force' instead
  return AtomisticModel(self.eval(), metadata, capabilities)
/home/runner/work/atomistic-cookbook/atomistic-cookbook/.nox/water-md/lib/python3.12/site-packages/metatrain/llpr/model.py:1249: UserWarning: the 'non_conservative_forces' output name is deprecated, please update the model to use 'non_conservative_force' instead
  return AtomisticModel(self.eval(), metadata, self.capabilities)

Liquid water at 400 K

We start with a simple case: 64 water molecules in a cubic, periodic box, propagated in the canonical (NVT) ensemble. This is the complete LAMMPS input:

# Liquid water NVT at 400 K with PET-MAD-xs
# Atom types: 1=H, 2=O

units metal
atom_style atomic

variable seed       index 12345
variable t_target   equal 400.0
variable tdamp      equal 100*dt       # thermostat time constant
variable nsteps     equal 500         # 500 * 0.5 fs = 0.25 ps
variable dump_every equal 10

read_data data/water.data

pair_style metatomic pet-mad-xs-v1.5.0.pt device cpu
pair_coeff * * 1 8

timestep 0.0005

neighbor 2.0 bin
neigh_modify one 50000 page 500000

thermo_style custom step temp pe etotal press vol
thermo 10

velocity all create ${t_target} ${seed} mom yes rot yes dist gaussian
reset_timestep 0

fix nve_int   all nve
fix thermostat all temp/csvr ${t_target} ${t_target} ${tdamp} ${seed}

print "step temp pe etotal press vol" file water_thermo.out
fix thermofile all print ${dump_every} "$(step) $(temp) $(pe) $(etotal) $(press) $(vol)" append water_thermo.out

dump traj all custom ${dump_every} water_traj.lammpstrj id type element xu yu zu
dump_modify traj element H O sort id

run ${nsteps}

Several of these settings recur in every simulation below and are worth a closer look:

  • Potential and element map. pair_style metatomic instructs LAMMPS to use the metatomic model to compute forces; the single pair_coeff * * 1 8 line is the only chemistry-specific input, mapping LAMMPS atom type 1 to hydrogen (Z=1) and type 2 to oxygen (Z=8).

  • Ensemble. fix nve propagates the equations of motion with the velocity-Verlet integrator, while fix temp/csvr adds a stochastic velocity-rescaling thermostat (the Bussi-Donadio-Parrinello, or CSVR, thermostat) on top. Together they sample the canonical ensemble. CSVR reproduces the exact canonical velocity distribution while disturbing the dynamics minimally, which makes it a very common choice, especially when one wants to compute dynamical observables.

  • Thermostat coupling time. tdamp = 100*dt (here 50 fs) sets how strongly the thermostat couples to the system: 100 times the integration time step is usually loose enough not to damp the physical motion we want to measure, tight enough to keep the temperature steady over the run.

  • Timestep. timestep 0.0005 is 0.5 fs. The fastest motion is the O-H stretch (period ≈ 10 fs), so half a femtosecond samples it about twenty times per oscillation, enough for stable, accurate integration.

  • Temperature. We run at 400 K rather than 300 K because the electronic-structure reference of the MAD dataset (the r2SCAN functional) overstructures liquid water and raises its melting point by a few tens of kelvin. Working slightly above ambient keeps the system liquid and accelerates sampling.

These runs are intentionally short, so they reproduce quickly, but long enough to show some structure and stable dynamics. The only precomputed trajectories are for superionic water, which requires shorter time-steps and longer dynamics.

Each input reads its starting structure from data/ and is launched with a single command, which we run here:

run_command("lmp -in in_water_nvt.lmp", print_output=True)
LAMMPS (4 Jul 2026)
OMP_NUM_THREADS environment is not set. Defaulting to 1 thread.
  using 1 OpenMP thread(s) per MPI task
Reading data file ...
  orthogonal box = (0.73005488 0.73005488 0.73005488) to (13.254708 13.254708 13.254708)
  1 by 1 by 1 MPI processor grid
  reading atoms ...
  192 atoms
  reading velocities ...
  192 velocities
  read_data CPU = 0.001 seconds

This is the PET-MAD-XS v1.5.0 model
===================================

A universal interatomic potential for advanced materials modeling based on a
Point-Edge Transformer (PET) architecture, and trained on the MAD dataset.
Model size: xs. Model version: 1.5.0.

Model authors
-------------

- Arslan Mazitov ([email protected])
- Filippo Bigi
- Matthias Kellner
- Paolo Pegolo
- Davide Tisi
- Guillaume Fraux
- Sergey Pozdnyakov
- Philip Loche
- Michele Ceriotti ([email protected])

Model references
----------------

Please cite the following references when using this model:
- about this specific model:
  * https://doi.org/10.1038/s41467-025-65662-7
  * https://arxiv.org/abs/2601.16195
- about the architecture of this model:
  * LLPR (uncertainty method):
    https://iopscience.iop.org/article/10.1088/2632-2153/ad805f
  * LPR (if using per-atom uncertainty):
    https://pubs.acs.org/doi/10.1021/acs.jctc.3c00704
  * https://arxiv.org/abs/2305.19302v3

Found 'energy_uncertainty' output, we will check for atoms with high uncertainty on the energy predictions
[W1112 22:35:38.572243866 module.cpp:218] Warning: module does not have '_mts_buffer_names'; falling back to processing all attributes. This is deprecated and will be removed in a future version, update your version of metatensor-learn and use `register_buffer` explicitly to remove this warning. (function operator())
Running simulation on cpu device with float32 data
step temp pe etotal press vol

CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE

Your simulation uses code contributions which should be cited:
- LLPR (uncertainty method): https://iopscience.iop.org/article/10.1088/2632-2153/ad805f
- LPR (if using per-atom uncertainty): https://pubs.acs.org/doi/10.1021/acs.jctc.3c00704
- https://arxiv.org/abs/2305.19302v3
- https://doi.org/10.1038/s41467-025-65662-7
- https://arxiv.org/abs/2601.16195
The log file lists these citations in BibTeX format.

CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE

Neighbor list info ...
  update: every = 1 steps, delay = 0 steps, check = yes
  max neighbors/atom: 50000, page size: 500000
  master list distance cutoff = 17
  ghost atom cutoff = 17
  binsize = 8.5, bins = 2 2 2
  1 neighbor lists, perpetual/occasional/extra = 1 0 0
  (1) pair metatomic, perpetual
      attributes: full, newton on, ghost
      pair build: full/bin/ghost
      stencil: full/ghost/bin/3d
      bin: standard
Setting up Verlet run ...
  Unit style    : metal
  Current step  : 0
  Time step     : 5e-04
0 400.00000000000011369 -1009.419189453125 -999.54371437512497778 6880.8960567258991432 1964.7040162035737012
Per MPI rank memory allocation (min/avg/max) = 58.34 | 58.34 | 58.34 Mbytes
   Step          Temp          PotEng         TotEng         Press          Volume
         0   400           -1009.4192     -999.54371      6880.8961      1964.704
10 353.47651034321540919 -1008.317138671875 -999.59026750049292787 -1875.0756223653033885 1964.7040162035737012
        10   353.47651     -1008.3171     -999.59027     -1875.0756      1964.704
20 350.42521281030826685 -1008.11572265625 -999.46418401672235632 12577.696343279831126 1964.7040162035737012
        20   350.42521     -1008.1157     -999.46418      12577.696      1964.704
30 336.1002360139348184 -1007.68682861328125 -999.38895485211742198 -3756.7197451692964023 1964.7040162035737012
        30   336.10024     -1007.6868     -999.38895     -3756.7197      1964.704
40 373.63773949462597557 -1008.28289794921875 -999.05827248777018212 13656.7152473466831 1964.7040162035737012
        40   373.63774     -1008.2829     -999.05827      13656.715      1964.704
50 368.59600128231846838 -1007.88623046875 -998.78607890746502562 -6488.2693937542599087 1964.7040162035737012
        50   368.596       -1007.8862     -998.78608     -6488.2694      1964.704
60 377.42001111670504088 -1008.47088623046875 -999.15288144616499721 15124.637591448228704 1964.7040162035737012
        60   377.42001     -1008.4709     -999.15288      15124.638      1964.704
70 360.77919042227858881 -1007.9412841796875 -999.03411942049694972 -5968.3958833969045372 1964.7040162035737012
        70   360.77919     -1007.9413     -999.03412     -5968.3959      1964.704
80 349.77203123083870651 -1008.0147705078125 -999.3793580643085761 14524.144998203531941 1964.7040162035737012
        80   349.77203     -1008.0148     -999.37936      14524.145      1964.704
90 359.54689760107788743 -1007.82354736328125 -998.94680629670210692 -4206.6467043190041295 1964.7040162035737012
        90   359.5469      -1007.8235     -998.94681     -4206.6467      1964.704
100 388.6034627864041795 -1008.54681396484375 -998.9527044349146081 10931.248982186205467 1964.7040162035737012
       100   388.60346     -1008.5468     -998.9527       10931.249      1964.704
110 369.89689135351926552 -1008.023193359375 -998.89092452939667055 -2798.426630698889312 1964.7040162035737012
       110   369.89689     -1008.0232     -998.89092     -2798.4266      1964.704
120 358.43583122643929073 -1007.99346923828125 -999.14415894243393268 11552.504383854700791 1964.7040162035737012
       120   358.43583     -1007.9935     -999.14416      11552.504      1964.704
130 360.78572933201127171 -1007.83673095703125 -998.92940476074045364 -2903.6197654289467209 1964.7040162035737012
       130   360.78573     -1007.8367     -998.9294      -2903.6198      1964.704
140 395.74289786652957446 -1008.54547119140625 -998.77509837846525897 9687.0042892123128695 1964.7040162035737012
       140   395.7429      -1008.5455     -998.7751       9687.0043      1964.704
150 394.10500567597682675 -1008.5372314453125 -998.80729604114208087 -2159.3213168419047179 1964.7040162035737012
       150   394.10501     -1008.5372     -998.8073      -2159.3213      1964.704
160 399.73344786160038211 -1008.686279296875 -998.81738504137433665 8889.0967524455118109 1964.7040162035737012
       160   399.73345     -1008.6863     -998.81739      8889.0968      1964.704
170 393.39304854998289329 -1008.6815185546875 -998.96916043765304494 -2420.761259329470704 1964.7040162035737012
       170   393.39305     -1008.6815     -998.96916     -2420.7613      1964.704
180 391.78834732723043999 -1008.68365478515625 -999.01091463545401439 8432.5562911392844399 1964.7040162035737012
       180   391.78835     -1008.6837     -999.01091      8432.5563      1964.704
190 406.13357187365073742 -1008.752685546875 -998.72578062843160751 -1333.4173700740179811 1964.7040162035737012
       190   406.13357     -1008.7527     -998.72578     -1333.4174      1964.704
200 389.63308430280829953 -1008.7650146484375 -999.14548511444581891 7129.2778736422260408 1964.7040162035737012
       200   389.63308     -1008.765      -999.14549      7129.2779      1964.704
210 394.64274720853410372 -1008.83770751953125 -999.09449598260289349 74.524881759373855061 1964.7040162035737012
       210   394.64275     -1008.8377     -999.0945       74.524882      1964.704
220 381.54878831612228396 -1008.41510009765625 -998.99516122251384331 5540.9455056147453433 1964.7040162035737012
       220   381.54879     -1008.4151     -998.99516      5540.9455      1964.704
230 381.56113794131022132 -1008.43719482421875 -999.01695105303690525 923.45187001665556181 1964.7040162035737012
       230   381.56114     -1008.4372     -999.01695      923.45187      1964.704
240 373.48059786154050244 -1008.4359130859375 -999.21516724519199215 5091.0791300453474832 1964.7040162035737012
       240   373.4806      -1008.4359     -999.21517      5091.0791      1964.704
250 387.02705380540891156 -1008.63494873046875 -999.07975866955109723 1588.9113017713843874 1964.7040162035737012
       250   387.02705     -1008.6349     -999.07976      1588.9113      1964.704
260 356.23139130355502857 -1008.2626953125 -999.46780974545117715 2719.4791534856171893 1964.7040162035737012
       260   356.23139     -1008.2627     -999.46781      2719.4792      1964.704
270 366.61901408075704012 -1008.1405029296875 -999.08916058799889015 4083.6567290128546119 1964.7040162035737012
       270   366.61901     -1008.1405     -999.08916      4083.6567      1964.704
280 368.77457976471407619 -1008.3409423828125 -999.23638195314663335 -1703.554631299625953 1964.7040162035737012
       280   368.77458     -1008.3409     -999.23638     -1703.5546      1964.704
290 370.72648603574856452 -1008.3848876953125 -999.23213726131109524 6641.9899854506256816 1964.7040162035737012
       290   370.72649     -1008.3849     -999.23214      6641.99        1964.704
300 368.67986620939200293 -1008.09234619140625 -998.99012411512819654 -3881.5236584435765508 1964.7040162035737012
       300   368.67987     -1008.0923     -998.99012     -3881.5237      1964.704
310 358.98884329390347148 -1008.02972412109375 -999.16676068302126623 7507.4072714544872724 1964.7040162035737012
       310   358.98884     -1008.0297     -999.16676      7507.4073      1964.704
320 349.97981262145452774 -1007.76055908203125 -999.12001678866556631 -6354.7572427802197126 1964.7040162035737012
       320   349.97981     -1007.7606     -999.12002     -6354.7572      1964.704
330 372.32907062995343495 -1008.10015869140625 -998.90784254685377164 9368.2646881409182242 1964.7040162035737012
       330   372.32907     -1008.1002     -998.90784      9368.2647      1964.704
340 349.43663271529874237 -1007.68450927734375 -999.05737738304333106 -6739.6707301232445388 1964.7040162035737012
       340   349.43663     -1007.6845     -999.05738     -6739.6707      1964.704
350 338.3274197719276799 -1007.50921630859375 -999.15635630318945459 9455.8344396419433906 1964.7040162035737012
       350   338.32742     -1007.5092     -999.15636      9455.8344      1964.704
360 325.71412708702666805 -1007.15118408203125 -999.10972972053014018 -4990.5671701844266863 1964.7040162035737012
       360   325.71413     -1007.1512     -999.10973     -4990.5672      1964.704
370 354.15084755193544197 -1007.5224609375 -998.77894126537069042 7604.5628213891304767 1964.7040162035737012
       370   354.15085     -1007.5225     -998.77894      7604.5628      1964.704
380 370.26932205453937286 -1007.7275390625 -998.58607540725608942 -3773.9854505193738987 1964.7040162035737012
       380   370.26932     -1007.7275     -998.58608     -3773.9855      1964.704
390 370.98158723816379734 -1007.41815185546875 -998.25910330755027644 2424.1003832805395177 1964.7040162035737012
       390   370.98159     -1007.4182     -998.2591       2424.1004      1964.704
400 355.28465088347263645 -1006.99615478515625 -998.22464299666705756 421.10809505087871685 1964.7040162035737012
       400   355.28465     -1006.9962     -998.22464      421.1081       1964.704
410 357.52203384498272953 -1007.2379150390625 -998.4111652013824596 -949.83486119004157899 1964.7040162035737012
       410   357.52203     -1007.2379     -998.41117     -949.83486      1964.704
420 370.23649825866630181 -1007.41839599609375 -998.27774271729515476 1959.5625642427869479 1964.7040162035737012
       420   370.2365      -1007.4184     -998.27774      1959.5626      1964.704
430 361.60696424369689339 -1007.01629638671875 -998.08869497816908734 -4093.7286607283353987 1964.7040162035737012
       430   361.60696     -1007.0163     -998.08869     -4093.7287      1964.704
440 336.39549100029483952 -1006.65399169921875 -998.34882847990627397 4009.8439689740098402 1964.7040162035737012
       440   336.39549     -1006.654      -998.34883      4009.844       1964.704
450 342.11410957188053317 -1006.59759521484375 -998.15124680757060105 -4112.5877294622960108 1964.7040162035737012
       450   342.11411     -1006.5976     -998.15125     -4112.5877      1964.704
460 373.1116772285663501 -1007.12127685546875 -997.9096391810149953 3004.9169817790225352 1964.7040162035737012
       460   373.11168     -1007.1213     -997.90964      3004.917       1964.704
470 358.06668721407288558 -1006.990478515625 -998.15028190101349992 -5493.3630523104202439 1964.7040162035737012
       470   358.06669     -1006.9905     -998.15028     -5493.3631      1964.704
480 374.20418670052868038 -1007.2386474609375 -998.00003716132664522 1194.3189909235295545 1964.7040162035737012
       480   374.20419     -1007.2386     -998.00004      1194.319       1964.704
490 387.95626025605781706 -1007.2105712890625 -997.63244034028059559 -3981.3613706568189627 1964.7040162035737012
       490   387.95626     -1007.2106     -997.63244     -3981.3614      1964.704
500 383.1954161697070731 -1007.3896484375 -997.92905648153055154 -254.44980384965245435 1964.7040162035737012
       500   383.19542     -1007.3896     -997.92906     -254.4498       1964.704
Loop time of 96.4124 on 1 procs for 500 steps with 192 atoms

Performance: 0.224 ns/day, 107.125 hours/ns, 5.186 timesteps/s, 995.722 atom-step/s
89.5% CPU use with 1 MPI tasks x 1 OpenMP threads

MPI task timing breakdown:
Section |  min time  |  avg time  |  max time  |%varavg| %total
---------------------------------------------------------------
Pair    | 95.331     | 95.331     | 95.331     |   0.0 | 98.88
Neigh   | 1.0358     | 1.0358     | 1.0358     |   0.0 |  1.07
Comm    | 0.024334   | 0.024334   | 0.024334   |   0.0 |  0.03
Output  | 0.0064362  | 0.0064362  | 0.0064362  |   0.0 |  0.01
Modify  | 0.011485   | 0.011485   | 0.011485   |   0.0 |  0.01
Other   |            | 0.003286   |            |       |  0.00

Nlocal:            192 ave         192 max         192 min
Histogram: 1 0 0 0 0 0 0 0 0 0
Nghost:           9642 ave        9642 max        9642 min
Histogram: 1 0 0 0 0 0 0 0 0 0
Neighs:              0 ave           0 max           0 min
Histogram: 1 0 0 0 0 0 0 0 0 0
FullNghs:       385200 ave      385200 max      385200 min
Histogram: 1 0 0 0 0 0 0 0 0 0

Total # of neighbors = 385200
Ave neighs/atom = 2006.25
Neighbor list builds = 8
Dangerous builds = 0
Total wall time: 0:01:37

CompletedProcess(args=['lmp', '-in', 'in_water_nvt.lmp'], returncode=0, stdout="LAMMPS (4 Jul 2026)\nOMP_NUM_THREADS environment is not set. Defaulting to 1 thread.\n  using 1 OpenMP thread(s) per MPI task\nReading data file ...\n  orthogonal box = (0.73005488 0.73005488 0.73005488) to (13.254708 13.254708 13.254708)\n  1 by 1 by 1 MPI processor grid\n  reading atoms ...\n  192 atoms\n  reading velocities ...\n  192 velocities\n  read_data CPU = 0.001 seconds\n\nThis is the PET-MAD-XS v1.5.0 model\n===================================\n\nA universal interatomic potential for advanced materials modeling based on a\nPoint-Edge Transformer (PET) architecture, and trained on the MAD dataset.\nModel size: xs. Model version: 1.5.0.\n\nModel authors\n-------------\n\n- Arslan Mazitov ([email protected])\n- Filippo Bigi\n- Matthias Kellner\n- Paolo Pegolo\n- Davide Tisi\n- Guillaume Fraux\n- Sergey Pozdnyakov\n- Philip Loche\n- Michele Ceriotti ([email protected])\n\nModel references\n----------------\n\nPlease cite the following references when using this model:\n- about this specific model:\n  * https://doi.org/10.1038/s41467-025-65662-7\n  * https://arxiv.org/abs/2601.16195\n- about the architecture of this model:\n  * LLPR (uncertainty method):\n    https://iopscience.iop.org/article/10.1088/2632-2153/ad805f\n  * LPR (if using per-atom uncertainty):\n    https://pubs.acs.org/doi/10.1021/acs.jctc.3c00704\n  * https://arxiv.org/abs/2305.19302v3\n\nFound 'energy_uncertainty' output, we will check for atoms with high uncertainty on the energy predictions\n[W1112 22:35:38.572243866 module.cpp:218] Warning: module does not have '_mts_buffer_names'; falling back to processing all attributes. This is deprecated and will be removed in a future version, update your version of metatensor-learn and use `register_buffer` explicitly to remove this warning. (function operator())\nRunning simulation on cpu device with float32 data\nstep temp pe etotal press vol\n\nCITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE\n\nYour simulation uses code contributions which should be cited:\n- LLPR (uncertainty method): https://iopscience.iop.org/article/10.1088/2632-2153/ad805f\n- LPR (if using per-atom uncertainty): https://pubs.acs.org/doi/10.1021/acs.jctc.3c00704\n- https://arxiv.org/abs/2305.19302v3\n- https://doi.org/10.1038/s41467-025-65662-7\n- https://arxiv.org/abs/2601.16195\nThe log file lists these citations in BibTeX format.\n\nCITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE\n\nNeighbor list info ...\n  update: every = 1 steps, delay = 0 steps, check = yes\n  max neighbors/atom: 50000, page size: 500000\n  master list distance cutoff = 17\n  ghost atom cutoff = 17\n  binsize = 8.5, bins = 2 2 2\n  1 neighbor lists, perpetual/occasional/extra = 1 0 0\n  (1) pair metatomic, perpetual\n      attributes: full, newton on, ghost\n      pair build: full/bin/ghost\n      stencil: full/ghost/bin/3d\n      bin: standard\nSetting up Verlet run ...\n  Unit style    : metal\n  Current step  : 0\n  Time step     : 5e-04\n0 400.00000000000011369 -1009.419189453125 -999.54371437512497778 6880.8960567258991432 1964.7040162035737012\nPer MPI rank memory allocation (min/avg/max) = 58.34 | 58.34 | 58.34 Mbytes\n   Step          Temp          PotEng         TotEng         Press          Volume    \n         0   400           -1009.4192     -999.54371      6880.8961      1964.704     \n10 353.47651034321540919 -1008.317138671875 -999.59026750049292787 -1875.0756223653033885 1964.7040162035737012\n        10   353.47651     -1008.3171     -999.59027     -1875.0756      1964.704     \n20 350.42521281030826685 -1008.11572265625 -999.46418401672235632 12577.696343279831126 1964.7040162035737012\n        20   350.42521     -1008.1157     -999.46418      12577.696      1964.704     \n30 336.1002360139348184 -1007.68682861328125 -999.38895485211742198 -3756.7197451692964023 1964.7040162035737012\n        30   336.10024     -1007.6868     -999.38895     -3756.7197      1964.704     \n40 373.63773949462597557 -1008.28289794921875 -999.05827248777018212 13656.7152473466831 1964.7040162035737012\n        40   373.63774     -1008.2829     -999.05827      13656.715      1964.704     \n50 368.59600128231846838 -1007.88623046875 -998.78607890746502562 -6488.2693937542599087 1964.7040162035737012\n        50   368.596       -1007.8862     -998.78608     -6488.2694      1964.704     \n60 377.42001111670504088 -1008.47088623046875 -999.15288144616499721 15124.637591448228704 1964.7040162035737012\n        60   377.42001     -1008.4709     -999.15288      15124.638      1964.704     \n70 360.77919042227858881 -1007.9412841796875 -999.03411942049694972 -5968.3958833969045372 1964.7040162035737012\n        70   360.77919     -1007.9413     -999.03412     -5968.3959      1964.704     \n80 349.77203123083870651 -1008.0147705078125 -999.3793580643085761 14524.144998203531941 1964.7040162035737012\n        80   349.77203     -1008.0148     -999.37936      14524.145      1964.704     \n90 359.54689760107788743 -1007.82354736328125 -998.94680629670210692 -4206.6467043190041295 1964.7040162035737012\n        90   359.5469      -1007.8235     -998.94681     -4206.6467      1964.704     \n100 388.6034627864041795 -1008.54681396484375 -998.9527044349146081 10931.248982186205467 1964.7040162035737012\n       100   388.60346     -1008.5468     -998.9527       10931.249      1964.704     \n110 369.89689135351926552 -1008.023193359375 -998.89092452939667055 -2798.426630698889312 1964.7040162035737012\n       110   369.89689     -1008.0232     -998.89092     -2798.4266      1964.704     \n120 358.43583122643929073 -1007.99346923828125 -999.14415894243393268 11552.504383854700791 1964.7040162035737012\n       120   358.43583     -1007.9935     -999.14416      11552.504      1964.704     \n130 360.78572933201127171 -1007.83673095703125 -998.92940476074045364 -2903.6197654289467209 1964.7040162035737012\n       130   360.78573     -1007.8367     -998.9294      -2903.6198      1964.704     \n140 395.74289786652957446 -1008.54547119140625 -998.77509837846525897 9687.0042892123128695 1964.7040162035737012\n       140   395.7429      -1008.5455     -998.7751       9687.0043      1964.704     \n150 394.10500567597682675 -1008.5372314453125 -998.80729604114208087 -2159.3213168419047179 1964.7040162035737012\n       150   394.10501     -1008.5372     -998.8073      -2159.3213      1964.704     \n160 399.73344786160038211 -1008.686279296875 -998.81738504137433665 8889.0967524455118109 1964.7040162035737012\n       160   399.73345     -1008.6863     -998.81739      8889.0968      1964.704     \n170 393.39304854998289329 -1008.6815185546875 -998.96916043765304494 -2420.761259329470704 1964.7040162035737012\n       170   393.39305     -1008.6815     -998.96916     -2420.7613      1964.704     \n180 391.78834732723043999 -1008.68365478515625 -999.01091463545401439 8432.5562911392844399 1964.7040162035737012\n       180   391.78835     -1008.6837     -999.01091      8432.5563      1964.704     \n190 406.13357187365073742 -1008.752685546875 -998.72578062843160751 -1333.4173700740179811 1964.7040162035737012\n       190   406.13357     -1008.7527     -998.72578     -1333.4174      1964.704     \n200 389.63308430280829953 -1008.7650146484375 -999.14548511444581891 7129.2778736422260408 1964.7040162035737012\n       200   389.63308     -1008.765      -999.14549      7129.2779      1964.704     \n210 394.64274720853410372 -1008.83770751953125 -999.09449598260289349 74.524881759373855061 1964.7040162035737012\n       210   394.64275     -1008.8377     -999.0945       74.524882      1964.704     \n220 381.54878831612228396 -1008.41510009765625 -998.99516122251384331 5540.9455056147453433 1964.7040162035737012\n       220   381.54879     -1008.4151     -998.99516      5540.9455      1964.704     \n230 381.56113794131022132 -1008.43719482421875 -999.01695105303690525 923.45187001665556181 1964.7040162035737012\n       230   381.56114     -1008.4372     -999.01695      923.45187      1964.704     \n240 373.48059786154050244 -1008.4359130859375 -999.21516724519199215 5091.0791300453474832 1964.7040162035737012\n       240   373.4806      -1008.4359     -999.21517      5091.0791      1964.704     \n250 387.02705380540891156 -1008.63494873046875 -999.07975866955109723 1588.9113017713843874 1964.7040162035737012\n       250   387.02705     -1008.6349     -999.07976      1588.9113      1964.704     \n260 356.23139130355502857 -1008.2626953125 -999.46780974545117715 2719.4791534856171893 1964.7040162035737012\n       260   356.23139     -1008.2627     -999.46781      2719.4792      1964.704     \n270 366.61901408075704012 -1008.1405029296875 -999.08916058799889015 4083.6567290128546119 1964.7040162035737012\n       270   366.61901     -1008.1405     -999.08916      4083.6567      1964.704     \n280 368.77457976471407619 -1008.3409423828125 -999.23638195314663335 -1703.554631299625953 1964.7040162035737012\n       280   368.77458     -1008.3409     -999.23638     -1703.5546      1964.704     \n290 370.72648603574856452 -1008.3848876953125 -999.23213726131109524 6641.9899854506256816 1964.7040162035737012\n       290   370.72649     -1008.3849     -999.23214      6641.99        1964.704     \n300 368.67986620939200293 -1008.09234619140625 -998.99012411512819654 -3881.5236584435765508 1964.7040162035737012\n       300   368.67987     -1008.0923     -998.99012     -3881.5237      1964.704     \n310 358.98884329390347148 -1008.02972412109375 -999.16676068302126623 7507.4072714544872724 1964.7040162035737012\n       310   358.98884     -1008.0297     -999.16676      7507.4073      1964.704     \n320 349.97981262145452774 -1007.76055908203125 -999.12001678866556631 -6354.7572427802197126 1964.7040162035737012\n       320   349.97981     -1007.7606     -999.12002     -6354.7572      1964.704     \n330 372.32907062995343495 -1008.10015869140625 -998.90784254685377164 9368.2646881409182242 1964.7040162035737012\n       330   372.32907     -1008.1002     -998.90784      9368.2647      1964.704     \n340 349.43663271529874237 -1007.68450927734375 -999.05737738304333106 -6739.6707301232445388 1964.7040162035737012\n       340   349.43663     -1007.6845     -999.05738     -6739.6707      1964.704     \n350 338.3274197719276799 -1007.50921630859375 -999.15635630318945459 9455.8344396419433906 1964.7040162035737012\n       350   338.32742     -1007.5092     -999.15636      9455.8344      1964.704     \n360 325.71412708702666805 -1007.15118408203125 -999.10972972053014018 -4990.5671701844266863 1964.7040162035737012\n       360   325.71413     -1007.1512     -999.10973     -4990.5672      1964.704     \n370 354.15084755193544197 -1007.5224609375 -998.77894126537069042 7604.5628213891304767 1964.7040162035737012\n       370   354.15085     -1007.5225     -998.77894      7604.5628      1964.704     \n380 370.26932205453937286 -1007.7275390625 -998.58607540725608942 -3773.9854505193738987 1964.7040162035737012\n       380   370.26932     -1007.7275     -998.58608     -3773.9855      1964.704     \n390 370.98158723816379734 -1007.41815185546875 -998.25910330755027644 2424.1003832805395177 1964.7040162035737012\n       390   370.98159     -1007.4182     -998.2591       2424.1004      1964.704     \n400 355.28465088347263645 -1006.99615478515625 -998.22464299666705756 421.10809505087871685 1964.7040162035737012\n       400   355.28465     -1006.9962     -998.22464      421.1081       1964.704     \n410 357.52203384498272953 -1007.2379150390625 -998.4111652013824596 -949.83486119004157899 1964.7040162035737012\n       410   357.52203     -1007.2379     -998.41117     -949.83486      1964.704     \n420 370.23649825866630181 -1007.41839599609375 -998.27774271729515476 1959.5625642427869479 1964.7040162035737012\n       420   370.2365      -1007.4184     -998.27774      1959.5626      1964.704     \n430 361.60696424369689339 -1007.01629638671875 -998.08869497816908734 -4093.7286607283353987 1964.7040162035737012\n       430   361.60696     -1007.0163     -998.08869     -4093.7287      1964.704     \n440 336.39549100029483952 -1006.65399169921875 -998.34882847990627397 4009.8439689740098402 1964.7040162035737012\n       440   336.39549     -1006.654      -998.34883      4009.844       1964.704     \n450 342.11410957188053317 -1006.59759521484375 -998.15124680757060105 -4112.5877294622960108 1964.7040162035737012\n       450   342.11411     -1006.5976     -998.15125     -4112.5877      1964.704     \n460 373.1116772285663501 -1007.12127685546875 -997.9096391810149953 3004.9169817790225352 1964.7040162035737012\n       460   373.11168     -1007.1213     -997.90964      3004.917       1964.704     \n470 358.06668721407288558 -1006.990478515625 -998.15028190101349992 -5493.3630523104202439 1964.7040162035737012\n       470   358.06669     -1006.9905     -998.15028     -5493.3631      1964.704     \n480 374.20418670052868038 -1007.2386474609375 -998.00003716132664522 1194.3189909235295545 1964.7040162035737012\n       480   374.20419     -1007.2386     -998.00004      1194.319       1964.704     \n490 387.95626025605781706 -1007.2105712890625 -997.63244034028059559 -3981.3613706568189627 1964.7040162035737012\n       490   387.95626     -1007.2106     -997.63244     -3981.3614      1964.704     \n500 383.1954161697070731 -1007.3896484375 -997.92905648153055154 -254.44980384965245435 1964.7040162035737012\n       500   383.19542     -1007.3896     -997.92906     -254.4498       1964.704     \nLoop time of 96.4124 on 1 procs for 500 steps with 192 atoms\n\nPerformance: 0.224 ns/day, 107.125 hours/ns, 5.186 timesteps/s, 995.722 atom-step/s\n89.5% CPU use with 1 MPI tasks x 1 OpenMP threads\n\nMPI task timing breakdown:\nSection |  min time  |  avg time  |  max time  |%varavg| %total\n---------------------------------------------------------------\nPair    | 95.331     | 95.331     | 95.331     |   0.0 | 98.88\nNeigh   | 1.0358     | 1.0358     | 1.0358     |   0.0 |  1.07\nComm    | 0.024334   | 0.024334   | 0.024334   |   0.0 |  0.03\nOutput  | 0.0064362  | 0.0064362  | 0.0064362  |   0.0 |  0.01\nModify  | 0.011485   | 0.011485   | 0.011485   |   0.0 |  0.01\nOther   |            | 0.003286   |            |       |  0.00\n\nNlocal:            192 ave         192 max         192 min\nHistogram: 1 0 0 0 0 0 0 0 0 0\nNghost:           9642 ave        9642 max        9642 min\nHistogram: 1 0 0 0 0 0 0 0 0 0\nNeighs:              0 ave           0 max           0 min\nHistogram: 1 0 0 0 0 0 0 0 0 0\nFullNghs:       385200 ave      385200 max      385200 min\nHistogram: 1 0 0 0 0 0 0 0 0 0\n\nTotal # of neighbors = 385200\nAve neighs/atom = 2006.25\nNeighbor list builds = 8\nDangerous builds = 0\nTotal wall time: 0:01:37\n")

As a first sanity check we plot the temperature and potential energy along the trajectory: the thermostat should hold the temperature near its 400 K target (fluctuations are expected, given the small system). After a brief equilibration the potential energy should settle around a stable mean, with no long-term drift.

water_thermo = np.loadtxt("water_thermo.out", skiprows=1)
# columns: step temp pe etotal press vol
time_ps = water_thermo[:, 0] * 0.0005  # step × dt (0.5 fs) in ps

fig, axes = plt.subplots(1, 2, figsize=(10, 4), dpi=200)
axes[0].plot(time_ps, water_thermo[:, 1])
axes[0].set(xlabel="Time (ps)", ylabel="Temperature (K)", title="Temperature")
axes[1].plot(time_ps, water_thermo[:, 2])
axes[1].set(
    xlabel="Time (ps)", ylabel="Potential energy (eV)", title="Potential energy"
)
fig.tight_layout()
plt.show()
Temperature, Potential energy

We can also inspect the trajectory interactively. Water molecules diffuse and the hydrogen-bond network continuously rearranges.

water_traj = ase.io.read("water_traj.lammpstrj", ":", format="lammps-dump-text")
for frame in water_traj:
    frame.wrap()
chemiscope.show(
    structures=water_traj,
    mode="structure",
    settings=chemiscope.quick_settings(
        trajectory=True,
        structure_settings={"playbackDelay": 20, "unitCell": True},
    ),
)

Loading icon


Adding ions: NaCl in water

PET-MAD can handle in principle any stable chemical element. We start by dissolving two NaCl units (two Na⁺ and two Cl⁻ ions) in 60 water molecules, a roughly 1.8 M solution. The only change to the LAMMPS input is the element map: the pair_coeff line now also assigns Na (Z=11) and Cl (Z=17). No new parameters and no retraining are involved: the same weights describe ion-water and ion-ion interactions out of the box.

# NaCl aqueous solution NVT at 400 K with PET-MAD-xs
# Atom types: 1=H, 2=O, 3=Na, 4=Cl

units metal
atom_style atomic

variable seed       index 23456
variable t_target   equal 400.0
variable tdamp      equal 100*dt
variable nsteps     equal 500         # 500 * 0.5 fs = 0.25 ps
variable dump_every equal 10

read_data data/nacl.data

pair_style metatomic pet-mad-xs-v1.5.0.pt device cpu
pair_coeff * * 1 8 11 17

timestep 0.0005

neighbor 2.0 bin
neigh_modify one 50000 page 500000

thermo_style custom step temp pe etotal press vol
thermo 10

velocity all create ${t_target} ${seed} mom yes rot yes dist gaussian
reset_timestep 0

fix nve_int   all nve
fix thermostat all temp/csvr ${t_target} ${t_target} ${tdamp} ${seed}

print "step temp pe etotal press vol" file nacl_thermo.out
fix thermofile all print ${dump_every} "$(step) $(temp) $(pe) $(etotal) $(press) $(vol)" append nacl_thermo.out

dump traj all custom ${dump_every} nacl_traj.lammpstrj id type element xu yu zu
dump_modify traj element H O Na Cl sort id

run ${nsteps}
run_command("lmp -in in_nacl_nvt.lmp", print_output=True)
LAMMPS (4 Jul 2026)
OMP_NUM_THREADS environment is not set. Defaulting to 1 thread.
  using 1 OpenMP thread(s) per MPI task
Reading data file ...
  orthogonal box = (0.95507965 0.95507965 0.95507965) to (13.141811 13.141811 13.141811)
  1 by 1 by 1 MPI processor grid
  reading atoms ...
  184 atoms
  reading velocities ...
  184 velocities
  read_data CPU = 0.001 seconds

This is the PET-MAD-XS v1.5.0 model
===================================

A universal interatomic potential for advanced materials modeling based on a
Point-Edge Transformer (PET) architecture, and trained on the MAD dataset.
Model size: xs. Model version: 1.5.0.

Model authors
-------------

- Arslan Mazitov ([email protected])
- Filippo Bigi
- Matthias Kellner
- Paolo Pegolo
- Davide Tisi
- Guillaume Fraux
- Sergey Pozdnyakov
- Philip Loche
- Michele Ceriotti ([email protected])

Model references
----------------

Please cite the following references when using this model:
- about this specific model:
  * https://doi.org/10.1038/s41467-025-65662-7
  * https://arxiv.org/abs/2601.16195
- about the architecture of this model:
  * LLPR (uncertainty method):
    https://iopscience.iop.org/article/10.1088/2632-2153/ad805f
  * LPR (if using per-atom uncertainty):
    https://pubs.acs.org/doi/10.1021/acs.jctc.3c00704
  * https://arxiv.org/abs/2305.19302v3

Found 'energy_uncertainty' output, we will check for atoms with high uncertainty on the energy predictions
[W1112 22:37:16.728367972 module.cpp:218] Warning: module does not have '_mts_buffer_names'; falling back to processing all attributes. This is deprecated and will be removed in a future version, update your version of metatensor-learn and use `register_buffer` explicitly to remove this warning. (function operator())
Running simulation on cpu device with float32 data
step temp pe etotal press vol

CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE

Your simulation uses code contributions which should be cited:
- LLPR (uncertainty method): https://iopscience.iop.org/article/10.1088/2632-2153/ad805f
- LPR (if using per-atom uncertainty): https://pubs.acs.org/doi/10.1021/acs.jctc.3c00704
- https://arxiv.org/abs/2305.19302v3
- https://doi.org/10.1038/s41467-025-65662-7
- https://arxiv.org/abs/2601.16195
The log file lists these citations in BibTeX format.

CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE

Neighbor list info ...
  update: every = 1 steps, delay = 0 steps, check = yes
  max neighbors/atom: 50000, page size: 500000
  master list distance cutoff = 17
  ghost atom cutoff = 17
  binsize = 8.5, bins = 2 2 2
  1 neighbor lists, perpetual/occasional/extra = 1 0 0
  (1) pair metatomic, perpetual
      attributes: full, newton on, ghost
      pair build: full/bin/ghost
      stencil: full/ghost/bin/3d
      bin: standard
Setting up Verlet run ...
  Unit style    : metal
  Current step  : 0
  Time step     : 5e-04
0 400.0000000000003979 -959.44195556640625 -949.98011295240621621 6335.7549538093817318 1809.9298793830914747
Per MPI rank memory allocation (min/avg/max) = 60.24 | 60.24 | 60.24 Mbytes
   Step          Temp          PotEng         TotEng         Press          Volume
         0   400           -959.44196     -949.98011      6335.755       1809.9299
10 357.76270136866310168 -958.8070068359375 -950.34427090216308898 -4157.8629208241200104 1809.9298793830914747
        10   357.7627      -958.80701     -950.34427     -4157.8629      1809.9299
20 368.2313956257402765 -958.78961181640625 -950.07924303904542285 6893.2132518616199377 1809.9298793830914747
        20   368.2314      -958.78961     -950.07924      6893.2133      1809.9299
30 377.54361026649974065 -958.9130859375 -949.98244038684254065 -3363.3847967695915031 1809.9298793830914747
        30   377.54361     -958.91309     -949.98244     -3363.3848      1809.9299
40 401.97242399286898262 -959.4512939453125 -949.94279441784101436 3892.1394653452580314 1809.9298793830914747
        40   401.97242     -959.45129     -949.94279      3892.1395      1809.9299
50 390.11838080151500208 -958.847412109375 -949.61931530944389124 -3125.7976544292077961 1809.9298793830914747
        50   390.11838     -958.84741     -949.61932     -3125.7977      1809.9299
60 386.20364715920112531 -958.65234375 -949.51684843406712844 4062.0612724453812916 1809.9298793830914747
        60   386.20365     -958.65234     -949.51685      4062.0613      1809.9299
70 353.71238858351682666 -958.32366943359375 -949.956742055095674 865.02153831453586008 1809.9298793830914747
        70   353.71239     -958.32367     -949.95674      865.02154      1809.9299
80 359.76838551701052893 -958.33544921875 -949.82526961561291046 1907.8110746174854739 1809.9298793830914747
        80   359.76839     -958.33545     -949.82527      1907.8111      1809.9299
90 352.06678692479886195 -957.8079833984375 -949.47998207968964834 3620.8438756366390407 1809.9298793830914747
        90   352.06679     -957.80798     -949.47998      3620.8439      1809.9299
100 358.18235134928096386 -958.34326171875 -949.87059912980157605 2566.473967981273745 1809.9298793830914747
       100   358.18235     -958.34326     -949.8706       2566.474       1809.9299
110 363.88334083473250757 -958.43194580078125 -949.82442854869429993 1234.8566694970288609 1809.9298793830914747
       110   363.88334     -958.43195     -949.82443      1234.8567      1809.9299
120 373.82342524926855276 -958.70703125 -949.86438521216257413 2094.8943130351972286 1809.9298793830914747
       120   373.82343     -958.70703     -949.86439      2094.8943      1809.9299
130 368.08427457452256704 -958.3759765625 -949.66908787571878747 -378.42231312886991645 1809.9298793830914747
       130   368.08427     -958.37598     -949.66909     -378.42231      1809.9299
140 368.27450218901969947 -958.5618896484375 -949.85050120228322612 3698.8597652647417817 1809.9298793830914747
       140   368.2745      -958.56189     -949.8505       3698.8598      1809.9299
150 363.86393982424090154 -958.3436279296875 -949.73656960087021162 -1021.8411772040705046 1809.9298793830914747
       150   363.86394     -958.34363     -949.73657     -1021.8412      1809.9299
160 376.88530236228092463 -958.6251220703125 -949.71004853410818214 3818.0540117032560374 1809.9298793830914747
       160   376.8853      -958.62512     -949.71005      3818.054       1809.9299
170 370.01742805759852217 -958.29583740234375 -949.54322073054856901 -1560.5347033240848305 1809.9298793830914747
       170   370.01743     -958.29584     -949.54322     -1560.5347      1809.9299
180 375.20697524693821379 -958.2528076171875 -949.37743424853374563 7268.9324810175121456 1809.9298793830914747
       180   375.20698     -958.25281     -949.37743      7268.9325      1809.9299
190 368.71585445181131035 -958.04571533203125 -949.32388687175728137 -1773.6827925224718001 1809.9298793830914747
       190   368.71585     -958.04572     -949.32389     -1773.6828      1809.9299
200 395.51712363634868552 -958.24554443359375 -948.8897424961210163 7414.0000078246730482 1809.9298793830914747
       200   395.51712     -958.24554     -948.88974      7414           1809.9299
210 408.67912003430245704 -958.3060302734375 -948.63888648995600761 -5245.7495408454005883 1809.9298793830914747
       210   408.67912     -958.30603     -948.63889     -5245.7495      1809.9299
220 390.90929619250670157 -958.05902099609375 -948.81221540378624013 9910.7577994477378525 1809.9298793830914747
       220   390.9093      -958.05902     -948.81222      9910.7578      1809.9299
230 364.84071214120450577 -957.48834228515625 -948.8581787915068162 -2397.5339159197751542 1809.9298793830914747
       230   364.84071     -957.48834     -948.85818     -2397.5339      1809.9299
240 386.76912590282285009 -957.663330078125 -948.51445858500790109 8076.86192415374353 1809.9298793830914747
       240   386.76913     -957.66333     -948.51446      8076.8619      1809.9299
250 370.72894673783054031 -957.7017822265625 -948.93233486034409907 -2306.3223410830269131 1809.9298793830914747
       250   370.72895     -957.70178     -948.93233     -2306.3223      1809.9299
260 383.43137578340559912 -958.25836181640625 -949.18844348907600761 6073.1066072935045668 1809.9298793830914747
       260   383.43138     -958.25836     -949.18844      6073.1066      1809.9299
270 373.25424608491709932 -958.096923828125 -949.26774149946822945 508.04752117434082948 1809.9298793830914747
       270   373.25425     -958.09692     -949.26774      508.04752      1809.9299
280 368.81270525464429966 -958.204345703125 -949.48022627521743289 2777.0725966917971164 1809.9298793830914747
       280   368.81271     -958.20435     -949.48023      2777.0726      1809.9299
290 376.21677847444868803 -958.04461669921875 -949.14535683254041487 1492.4762343307020274 1809.9298793830914747
       290   376.21678     -958.04462     -949.14536      1492.4762      1809.9299
300 374.30667327966455105 -958.2183837890625 -949.36430670920719876 -645.28430971218278955 1809.9298793830914747
       300   374.30667     -958.21838     -949.36431     -645.28431      1809.9299
310 361.44552299349192026 -958.01593017578125 -949.46607854553292327 3105.0892987513620938 1809.9298793830914747
       310   361.44552     -958.01593     -949.46608      3105.0893      1809.9299
320 349.80745753863863001 -957.9735107421875 -949.69895297110224419 -379.13226111580485167 1809.9298793830914747
       320   349.80746     -957.97351     -949.69895     -379.13226      1809.9299
330 355.28235181499576356 -957.98529052734375 -949.58122628633054774 1854.6336502830301924 1809.9298793830914747
       330   355.28235     -957.98529     -949.58123      1854.6337      1809.9299
340 381.020044753571824 -958.40716552734375 -949.39428628674988886 -839.95248540467298426 1809.9298793830914747
       340   381.02004     -958.40717     -949.39429     -839.95249      1809.9299
350 373.81607171690615132 -957.98480224609375 -949.14233015317097397 2729.9399222625347647 1809.9298793830914747
       350   373.81607     -957.9848      -949.14233      2729.9399      1809.9299
360 386.35484846762648203 -958.3848876953125 -949.2458157719212295 911.84361643808006193 1809.9298793830914747
       360   386.35485     -958.38489     -949.24582      911.84362      1809.9299
370 366.83628494289740729 -958.5029296875 -949.82556170441466747 -2075.2851000857053805 1809.9298793830914747
       370   366.83628     -958.50293     -949.82556     -2075.2851      1809.9299
380 380.42193095523185775 -958.48736572265625 -949.4886346286252774 4381.8674187077322131 1809.9298793830914747
       380   380.42193     -958.48737     -949.48863      4381.8674      1809.9299
390 347.34769606009774634 -957.6953125 -949.47893941885956792 -2456.6105419831615109 1809.9298793830914747
       390   347.3477      -957.69531     -949.47894     -2456.6105      1809.9299
400 352.97610167536896597 -957.91729736328125 -949.5677865618922624 7865.9368940733102136 1809.9298793830914747
       400   352.9761      -957.9173      -949.56779      7865.9369      1809.9299
410 353.10666018450081083 -957.73779296875 -949.38519385719769161 -4989.7809190577308982 1809.9298793830914747
       410   353.10666     -957.73779     -949.38519     -4989.7809      1809.9299
420 369.12890951348498447 -958.27557373046875 -949.54397461523365109 8734.8565660249405482 1809.9298793830914747
       420   369.12891     -958.27557     -949.54397      8734.8566      1809.9299
430 341.24601204841138724 -957.774658203125 -949.70261805648192421 -5312.7471148321346845 1809.9298793830914747
       430   341.24601     -957.77466     -949.70262     -5312.7471      1809.9299
440 338.93406866984810222 -957.77581787109375 -949.75846583540180745 10912.954742425434233 1809.9298793830914747
       440   338.93407     -957.77582     -949.75847      10912.955      1809.9299
450 347.03217177807630378 -957.72894287109375 -949.52003339269685966 -5333.438674577346319 1809.9298793830914747
       450   347.03217     -957.72894     -949.52003     -5333.4387      1809.9299
460 356.21562833728677333 -957.97454833984375 -949.54840780990741678 8940.4830165785897407 1809.9298793830914747
       460   356.21563     -957.97455     -949.54841      8940.483       1809.9299
470 370.31347369663683367 -958.25762939453125 -949.49800987962828458 -3376.2427915034259058 1809.9298793830914747
       470   370.31347     -958.25763     -949.49801     -3376.2428      1809.9299
480 366.28611203962304899 -958.01123046875 -949.34687660921781571 6831.6791024523818123 1809.9298793830914747
       480   366.28611     -958.01123     -949.34688      6831.6791      1809.9299
490 366.20898906280382334 -957.9986572265625 -949.336127680701793 -1089.3675463962440517 1809.9298793830914747
       490   366.20899     -957.99866     -949.33613     -1089.3675      1809.9299
500 365.27188681451849561 -958.096923828125 -949.45656106723049561 4678.6586299143518772 1809.9298793830914747
       500   365.27189     -958.09692     -949.45656      4678.6586      1809.9299
Loop time of 97.3972 on 1 procs for 500 steps with 184 atoms

Performance: 0.222 ns/day, 108.219 hours/ns, 5.134 timesteps/s, 944.586 atom-step/s
88.4% CPU use with 1 MPI tasks x 1 OpenMP threads

MPI task timing breakdown:
Section |  min time  |  avg time  |  max time  |%varavg| %total
---------------------------------------------------------------
Pair    | 96.421     | 96.421     | 96.421     |   0.0 | 99.00
Neigh   | 0.93273    | 0.93273    | 0.93273    |   0.0 |  0.96
Comm    | 0.0245     | 0.0245     | 0.0245     |   0.0 |  0.03
Output  | 0.0062822  | 0.0062822  | 0.0062822  |   0.0 |  0.01
Modify  | 0.0094216  | 0.0094216  | 0.0094216  |   0.0 |  0.01
Other   |            | 0.003157   |            |       |  0.00

Nlocal:            184 ave         184 max         184 min
Histogram: 1 0 0 0 0 0 0 0 0 0
Nghost:           9765 ave        9765 max        9765 min
Histogram: 1 0 0 0 0 0 0 0 0 0
Neighs:              0 ave           0 max           0 min
Histogram: 1 0 0 0 0 0 0 0 0 0
FullNghs:       383610 ave      383610 max      383610 min
Histogram: 1 0 0 0 0 0 0 0 0 0

Total # of neighbors = 383610
Ave neighs/atom = 2084.837
Neighbor list builds = 7
Dangerous builds = 0
Total wall time: 0:01:38

CompletedProcess(args=['lmp', '-in', 'in_nacl_nvt.lmp'], returncode=0, stdout="LAMMPS (4 Jul 2026)\nOMP_NUM_THREADS environment is not set. Defaulting to 1 thread.\n  using 1 OpenMP thread(s) per MPI task\nReading data file ...\n  orthogonal box = (0.95507965 0.95507965 0.95507965) to (13.141811 13.141811 13.141811)\n  1 by 1 by 1 MPI processor grid\n  reading atoms ...\n  184 atoms\n  reading velocities ...\n  184 velocities\n  read_data CPU = 0.001 seconds\n\nThis is the PET-MAD-XS v1.5.0 model\n===================================\n\nA universal interatomic potential for advanced materials modeling based on a\nPoint-Edge Transformer (PET) architecture, and trained on the MAD dataset.\nModel size: xs. Model version: 1.5.0.\n\nModel authors\n-------------\n\n- Arslan Mazitov ([email protected])\n- Filippo Bigi\n- Matthias Kellner\n- Paolo Pegolo\n- Davide Tisi\n- Guillaume Fraux\n- Sergey Pozdnyakov\n- Philip Loche\n- Michele Ceriotti ([email protected])\n\nModel references\n----------------\n\nPlease cite the following references when using this model:\n- about this specific model:\n  * https://doi.org/10.1038/s41467-025-65662-7\n  * https://arxiv.org/abs/2601.16195\n- about the architecture of this model:\n  * LLPR (uncertainty method):\n    https://iopscience.iop.org/article/10.1088/2632-2153/ad805f\n  * LPR (if using per-atom uncertainty):\n    https://pubs.acs.org/doi/10.1021/acs.jctc.3c00704\n  * https://arxiv.org/abs/2305.19302v3\n\nFound 'energy_uncertainty' output, we will check for atoms with high uncertainty on the energy predictions\n[W1112 22:37:16.728367972 module.cpp:218] Warning: module does not have '_mts_buffer_names'; falling back to processing all attributes. This is deprecated and will be removed in a future version, update your version of metatensor-learn and use `register_buffer` explicitly to remove this warning. (function operator())\nRunning simulation on cpu device with float32 data\nstep temp pe etotal press vol\n\nCITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE\n\nYour simulation uses code contributions which should be cited:\n- LLPR (uncertainty method): https://iopscience.iop.org/article/10.1088/2632-2153/ad805f\n- LPR (if using per-atom uncertainty): https://pubs.acs.org/doi/10.1021/acs.jctc.3c00704\n- https://arxiv.org/abs/2305.19302v3\n- https://doi.org/10.1038/s41467-025-65662-7\n- https://arxiv.org/abs/2601.16195\nThe log file lists these citations in BibTeX format.\n\nCITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE\n\nNeighbor list info ...\n  update: every = 1 steps, delay = 0 steps, check = yes\n  max neighbors/atom: 50000, page size: 500000\n  master list distance cutoff = 17\n  ghost atom cutoff = 17\n  binsize = 8.5, bins = 2 2 2\n  1 neighbor lists, perpetual/occasional/extra = 1 0 0\n  (1) pair metatomic, perpetual\n      attributes: full, newton on, ghost\n      pair build: full/bin/ghost\n      stencil: full/ghost/bin/3d\n      bin: standard\nSetting up Verlet run ...\n  Unit style    : metal\n  Current step  : 0\n  Time step     : 5e-04\n0 400.0000000000003979 -959.44195556640625 -949.98011295240621621 6335.7549538093817318 1809.9298793830914747\nPer MPI rank memory allocation (min/avg/max) = 60.24 | 60.24 | 60.24 Mbytes\n   Step          Temp          PotEng         TotEng         Press          Volume    \n         0   400           -959.44196     -949.98011      6335.755       1809.9299    \n10 357.76270136866310168 -958.8070068359375 -950.34427090216308898 -4157.8629208241200104 1809.9298793830914747\n        10   357.7627      -958.80701     -950.34427     -4157.8629      1809.9299    \n20 368.2313956257402765 -958.78961181640625 -950.07924303904542285 6893.2132518616199377 1809.9298793830914747\n        20   368.2314      -958.78961     -950.07924      6893.2133      1809.9299    \n30 377.54361026649974065 -958.9130859375 -949.98244038684254065 -3363.3847967695915031 1809.9298793830914747\n        30   377.54361     -958.91309     -949.98244     -3363.3848      1809.9299    \n40 401.97242399286898262 -959.4512939453125 -949.94279441784101436 3892.1394653452580314 1809.9298793830914747\n        40   401.97242     -959.45129     -949.94279      3892.1395      1809.9299    \n50 390.11838080151500208 -958.847412109375 -949.61931530944389124 -3125.7976544292077961 1809.9298793830914747\n        50   390.11838     -958.84741     -949.61932     -3125.7977      1809.9299    \n60 386.20364715920112531 -958.65234375 -949.51684843406712844 4062.0612724453812916 1809.9298793830914747\n        60   386.20365     -958.65234     -949.51685      4062.0613      1809.9299    \n70 353.71238858351682666 -958.32366943359375 -949.956742055095674 865.02153831453586008 1809.9298793830914747\n        70   353.71239     -958.32367     -949.95674      865.02154      1809.9299    \n80 359.76838551701052893 -958.33544921875 -949.82526961561291046 1907.8110746174854739 1809.9298793830914747\n        80   359.76839     -958.33545     -949.82527      1907.8111      1809.9299    \n90 352.06678692479886195 -957.8079833984375 -949.47998207968964834 3620.8438756366390407 1809.9298793830914747\n        90   352.06679     -957.80798     -949.47998      3620.8439      1809.9299    \n100 358.18235134928096386 -958.34326171875 -949.87059912980157605 2566.473967981273745 1809.9298793830914747\n       100   358.18235     -958.34326     -949.8706       2566.474       1809.9299    \n110 363.88334083473250757 -958.43194580078125 -949.82442854869429993 1234.8566694970288609 1809.9298793830914747\n       110   363.88334     -958.43195     -949.82443      1234.8567      1809.9299    \n120 373.82342524926855276 -958.70703125 -949.86438521216257413 2094.8943130351972286 1809.9298793830914747\n       120   373.82343     -958.70703     -949.86439      2094.8943      1809.9299    \n130 368.08427457452256704 -958.3759765625 -949.66908787571878747 -378.42231312886991645 1809.9298793830914747\n       130   368.08427     -958.37598     -949.66909     -378.42231      1809.9299    \n140 368.27450218901969947 -958.5618896484375 -949.85050120228322612 3698.8597652647417817 1809.9298793830914747\n       140   368.2745      -958.56189     -949.8505       3698.8598      1809.9299    \n150 363.86393982424090154 -958.3436279296875 -949.73656960087021162 -1021.8411772040705046 1809.9298793830914747\n       150   363.86394     -958.34363     -949.73657     -1021.8412      1809.9299    \n160 376.88530236228092463 -958.6251220703125 -949.71004853410818214 3818.0540117032560374 1809.9298793830914747\n       160   376.8853      -958.62512     -949.71005      3818.054       1809.9299    \n170 370.01742805759852217 -958.29583740234375 -949.54322073054856901 -1560.5347033240848305 1809.9298793830914747\n       170   370.01743     -958.29584     -949.54322     -1560.5347      1809.9299    \n180 375.20697524693821379 -958.2528076171875 -949.37743424853374563 7268.9324810175121456 1809.9298793830914747\n       180   375.20698     -958.25281     -949.37743      7268.9325      1809.9299    \n190 368.71585445181131035 -958.04571533203125 -949.32388687175728137 -1773.6827925224718001 1809.9298793830914747\n       190   368.71585     -958.04572     -949.32389     -1773.6828      1809.9299    \n200 395.51712363634868552 -958.24554443359375 -948.8897424961210163 7414.0000078246730482 1809.9298793830914747\n       200   395.51712     -958.24554     -948.88974      7414           1809.9299    \n210 408.67912003430245704 -958.3060302734375 -948.63888648995600761 -5245.7495408454005883 1809.9298793830914747\n       210   408.67912     -958.30603     -948.63889     -5245.7495      1809.9299    \n220 390.90929619250670157 -958.05902099609375 -948.81221540378624013 9910.7577994477378525 1809.9298793830914747\n       220   390.9093      -958.05902     -948.81222      9910.7578      1809.9299    \n230 364.84071214120450577 -957.48834228515625 -948.8581787915068162 -2397.5339159197751542 1809.9298793830914747\n       230   364.84071     -957.48834     -948.85818     -2397.5339      1809.9299    \n240 386.76912590282285009 -957.663330078125 -948.51445858500790109 8076.86192415374353 1809.9298793830914747\n       240   386.76913     -957.66333     -948.51446      8076.8619      1809.9299    \n250 370.72894673783054031 -957.7017822265625 -948.93233486034409907 -2306.3223410830269131 1809.9298793830914747\n       250   370.72895     -957.70178     -948.93233     -2306.3223      1809.9299    \n260 383.43137578340559912 -958.25836181640625 -949.18844348907600761 6073.1066072935045668 1809.9298793830914747\n       260   383.43138     -958.25836     -949.18844      6073.1066      1809.9299    \n270 373.25424608491709932 -958.096923828125 -949.26774149946822945 508.04752117434082948 1809.9298793830914747\n       270   373.25425     -958.09692     -949.26774      508.04752      1809.9299    \n280 368.81270525464429966 -958.204345703125 -949.48022627521743289 2777.0725966917971164 1809.9298793830914747\n       280   368.81271     -958.20435     -949.48023      2777.0726      1809.9299    \n290 376.21677847444868803 -958.04461669921875 -949.14535683254041487 1492.4762343307020274 1809.9298793830914747\n       290   376.21678     -958.04462     -949.14536      1492.4762      1809.9299    \n300 374.30667327966455105 -958.2183837890625 -949.36430670920719876 -645.28430971218278955 1809.9298793830914747\n       300   374.30667     -958.21838     -949.36431     -645.28431      1809.9299    \n310 361.44552299349192026 -958.01593017578125 -949.46607854553292327 3105.0892987513620938 1809.9298793830914747\n       310   361.44552     -958.01593     -949.46608      3105.0893      1809.9299    \n320 349.80745753863863001 -957.9735107421875 -949.69895297110224419 -379.13226111580485167 1809.9298793830914747\n       320   349.80746     -957.97351     -949.69895     -379.13226      1809.9299    \n330 355.28235181499576356 -957.98529052734375 -949.58122628633054774 1854.6336502830301924 1809.9298793830914747\n       330   355.28235     -957.98529     -949.58123      1854.6337      1809.9299    \n340 381.020044753571824 -958.40716552734375 -949.39428628674988886 -839.95248540467298426 1809.9298793830914747\n       340   381.02004     -958.40717     -949.39429     -839.95249      1809.9299    \n350 373.81607171690615132 -957.98480224609375 -949.14233015317097397 2729.9399222625347647 1809.9298793830914747\n       350   373.81607     -957.9848      -949.14233      2729.9399      1809.9299    \n360 386.35484846762648203 -958.3848876953125 -949.2458157719212295 911.84361643808006193 1809.9298793830914747\n       360   386.35485     -958.38489     -949.24582      911.84362      1809.9299    \n370 366.83628494289740729 -958.5029296875 -949.82556170441466747 -2075.2851000857053805 1809.9298793830914747\n       370   366.83628     -958.50293     -949.82556     -2075.2851      1809.9299    \n380 380.42193095523185775 -958.48736572265625 -949.4886346286252774 4381.8674187077322131 1809.9298793830914747\n       380   380.42193     -958.48737     -949.48863      4381.8674      1809.9299    \n390 347.34769606009774634 -957.6953125 -949.47893941885956792 -2456.6105419831615109 1809.9298793830914747\n       390   347.3477      -957.69531     -949.47894     -2456.6105      1809.9299    \n400 352.97610167536896597 -957.91729736328125 -949.5677865618922624 7865.9368940733102136 1809.9298793830914747\n       400   352.9761      -957.9173      -949.56779      7865.9369      1809.9299    \n410 353.10666018450081083 -957.73779296875 -949.38519385719769161 -4989.7809190577308982 1809.9298793830914747\n       410   353.10666     -957.73779     -949.38519     -4989.7809      1809.9299    \n420 369.12890951348498447 -958.27557373046875 -949.54397461523365109 8734.8565660249405482 1809.9298793830914747\n       420   369.12891     -958.27557     -949.54397      8734.8566      1809.9299    \n430 341.24601204841138724 -957.774658203125 -949.70261805648192421 -5312.7471148321346845 1809.9298793830914747\n       430   341.24601     -957.77466     -949.70262     -5312.7471      1809.9299    \n440 338.93406866984810222 -957.77581787109375 -949.75846583540180745 10912.954742425434233 1809.9298793830914747\n       440   338.93407     -957.77582     -949.75847      10912.955      1809.9299    \n450 347.03217177807630378 -957.72894287109375 -949.52003339269685966 -5333.438674577346319 1809.9298793830914747\n       450   347.03217     -957.72894     -949.52003     -5333.4387      1809.9299    \n460 356.21562833728677333 -957.97454833984375 -949.54840780990741678 8940.4830165785897407 1809.9298793830914747\n       460   356.21563     -957.97455     -949.54841      8940.483       1809.9299    \n470 370.31347369663683367 -958.25762939453125 -949.49800987962828458 -3376.2427915034259058 1809.9298793830914747\n       470   370.31347     -958.25763     -949.49801     -3376.2428      1809.9299    \n480 366.28611203962304899 -958.01123046875 -949.34687660921781571 6831.6791024523818123 1809.9298793830914747\n       480   366.28611     -958.01123     -949.34688      6831.6791      1809.9299    \n490 366.20898906280382334 -957.9986572265625 -949.336127680701793 -1089.3675463962440517 1809.9298793830914747\n       490   366.20899     -957.99866     -949.33613     -1089.3675      1809.9299    \n500 365.27188681451849561 -958.096923828125 -949.45656106723049561 4678.6586299143518772 1809.9298793830914747\n       500   365.27189     -958.09692     -949.45656      4678.6586      1809.9299    \nLoop time of 97.3972 on 1 procs for 500 steps with 184 atoms\n\nPerformance: 0.222 ns/day, 108.219 hours/ns, 5.134 timesteps/s, 944.586 atom-step/s\n88.4% CPU use with 1 MPI tasks x 1 OpenMP threads\n\nMPI task timing breakdown:\nSection |  min time  |  avg time  |  max time  |%varavg| %total\n---------------------------------------------------------------\nPair    | 96.421     | 96.421     | 96.421     |   0.0 | 99.00\nNeigh   | 0.93273    | 0.93273    | 0.93273    |   0.0 |  0.96\nComm    | 0.0245     | 0.0245     | 0.0245     |   0.0 |  0.03\nOutput  | 0.0062822  | 0.0062822  | 0.0062822  |   0.0 |  0.01\nModify  | 0.0094216  | 0.0094216  | 0.0094216  |   0.0 |  0.01\nOther   |            | 0.003157   |            |       |  0.00\n\nNlocal:            184 ave         184 max         184 min\nHistogram: 1 0 0 0 0 0 0 0 0 0\nNghost:           9765 ave        9765 max        9765 min\nHistogram: 1 0 0 0 0 0 0 0 0 0\nNeighs:              0 ave           0 max           0 min\nHistogram: 1 0 0 0 0 0 0 0 0 0\nFullNghs:       383610 ave      383610 max      383610 min\nHistogram: 1 0 0 0 0 0 0 0 0 0\n\nTotal # of neighbors = 383610\nAve neighs/atom = 2084.837\nNeighbor list builds = 7\nDangerous builds = 0\nTotal wall time: 0:01:38\n")

Does that hold up quantitatively? The standard structural probe of solvation is the ion-oxygen radial distribution function g(r): the density of water oxygens at a distance r from each ion, normalized to the bulk density. A tall first peak followed by a deep minimum is the fingerprint of a well-defined hydration shell, and that first minimum sets the shell radius.

nacl_traj = ase.io.read("nacl_traj.lammpstrj", ":", format="lammps-dump-text")
g_na = []
r_na = []
g_cl = []
r_cl = []
for frame in nacl_traj:
    g_na_, r_na_ = get_rdf(frame, 6.0, 100, elements=["Na", "O"])
    g_cl_, r_cl_ = get_rdf(frame, 6.0, 100, elements=["Cl", "O"])
    g_na.append(g_na_)
    r_na.append(r_na_)
    g_cl.append(g_cl_)
    r_cl.append(r_cl_)
g_na = np.array(g_na).mean(axis=0)
r_na = np.array(r_na).mean(axis=0)
g_cl = np.array(g_cl).mean(axis=0)
r_cl = np.array(r_cl).mean(axis=0)

fig, ax = plt.subplots(figsize=(7, 4), dpi=200)
ax.plot(r_na, g_na, color="tab:orange", label="Na⁺-O")
ax.plot(r_cl, g_cl, color="tab:green", label="Cl⁻-O")
ax.axvline(3.1, color="tab:orange", ls="--", lw=0.8)
ax.axvline(3.8, color="tab:green", ls="--", lw=0.8)
ax.set(xlabel="r (Å)", ylabel="g(r)", title="Ion-oxygen radial distribution")
ax.legend()
plt.show()
Ion-oxygen radial distribution

If sampled for longer, g(r) of both ions would show a structured first peak and a clear first minimum (dashed lines, near 3.1 Å for Na⁺ and 3.8 Å for Cl⁻). Counting the water oxygens inside those radii every frame gives a coordination number, which we attach to the trajectory and show on the map beside the structure below. It fluctuates around 5-6 for Na⁺ and about 7 for Cl⁻. The default chemiscope visualization shows the Na⁺ coordination as the y-axis, but you can switch to the Cl⁻ one with the dropdown menu.

def first_shell_count(
    traj: list[ase.Atoms], ion: str, cutoff: float, other: str = "O"
) -> np.ndarray:
    """
    Mean number of other atoms within cutoff of each ion.

    :param traj: trajectory to analyze
    :param ion: element symbol of the ion (e.g. "Na" or "Cl")
    :param cutoff: shell radius in Å
    :param other: element symbol of the other species (default: "O")
    :return: array of shape (n_frames,) with the average count per ion at each frame
    """
    sym = np.array(traj[0].get_chemical_symbols())
    i_ion = np.where(sym == ion)[0]
    i_other = np.where(sym == other)[0]
    counts = []
    for frame in traj:
        d = frame.get_all_distances(mic=True)[i_ion, :][:, i_other]
        counts.append((d < cutoff).sum(axis=1).mean())
    return np.array(counts)


n_na = first_shell_count(nacl_traj, "Na", 3.1)
n_cl = first_shell_count(nacl_traj, "Cl", 3.8)
time_ps = np.arange(len(nacl_traj)) * 0.0005 * 10  # 0.5 fs step, dumped every 10

for frame in nacl_traj:
    frame.wrap()
chemiscope.show(
    structures=nacl_traj,
    properties={
        "time [ps]": {"target": "structure", "values": time_ps},
        "Na+ first-shell waters": {"target": "structure", "values": n_na},
        "Cl- first-shell waters": {"target": "structure", "values": n_cl},
    },
    mode="default",
    settings=chemiscope.quick_settings(
        trajectory=True,
        x="time [ps]",
        y="Na+ first-shell waters",
        structure_settings={"playbackDelay": 20, "unitCell": True},
        map_settings={"markerOutline": False},
    ),
)

Loading icon


An organic mixture: ethanol-water

Ethanol (C₂H₅OH) adds a third element, carbon. For LAMMPS this is simply a third atom type, and the pair_coeff line grows by one entry to map C (Z=6). The model handles the new C-H, C-C, C-O and carbon-water interactions with no extra input. This kind of mixed organic/aqueous environment is common in chemistry, but can be tedious to parameterize with traditional force fields.

# Ethanol-water mixture NVT at 400 K with PET-MAD-xs
# Atom types: 1=H, 2=O, 3=C

units metal
atom_style atomic

variable seed       index 34567
variable t_target   equal 400.0
variable tdamp      equal 100*dt
variable nsteps     equal 500         # 500 * 0.5 fs = 0.25 ps
variable dump_every equal 10

read_data data/ethanol_water.data

pair_style metatomic pet-mad-xs-v1.5.0.pt device cpu
pair_coeff * * 1 8 6

timestep 0.0005

neighbor 2.0 bin
neigh_modify one 50000 page 500000

thermo_style custom step temp pe etotal press vol
thermo 10

velocity all create ${t_target} ${seed} mom yes rot yes dist gaussian
reset_timestep 0

fix nve_int   all nve
fix thermostat all temp/csvr ${t_target} ${t_target} ${tdamp} ${seed}

print "step temp pe etotal press vol" file ethanol_thermo.out
fix thermofile all print ${dump_every} "$(step) $(temp) $(pe) $(etotal) $(press) $(vol)" append ethanol_thermo.out

dump traj all custom ${dump_every} ethanol_traj.lammpstrj id type element xu yu zu
dump_modify traj element H O C sort id

run ${nsteps}
run_command("lmp -in in_ethanol_nvt.lmp", print_output=True)
LAMMPS (4 Jul 2026)
OMP_NUM_THREADS environment is not set. Defaulting to 1 thread.
  using 1 OpenMP thread(s) per MPI task
Reading data file ...
  orthogonal box = (0.56573683 0.56573683 0.56573683) to (13.499283 13.499283 13.499283)
  1 by 1 by 1 MPI processor grid
  reading atoms ...
  192 atoms
  reading velocities ...
  192 velocities
  read_data CPU = 0.001 seconds

This is the PET-MAD-XS v1.5.0 model
===================================

A universal interatomic potential for advanced materials modeling based on a
Point-Edge Transformer (PET) architecture, and trained on the MAD dataset.
Model size: xs. Model version: 1.5.0.

Model authors
-------------

- Arslan Mazitov ([email protected])
- Filippo Bigi
- Matthias Kellner
- Paolo Pegolo
- Davide Tisi
- Guillaume Fraux
- Sergey Pozdnyakov
- Philip Loche
- Michele Ceriotti ([email protected])

Model references
----------------

Please cite the following references when using this model:
- about this specific model:
  * https://doi.org/10.1038/s41467-025-65662-7
  * https://arxiv.org/abs/2601.16195
- about the architecture of this model:
  * LLPR (uncertainty method):
    https://iopscience.iop.org/article/10.1088/2632-2153/ad805f
  * LPR (if using per-atom uncertainty):
    https://pubs.acs.org/doi/10.1021/acs.jctc.3c00704
  * https://arxiv.org/abs/2305.19302v3

Found 'energy_uncertainty' output, we will check for atoms with high uncertainty on the energy predictions
[W1112 22:38:58.854822627 module.cpp:218] Warning: module does not have '_mts_buffer_names'; falling back to processing all attributes. This is deprecated and will be removed in a future version, update your version of metatensor-learn and use `register_buffer` explicitly to remove this warning. (function operator())
Running simulation on cpu device with float32 data
step temp pe etotal press vol

CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE

Your simulation uses code contributions which should be cited:
- LLPR (uncertainty method): https://iopscience.iop.org/article/10.1088/2632-2153/ad805f
- LPR (if using per-atom uncertainty): https://pubs.acs.org/doi/10.1021/acs.jctc.3c00704
- https://arxiv.org/abs/2305.19302v3
- https://doi.org/10.1038/s41467-025-65662-7
- https://arxiv.org/abs/2601.16195
The log file lists these citations in BibTeX format.

CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE

Neighbor list info ...
  update: every = 1 steps, delay = 0 steps, check = yes
  max neighbors/atom: 50000, page size: 500000
  master list distance cutoff = 17
  ghost atom cutoff = 17
  binsize = 8.5, bins = 2 2 2
  1 neighbor lists, perpetual/occasional/extra = 1 0 0
  (1) pair metatomic, perpetual
      attributes: full, newton on, ghost
      pair build: full/bin/ghost
      stencil: full/ghost/bin/3d
      bin: standard
Setting up Verlet run ...
  Unit style    : metal
  Current step  : 0
  Time step     : 5e-04
0 400 -1028.9742431640625 -1019.0987680860624778 717.51682503471897689 2163.4799322060885061
Per MPI rank memory allocation (min/avg/max) = 48.77 | 48.77 | 48.77 Mbytes
   Step          Temp          PotEng         TotEng         Press          Volume
         0   400           -1028.9742     -1019.0988      717.51683      2163.4799
10 349.42218400918369525 -1027.592529296875 -1018.9657541221674819 -3486.295519217384026 2163.4799322060885061
        10   349.42218     -1027.5925     -1018.9658     -3486.2955      2163.4799
20 355.95343052041005194 -1027.8218994140625 -1019.0338763339801744 2142.6315074866952273 2163.4799322060885061
        20   355.95343     -1027.8219     -1019.0339      2142.6315      2163.4799
30 334.17441061579535244 -1027.2874755859375 -1019.0371479265834296 -2718.7649894840965317 2163.4799322060885061
        30   334.17441     -1027.2875     -1019.0371     -2718.765       2163.4799
40 362.92848731804122053 -1027.7923583984375 -1018.8321303194236407 -1187.041094676281773 2163.4799322060885061
        40   362.92849     -1027.7924     -1018.8321     -1187.0411      2163.4799
50 353.89805323155746919 -1027.4453125 -1018.7080339878975792 -4482.7427147296430121 2163.4799322060885061
        50   353.89805     -1027.4453     -1018.708      -4482.7427      2163.4799
60 374.43759758289479578 -1027.9898681640625 -1018.7454952560723314 -1737.8300076318919309 2163.4799322060885061
        60   374.4376      -1027.9899     -1018.7455     -1737.83        2163.4799
70 365.46118474268536147 -1027.596435546875 -1018.5736784921181197 -1459.8112919911534391 2163.4799322060885061
        70   365.46118     -1027.5964     -1018.5737     -1459.8113      2163.4799
80 358.77885252725923237 -1027.21728515625 -1018.3595061146340868 1656.1738239276116929 2163.4799322060885061
        80   358.77885     -1027.2173     -1018.3595      1656.1738      2163.4799
90 381.5412394442068944 -1027.7908935546875 -1018.3711410512862585 -1895.7055939821452739 2163.4799322060885061
        90   381.54124     -1027.7909     -1018.3711     -1895.7056      2163.4799
100 382.82974346116475317 -1027.853759765625 -1018.4021957889552823 -1163.6294116432820829 2163.4799322060885061
       100   382.82974     -1027.8538     -1018.4022     -1163.6294      2163.4799
110 377.19127754355292836 -1027.6220703125 -1018.3097126599491276 -3631.747488323052039 2163.4799322060885061
       110   377.19128     -1027.6221     -1018.3097     -3631.7475      2163.4799
120 363.76280905215696748 -1027.15673828125 -1018.1759118935053721 4850.1819746739256516 2163.4799322060885061
       120   363.76281     -1027.1567     -1018.1759      4850.182       2163.4799
130 349.80128802047227055 -1026.5670166015625 -1017.9308818463163107 -2141.191830946088885 2163.4799322060885061
       130   349.80129     -1026.567      -1017.9309     -2141.1918      2163.4799
140 356.03468912810456004 -1026.57373046875 -1017.7837012202797951 7723.7641925793359405 2163.4799322060885061
       140   356.03469     -1026.5737     -1017.7837      7723.7642      2163.4799
150 368.82244122990658752 -1026.542236328125 -1017.4364942616923599 -4841.5642811041252571 2163.4799322060885061
       150   368.82244     -1026.5422     -1017.4365     -4841.5643      2163.4799
160 381.17826948844231083 -1026.6846923828125 -1017.2739011312918365 5882.3535690258449904 2163.4799322060885061
       160   381.17827     -1026.6847     -1017.2739      5882.3536      2163.4799
170 373.09475217817521298 -1026.7027587890625 -1017.4915389718920551 -4756.6325068653186463 2163.4799322060885061
       170   373.09475     -1026.7028     -1017.4915     -4756.6325      2163.4799
180 390.22774885981755233 -1026.848388671875 -1017.2141776503520987 6978.2788193237747691 2163.4799322060885061
       180   390.22775     -1026.8484     -1017.2142      6978.2788      2163.4799
190 394.16298286034293596 -1027.242919921875 -1017.5115531371063753 -1389.0215714746984759 2163.4799322060885061
       190   394.16298     -1027.2429     -1017.5116     -1389.0216      2163.4799
200 400.3763384996685204 -1027.137939453125 -1017.2531730714390505 3610.2662469872020665 2163.4799322060885061
       200   400.37634     -1027.1379     -1017.2532      3610.2662      2163.4799
210 405.17908337292556098 -1026.8817138671875 -1016.8783740172469834 -815.07385519534466312 2163.4799322060885061
       210   405.17908     -1026.8817     -1016.8784     -815.07386      2163.4799
220 420.06102594271851558 -1027.5062255859375 -1017.1354701035963899 -2095.6330720881628622 2163.4799322060885061
       220   420.06103     -1027.5062     -1017.1355     -2095.6331      2163.4799
230 392.82501159946372127 -1027.119384765625 -1017.4210507354611082 904.63580205286200453 2163.4799322060885061
       230   392.82501     -1027.1194     -1017.4211      904.6358       2163.4799
240 381.13616863211842656 -1027.0189208984375 -1017.6091690618102348 -1332.7090621924232892 2163.4799322060885061
       240   381.13617     -1027.0189     -1017.6092     -1332.7091      2163.4799
250 392.56812876433696147 -1027.026611328125 -1017.3346193980517 5603.8152747003068725 2163.4799322060885061
       250   392.56813     -1027.0266     -1017.3346      5603.8153      2163.4799
260 394.15127369798324253 -1027.01123046875 -1017.2801527678340108 -1792.4369270820300244 2163.4799322060885061
       260   394.15127     -1027.0112     -1017.2802     -1792.4369      2163.4799
270 380.18425905731237435 -1026.7059326171875 -1017.319682178766584 2910.4201382769119846 2163.4799322060885061
       270   380.18426     -1026.7059     -1017.3197      2910.4201      2163.4799
280 374.36736908290595238 -1026.6458740234375 -1017.4032349649507978 -3824.572998811407615 2163.4799322060885061
       280   374.36737     -1026.6459     -1017.4032     -3824.573       2163.4799
290 391.94811032393681671 -1027.187255859375 -1017.5105713709418751 -2012.1581118069761942 2163.4799322060885061
       290   391.94811     -1027.1873     -1017.5106     -2012.1581      2163.4799
300 376.63468544542109839 -1026.712646484375 -1017.4140303603084021 -2754.1609311017150503 2163.4799322060885061
       300   376.63469     -1026.7126     -1017.414      -2754.1609      2163.4799
310 360.6546755000569533 -1026.343994140625 -1017.4399034914624735 794.33858852195555755 2163.4799322060885061
       310   360.65468     -1026.344      -1017.4399      794.33859      2163.4799
320 385.50406291861162345 -1026.5064697265625 -1016.988880312011247 3231.3733342119239751 2163.4799322060885061
       320   385.50406     -1026.5065     -1016.9889      3231.3733      2163.4799
330 377.58400538937860347 -1026.158935546875 -1016.8368819591894407 1455.0140582805966005 2163.4799322060885061
       330   377.58401     -1026.1589     -1016.8369      1455.0141      2163.4799
340 396.18316493284191893 -1026.6485595703125 -1016.8673171412689271 1650.3635382130985363 2163.4799322060885061
       340   396.18316     -1026.6486     -1016.8673      1650.3635      2163.4799
350 387.84398511650863384 -1026.211181640625 -1016.6358226176993185 -5903.019574067890062 2163.4799322060885061
       350   387.84399     -1026.2112     -1016.6358     -5903.0196      2163.4799
360 410.46447057194217223 -1026.40625 -1016.2724208761558202 1430.7218597770468023 2163.4799322060885061
       360   410.46447     -1026.4062     -1016.2724      1430.7219      2163.4799
370 385.92954467507394156 -1025.6885986328125 -1016.1605046320560177 -2691.767405219664397 2163.4799322060885061
       370   385.92954     -1025.6886     -1016.1605     -2691.7674      2163.4799
380 416.70756587828037709 -1026.1011962890625 -1015.8132333349500414 4342.3765654897742934 2163.4799322060885061
       380   416.70757     -1026.1012     -1015.8132      4342.3766      2163.4799
390 409.72420781272143131 -1025.88134765625 -1015.765794648480437 -3450.7249787115588333 2163.4799322060885061
       390   409.72421     -1025.8813     -1015.7658     -3450.725       2163.4799
400 394.80920947988295211 -1025.70263671875 -1015.95531544679136 2652.5861336972902791 2163.4799322060885061
       400   394.80921     -1025.7026     -1015.9553      2652.5861      2163.4799
410 422.82324586378160802 -1026.1741943359375 -1015.7352432686203656 -225.36224076115135517 2163.4799322060885061
       410   422.82325     -1026.1742     -1015.7352     -225.36224      2163.4799
420 413.89894493054578106 -1026.1680908203125 -1015.9494690316322476 2078.2117382508563423 2163.4799322060885061
       420   413.89894     -1026.1681     -1015.9495      2078.2117      2163.4799
430 395.27518527021993577 -1025.7569580078125 -1015.9981324050927469 1347.8967052914140368 2163.4799322060885061
       430   395.27519     -1025.757      -1015.9981      1347.8967      2163.4799
440 380.74592536404071552 -1025.70556640625 -1016.3054491637934689 -2874.8196658917681816 2163.4799322060885061
       440   380.74593     -1025.7056     -1016.3054     -2874.8197      2163.4799
450 400.66887351650512983 -1026.021240234375 -1016.1292515470184981 581.92806061408475671 2163.4799322060885061
       450   400.66887     -1026.0212     -1016.1293      581.92806      2163.4799
460 398.14875522088902926 -1025.8626708984375 -1016.0329006246359995 -1075.0429855684494669 2163.4799322060885061
       460   398.14876     -1025.8627     -1016.0329     -1075.043       2163.4799
470 380.37486801224810051 -1025.5836181640625 -1016.1926618406812395 3332.0170868604695897 2163.4799322060885061
       470   380.37487     -1025.5836     -1016.1927      3332.0171      2163.4799
480 422.64425955235878973 -1026.5401611328125 -1016.1056290026398301 650.47644334875144523 2163.4799322060885061
       480   422.64426     -1026.5402     -1016.1056      650.47644      2163.4799
490 411.69368051031727873 -1026.0535888671875 -1015.8894121630631844 -1347.8853738152106416 2163.4799322060885061
       490   411.69368     -1026.0536     -1015.8894     -1347.8854      2163.4799
500 409.15463300468798025 -1025.697998046875 -1015.5965070936599659 4266.4235048339542118 2163.4799322060885061
       500   409.15463     -1025.698      -1015.5965      4266.4235      2163.4799
Loop time of 94.1532 on 1 procs for 500 steps with 192 atoms

Performance: 0.229 ns/day, 104.615 hours/ns, 5.310 timesteps/s, 1.020 katom-step/s
88.7% CPU use with 1 MPI tasks x 1 OpenMP threads

MPI task timing breakdown:
Section |  min time  |  avg time  |  max time  |%varavg| %total
---------------------------------------------------------------
Pair    | 93.192     | 93.192     | 93.192     |   0.0 | 98.98
Neigh   | 0.91859    | 0.91859    | 0.91859    |   0.0 |  0.98
Comm    | 0.023645   | 0.023645   | 0.023645   |   0.0 |  0.03
Output  | 0.0064293  | 0.0064293  | 0.0064293  |   0.0 |  0.01
Modify  | 0.0095891  | 0.0095891  | 0.0095891  |   0.0 |  0.01
Other   |            | 0.003215   |            |       |  0.00

Nlocal:            192 ave         192 max         192 min
Histogram: 1 0 0 0 0 0 0 0 0 0
Nghost:           9037 ave        9037 max        9037 min
Histogram: 1 0 0 0 0 0 0 0 0 0
Neighs:              0 ave           0 max           0 min
Histogram: 1 0 0 0 0 0 0 0 0 0
FullNghs:       349944 ave      349944 max      349944 min
Histogram: 1 0 0 0 0 0 0 0 0 0

Total # of neighbors = 349944
Ave neighs/atom = 1822.625
Neighbor list builds = 8
Dangerous builds = 0
Total wall time: 0:01:35

CompletedProcess(args=['lmp', '-in', 'in_ethanol_nvt.lmp'], returncode=0, stdout="LAMMPS (4 Jul 2026)\nOMP_NUM_THREADS environment is not set. Defaulting to 1 thread.\n  using 1 OpenMP thread(s) per MPI task\nReading data file ...\n  orthogonal box = (0.56573683 0.56573683 0.56573683) to (13.499283 13.499283 13.499283)\n  1 by 1 by 1 MPI processor grid\n  reading atoms ...\n  192 atoms\n  reading velocities ...\n  192 velocities\n  read_data CPU = 0.001 seconds\n\nThis is the PET-MAD-XS v1.5.0 model\n===================================\n\nA universal interatomic potential for advanced materials modeling based on a\nPoint-Edge Transformer (PET) architecture, and trained on the MAD dataset.\nModel size: xs. Model version: 1.5.0.\n\nModel authors\n-------------\n\n- Arslan Mazitov ([email protected])\n- Filippo Bigi\n- Matthias Kellner\n- Paolo Pegolo\n- Davide Tisi\n- Guillaume Fraux\n- Sergey Pozdnyakov\n- Philip Loche\n- Michele Ceriotti ([email protected])\n\nModel references\n----------------\n\nPlease cite the following references when using this model:\n- about this specific model:\n  * https://doi.org/10.1038/s41467-025-65662-7\n  * https://arxiv.org/abs/2601.16195\n- about the architecture of this model:\n  * LLPR (uncertainty method):\n    https://iopscience.iop.org/article/10.1088/2632-2153/ad805f\n  * LPR (if using per-atom uncertainty):\n    https://pubs.acs.org/doi/10.1021/acs.jctc.3c00704\n  * https://arxiv.org/abs/2305.19302v3\n\nFound 'energy_uncertainty' output, we will check for atoms with high uncertainty on the energy predictions\n[W1112 22:38:58.854822627 module.cpp:218] Warning: module does not have '_mts_buffer_names'; falling back to processing all attributes. This is deprecated and will be removed in a future version, update your version of metatensor-learn and use `register_buffer` explicitly to remove this warning. (function operator())\nRunning simulation on cpu device with float32 data\nstep temp pe etotal press vol\n\nCITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE\n\nYour simulation uses code contributions which should be cited:\n- LLPR (uncertainty method): https://iopscience.iop.org/article/10.1088/2632-2153/ad805f\n- LPR (if using per-atom uncertainty): https://pubs.acs.org/doi/10.1021/acs.jctc.3c00704\n- https://arxiv.org/abs/2305.19302v3\n- https://doi.org/10.1038/s41467-025-65662-7\n- https://arxiv.org/abs/2601.16195\nThe log file lists these citations in BibTeX format.\n\nCITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE\n\nNeighbor list info ...\n  update: every = 1 steps, delay = 0 steps, check = yes\n  max neighbors/atom: 50000, page size: 500000\n  master list distance cutoff = 17\n  ghost atom cutoff = 17\n  binsize = 8.5, bins = 2 2 2\n  1 neighbor lists, perpetual/occasional/extra = 1 0 0\n  (1) pair metatomic, perpetual\n      attributes: full, newton on, ghost\n      pair build: full/bin/ghost\n      stencil: full/ghost/bin/3d\n      bin: standard\nSetting up Verlet run ...\n  Unit style    : metal\n  Current step  : 0\n  Time step     : 5e-04\n0 400 -1028.9742431640625 -1019.0987680860624778 717.51682503471897689 2163.4799322060885061\nPer MPI rank memory allocation (min/avg/max) = 48.77 | 48.77 | 48.77 Mbytes\n   Step          Temp          PotEng         TotEng         Press          Volume    \n         0   400           -1028.9742     -1019.0988      717.51683      2163.4799    \n10 349.42218400918369525 -1027.592529296875 -1018.9657541221674819 -3486.295519217384026 2163.4799322060885061\n        10   349.42218     -1027.5925     -1018.9658     -3486.2955      2163.4799    \n20 355.95343052041005194 -1027.8218994140625 -1019.0338763339801744 2142.6315074866952273 2163.4799322060885061\n        20   355.95343     -1027.8219     -1019.0339      2142.6315      2163.4799    \n30 334.17441061579535244 -1027.2874755859375 -1019.0371479265834296 -2718.7649894840965317 2163.4799322060885061\n        30   334.17441     -1027.2875     -1019.0371     -2718.765       2163.4799    \n40 362.92848731804122053 -1027.7923583984375 -1018.8321303194236407 -1187.041094676281773 2163.4799322060885061\n        40   362.92849     -1027.7924     -1018.8321     -1187.0411      2163.4799    \n50 353.89805323155746919 -1027.4453125 -1018.7080339878975792 -4482.7427147296430121 2163.4799322060885061\n        50   353.89805     -1027.4453     -1018.708      -4482.7427      2163.4799    \n60 374.43759758289479578 -1027.9898681640625 -1018.7454952560723314 -1737.8300076318919309 2163.4799322060885061\n        60   374.4376      -1027.9899     -1018.7455     -1737.83        2163.4799    \n70 365.46118474268536147 -1027.596435546875 -1018.5736784921181197 -1459.8112919911534391 2163.4799322060885061\n        70   365.46118     -1027.5964     -1018.5737     -1459.8113      2163.4799    \n80 358.77885252725923237 -1027.21728515625 -1018.3595061146340868 1656.1738239276116929 2163.4799322060885061\n        80   358.77885     -1027.2173     -1018.3595      1656.1738      2163.4799    \n90 381.5412394442068944 -1027.7908935546875 -1018.3711410512862585 -1895.7055939821452739 2163.4799322060885061\n        90   381.54124     -1027.7909     -1018.3711     -1895.7056      2163.4799    \n100 382.82974346116475317 -1027.853759765625 -1018.4021957889552823 -1163.6294116432820829 2163.4799322060885061\n       100   382.82974     -1027.8538     -1018.4022     -1163.6294      2163.4799    \n110 377.19127754355292836 -1027.6220703125 -1018.3097126599491276 -3631.747488323052039 2163.4799322060885061\n       110   377.19128     -1027.6221     -1018.3097     -3631.7475      2163.4799    \n120 363.76280905215696748 -1027.15673828125 -1018.1759118935053721 4850.1819746739256516 2163.4799322060885061\n       120   363.76281     -1027.1567     -1018.1759      4850.182       2163.4799    \n130 349.80128802047227055 -1026.5670166015625 -1017.9308818463163107 -2141.191830946088885 2163.4799322060885061\n       130   349.80129     -1026.567      -1017.9309     -2141.1918      2163.4799    \n140 356.03468912810456004 -1026.57373046875 -1017.7837012202797951 7723.7641925793359405 2163.4799322060885061\n       140   356.03469     -1026.5737     -1017.7837      7723.7642      2163.4799    \n150 368.82244122990658752 -1026.542236328125 -1017.4364942616923599 -4841.5642811041252571 2163.4799322060885061\n       150   368.82244     -1026.5422     -1017.4365     -4841.5643      2163.4799    \n160 381.17826948844231083 -1026.6846923828125 -1017.2739011312918365 5882.3535690258449904 2163.4799322060885061\n       160   381.17827     -1026.6847     -1017.2739      5882.3536      2163.4799    \n170 373.09475217817521298 -1026.7027587890625 -1017.4915389718920551 -4756.6325068653186463 2163.4799322060885061\n       170   373.09475     -1026.7028     -1017.4915     -4756.6325      2163.4799    \n180 390.22774885981755233 -1026.848388671875 -1017.2141776503520987 6978.2788193237747691 2163.4799322060885061\n       180   390.22775     -1026.8484     -1017.2142      6978.2788      2163.4799    \n190 394.16298286034293596 -1027.242919921875 -1017.5115531371063753 -1389.0215714746984759 2163.4799322060885061\n       190   394.16298     -1027.2429     -1017.5116     -1389.0216      2163.4799    \n200 400.3763384996685204 -1027.137939453125 -1017.2531730714390505 3610.2662469872020665 2163.4799322060885061\n       200   400.37634     -1027.1379     -1017.2532      3610.2662      2163.4799    \n210 405.17908337292556098 -1026.8817138671875 -1016.8783740172469834 -815.07385519534466312 2163.4799322060885061\n       210   405.17908     -1026.8817     -1016.8784     -815.07386      2163.4799    \n220 420.06102594271851558 -1027.5062255859375 -1017.1354701035963899 -2095.6330720881628622 2163.4799322060885061\n       220   420.06103     -1027.5062     -1017.1355     -2095.6331      2163.4799    \n230 392.82501159946372127 -1027.119384765625 -1017.4210507354611082 904.63580205286200453 2163.4799322060885061\n       230   392.82501     -1027.1194     -1017.4211      904.6358       2163.4799    \n240 381.13616863211842656 -1027.0189208984375 -1017.6091690618102348 -1332.7090621924232892 2163.4799322060885061\n       240   381.13617     -1027.0189     -1017.6092     -1332.7091      2163.4799    \n250 392.56812876433696147 -1027.026611328125 -1017.3346193980517 5603.8152747003068725 2163.4799322060885061\n       250   392.56813     -1027.0266     -1017.3346      5603.8153      2163.4799    \n260 394.15127369798324253 -1027.01123046875 -1017.2801527678340108 -1792.4369270820300244 2163.4799322060885061\n       260   394.15127     -1027.0112     -1017.2802     -1792.4369      2163.4799    \n270 380.18425905731237435 -1026.7059326171875 -1017.319682178766584 2910.4201382769119846 2163.4799322060885061\n       270   380.18426     -1026.7059     -1017.3197      2910.4201      2163.4799    \n280 374.36736908290595238 -1026.6458740234375 -1017.4032349649507978 -3824.572998811407615 2163.4799322060885061\n       280   374.36737     -1026.6459     -1017.4032     -3824.573       2163.4799    \n290 391.94811032393681671 -1027.187255859375 -1017.5105713709418751 -2012.1581118069761942 2163.4799322060885061\n       290   391.94811     -1027.1873     -1017.5106     -2012.1581      2163.4799    \n300 376.63468544542109839 -1026.712646484375 -1017.4140303603084021 -2754.1609311017150503 2163.4799322060885061\n       300   376.63469     -1026.7126     -1017.414      -2754.1609      2163.4799    \n310 360.6546755000569533 -1026.343994140625 -1017.4399034914624735 794.33858852195555755 2163.4799322060885061\n       310   360.65468     -1026.344      -1017.4399      794.33859      2163.4799    \n320 385.50406291861162345 -1026.5064697265625 -1016.988880312011247 3231.3733342119239751 2163.4799322060885061\n       320   385.50406     -1026.5065     -1016.9889      3231.3733      2163.4799    \n330 377.58400538937860347 -1026.158935546875 -1016.8368819591894407 1455.0140582805966005 2163.4799322060885061\n       330   377.58401     -1026.1589     -1016.8369      1455.0141      2163.4799    \n340 396.18316493284191893 -1026.6485595703125 -1016.8673171412689271 1650.3635382130985363 2163.4799322060885061\n       340   396.18316     -1026.6486     -1016.8673      1650.3635      2163.4799    \n350 387.84398511650863384 -1026.211181640625 -1016.6358226176993185 -5903.019574067890062 2163.4799322060885061\n       350   387.84399     -1026.2112     -1016.6358     -5903.0196      2163.4799    \n360 410.46447057194217223 -1026.40625 -1016.2724208761558202 1430.7218597770468023 2163.4799322060885061\n       360   410.46447     -1026.4062     -1016.2724      1430.7219      2163.4799    \n370 385.92954467507394156 -1025.6885986328125 -1016.1605046320560177 -2691.767405219664397 2163.4799322060885061\n       370   385.92954     -1025.6886     -1016.1605     -2691.7674      2163.4799    \n380 416.70756587828037709 -1026.1011962890625 -1015.8132333349500414 4342.3765654897742934 2163.4799322060885061\n       380   416.70757     -1026.1012     -1015.8132      4342.3766      2163.4799    \n390 409.72420781272143131 -1025.88134765625 -1015.765794648480437 -3450.7249787115588333 2163.4799322060885061\n       390   409.72421     -1025.8813     -1015.7658     -3450.725       2163.4799    \n400 394.80920947988295211 -1025.70263671875 -1015.95531544679136 2652.5861336972902791 2163.4799322060885061\n       400   394.80921     -1025.7026     -1015.9553      2652.5861      2163.4799    \n410 422.82324586378160802 -1026.1741943359375 -1015.7352432686203656 -225.36224076115135517 2163.4799322060885061\n       410   422.82325     -1026.1742     -1015.7352     -225.36224      2163.4799    \n420 413.89894493054578106 -1026.1680908203125 -1015.9494690316322476 2078.2117382508563423 2163.4799322060885061\n       420   413.89894     -1026.1681     -1015.9495      2078.2117      2163.4799    \n430 395.27518527021993577 -1025.7569580078125 -1015.9981324050927469 1347.8967052914140368 2163.4799322060885061\n       430   395.27519     -1025.757      -1015.9981      1347.8967      2163.4799    \n440 380.74592536404071552 -1025.70556640625 -1016.3054491637934689 -2874.8196658917681816 2163.4799322060885061\n       440   380.74593     -1025.7056     -1016.3054     -2874.8197      2163.4799    \n450 400.66887351650512983 -1026.021240234375 -1016.1292515470184981 581.92806061408475671 2163.4799322060885061\n       450   400.66887     -1026.0212     -1016.1293      581.92806      2163.4799    \n460 398.14875522088902926 -1025.8626708984375 -1016.0329006246359995 -1075.0429855684494669 2163.4799322060885061\n       460   398.14876     -1025.8627     -1016.0329     -1075.043       2163.4799    \n470 380.37486801224810051 -1025.5836181640625 -1016.1926618406812395 3332.0170868604695897 2163.4799322060885061\n       470   380.37487     -1025.5836     -1016.1927      3332.0171      2163.4799    \n480 422.64425955235878973 -1026.5401611328125 -1016.1056290026398301 650.47644334875144523 2163.4799322060885061\n       480   422.64426     -1026.5402     -1016.1056      650.47644      2163.4799    \n490 411.69368051031727873 -1026.0535888671875 -1015.8894121630631844 -1347.8853738152106416 2163.4799322060885061\n       490   411.69368     -1026.0536     -1015.8894     -1347.8854      2163.4799    \n500 409.15463300468798025 -1025.697998046875 -1015.5965070936599659 4266.4235048339542118 2163.4799322060885061\n       500   409.15463     -1025.698      -1015.5965      4266.4235      2163.4799    \nLoop time of 94.1532 on 1 procs for 500 steps with 192 atoms\n\nPerformance: 0.229 ns/day, 104.615 hours/ns, 5.310 timesteps/s, 1.020 katom-step/s\n88.7% CPU use with 1 MPI tasks x 1 OpenMP threads\n\nMPI task timing breakdown:\nSection |  min time  |  avg time  |  max time  |%varavg| %total\n---------------------------------------------------------------\nPair    | 93.192     | 93.192     | 93.192     |   0.0 | 98.98\nNeigh   | 0.91859    | 0.91859    | 0.91859    |   0.0 |  0.98\nComm    | 0.023645   | 0.023645   | 0.023645   |   0.0 |  0.03\nOutput  | 0.0064293  | 0.0064293  | 0.0064293  |   0.0 |  0.01\nModify  | 0.0095891  | 0.0095891  | 0.0095891  |   0.0 |  0.01\nOther   |            | 0.003215   |            |       |  0.00\n\nNlocal:            192 ave         192 max         192 min\nHistogram: 1 0 0 0 0 0 0 0 0 0\nNghost:           9037 ave        9037 max        9037 min\nHistogram: 1 0 0 0 0 0 0 0 0 0\nNeighs:              0 ave           0 max           0 min\nHistogram: 1 0 0 0 0 0 0 0 0 0\nFullNghs:       349944 ave      349944 max      349944 min\nHistogram: 1 0 0 0 0 0 0 0 0 0\n\nTotal # of neighbors = 349944\nAve neighs/atom = 1822.625\nNeighbor list builds = 8\nDangerous builds = 0\nTotal wall time: 0:01:35\n")

We claimed that the two species mix and hydrogen-bond to each other; we can count those bonds explicitly. Using the standard geometric definition (an O-H…O motif with the two oxygens within 3.5 Å and an O-H…O angle above 150°) we classify each hydrogen bond as water-water or water-ethanol. (A hydroxyl H is identified as the H whose nearest heavy neighbor is an oxygen; an ethanol O is one bonded to a carbon.)

def count_hbonds(
    traj: list[ase.Atoms], r_oo: float = 3.5, angle: float = 150.0
) -> tuple[np.ndarray, np.ndarray]:
    """
    Per-frame counts of (water-water, water-ethanol) hydrogen bonds.

    A hydrogen bond is counted with the usual geometric criterion: a covalent donor O-H
    pointing at an acceptor oxygen, with the two oxygens closer than ``r_oo`` and the
    O-H...O angle wider than ``angle``. Each bond is then labelled water-water or
    water-ethanol from the identity of its two oxygens.

    :param traj: trajectory to analyze
    :param r_oo: O-O distance cutoff in Å
    :param angle: O-H...O angle cutoff in degrees
    :return: tuple of two arrays of shape (n_frames,) with the counts of water-water and
        water-ethanol H-bonds at each frame
    """
    sym = np.array(traj[0].get_chemical_symbols())
    L = traj[0].get_cell()[0, 0]  # cubic box edge (minimum-image convention)
    iO = np.where(sym == "O")[0]
    iH = np.where(sym == "H")[0]
    iC = np.where(sym == "C")[0]
    heavy = np.concatenate([iO, iC])  # all heavy atoms, oxygens first then carbons

    def mic(a, b):
        # Minimum-image displacement vectors a[i] -> b[j] for a cubic box. We roll this
        # by hand because it is far cheaper than ASE's general-cell minimum image for
        # these small systems (we only need a few atom-pair blocks per frame).
        d = a[:, None, :] - b[None, :, :]
        return d - np.round(d / L) * L

    # An ethanol oxygen is the one with a carbon neighbour; the bonding topology never
    # changes, so we flag the ethanol oxygens once, from the first frame (one bool per
    # atom in ``iO``).
    p0 = traj[0].get_positions()
    eth_O = (np.linalg.norm(mic(p0[iO], p0[iC]), axis=-1) < 1.7).any(axis=1)
    cos_thr = np.cos(np.radians(angle))  # angle > thr  <=>  cos(angle) < cos(thr)

    ww, we = [], []
    for frame in traj:
        p = frame.get_positions()
        # Assign each H to its nearest heavy atom; keep it as a donor only if that
        # neighbour is an oxygen within a covalent O-H bond length (1.3 Å).
        dist_H = np.linalg.norm(mic(p[iH], p[heavy]), axis=-1)
        nn = np.argmin(dist_H, axis=1)
        is_oh = (nn < len(iO)) & (dist_H[np.arange(len(iH)), nn] < 1.3)
        Hd, Od = iH[is_oh], iO[nn[is_oh]]  # donor hydrogens and their donor oxygens

        # For every (donor H, candidate acceptor O) pair, build the two bond vectors
        # that meet at the hydrogen, plus the donor-acceptor oxygen distance.
        vHD = p[Od] - p[Hd]
        vHD -= np.round(vHD / L) * L  # H -> donor O
        vHA = -mic(p[Hd], p[iO])  # H -> every candidate acceptor O
        rDA = np.linalg.norm(mic(p[Od], p[iO]), axis=-1)  # donor O .. acceptor O
        nHD = np.linalg.norm(vHD, axis=-1)
        nHA = np.linalg.norm(vHA, axis=-1)
        # cos of the O-H...O angle at the hydrogen, for every donor/acceptor pair.
        cos = (vHD[:, None, :] * vHA).sum(-1) / (nHD[:, None] * nHA + 1e-9)
        # Keep pairs that are both close and near-linear. A donor's own oxygen pairs
        # with itself at cos = 1, so it never passes the angle test.
        hbond = (rDA < r_oo) & (cos < cos_thr)

        # Split the surviving bonds by whether their donor / acceptor oxygen is ethanol.
        donor_eth = eth_O[nn[is_oh]][:, None]
        accpt_eth = eth_O[None, :]
        ww.append(int((hbond & ~donor_eth & ~accpt_eth).sum()))  # water-water
        we.append(int((hbond & (donor_eth ^ accpt_eth)).sum()))  # water-ethanol
    return np.array(ww), np.array(we)


ethanol_traj = ase.io.read("ethanol_traj.lammpstrj", ":", format="lammps-dump-text")
hb_ww, hb_we = count_hbonds(ethanol_traj)
time_ps = np.arange(len(ethanol_traj)) * 0.0005 * 10

At every instant there are roughly a dozen water-ethanol hydrogen bonds and about forty water-water ones. That persistent water-ethanol count is the molecular signature of a miscible mixture: ethanol is not trapped in a pocket but stitched into the water hydrogen-bond network. Both counts are attached to the trajectory below: you can switch the map axis between the two curves.

for frame in ethanol_traj:
    frame.wrap()
chemiscope.show(
    structures=ethanol_traj,
    properties={
        "time [ps]": {"target": "structure", "values": time_ps},
        "water-ethanol H-bonds": {"target": "structure", "values": hb_we},
        "water-water H-bonds": {"target": "structure", "values": hb_ww},
    },
    mode="default",
    settings=chemiscope.quick_settings(
        trajectory=True,
        x="time [ps]",
        y="water-ethanol H-bonds",
        structure_settings={"playbackDelay": 20, "unitCell": True},
        map_settings={"markerOutline": False},
    ),
)

Loading icon


Extreme conditions: superionic water

The last system pushes far outside everyday chemistry. Deep inside the ice-giant planets (Uranus and Neptune) water is thought to exist in a superionic phase: the oxygen atoms stay locked on a crystalline lattice while the protons melt and diffuse through it like a liquid, turning the material into an ionic conductor. Reaching it requires roughly 3000 K and ~140 GPa. At these conditions common empirical water models are undefined, whereas an MLIP is reactive by construction.

We start from an ice-X-like configuration (a 4×4×4 supercell of a body-centered-cubic oxygen lattice, 128 water molecules) and hold it at 3000 K and fixed volume. Two settings change relative to the runs above: the temperature is much higher, and the timestep is shortened to 0.2 fs (timestep 0.0002) because atoms move much faster at 3000 K and the integration must stay stable.

# Superionic water NVT at 3000 K with PET-MAD-xs
# Pre-equilibrated at ~140 GPa; NVT keeps the volume fixed.
# Atom types: 1=H, 2=O

units metal
atom_style atomic

variable seed       index 45678
variable t_target   equal 3000.0
variable tdamp      equal 100*dt
variable nsteps     equal 50000        # 50000 * 0.2 fs = 10 ps
variable dump_every equal 25

read_data data/superionic_ice.data

pair_style metatomic pet-mad-xs-v1.5.1.pt device cpu
pair_coeff * * 1 8

timestep 0.0002                        # 0.2 fs (shorter for high-T/P stability)

neighbor 2.0 bin
neigh_modify one 50000 page 500000

thermo_style custom step temp pe etotal press vol
thermo 10

velocity all create ${t_target} ${seed} mom yes rot yes dist gaussian
reset_timestep 0

fix nve_int   all nve
fix thermostat all temp/csvr ${t_target} ${t_target} ${tdamp} ${seed}

print "step temp pe etotal press vol" file superionic_thermo.out
fix thermofile all print ${dump_every} "$(step) $(temp) $(pe) $(etotal) $(press) $(vol)" append superionic_thermo.out

dump traj all custom ${dump_every} superionic_traj.lammpstrj id type element xu yu zu
dump_modify traj element H O sort id

run ${nsteps}
lmp -in in_superionic_nvt.lmp

The clearest signature of the superionic phase is the mean-squared displacement (MSD) of each species. If the phase is truly superionic, the hydrogen MSD should grow linearly in time (Fickian diffusion, exactly as in a liquid) while the oxygen MSD stays small and flat, meaning that atoms can only rattle around fixed lattice sites.

Because the trajectory was dumped with unwrapped coordinates, the MSD is a plain average of squared displacements, with no periodic-boundary correction needed:

def compute_msd(traj: list, species: str) -> np.ndarray:
    symbols = np.array(traj[0].get_chemical_symbols())
    mask = symbols == species
    pos = np.array([f.get_positions()[mask] for f in traj])
    return np.mean(np.sum((pos - pos[0][np.newaxis]) ** 2, axis=-1), axis=-1)


sup_traj = ase.io.read("superionic_traj.lammpstrj", ":", format="lammps-dump-text")

dt_ps = 0.0002  # timestep in ps (0.2 fs)
dump_every = 25
time_ps = np.arange(len(sup_traj)) * dt_ps * dump_every

msd_H = compute_msd(sup_traj, "H")
msd_O = compute_msd(sup_traj, "O")

fig, ax = plt.subplots(figsize=(7, 4), dpi=200)
ax.plot(time_ps, msd_H, label="H")
ax.plot(time_ps, msd_O, label="O")
ax.set(
    xlabel="Time (ps)",
    ylabel="MSD (Ų)",
    title="Superionic water (3000 K, ~140 GPa)",
)
ax.legend()
plt.show()
Superionic water (3000 K, ~140 GPa)

The two curves behave just as expected: hydrogen diffuses freely while oxygen oscillated around lattice sites. To watch the transition itself, we ramp the temperature from 300 K to 3000 K over a single trajectory. The input is the one above with a single change: the thermostat target sweeps from 300 K to 3000 K instead of being held fixed (fix temp/csvr 300 3000 ...). Run it with:

lmp -in in_superionic_ramp.lmp

While visualizing the trajectory, notice how the oxygen lattice stays ordered while the hydrogen atoms progressively diffuse and begin to flow between sites.

sup_ramp_traj = ase.io.read(
    "superionic_ramp_traj.lammpstrj", ":", format="lammps-dump-text"
)
sup_ramp_thermo = np.loadtxt("superionic_ramp_thermo.out", skiprows=1)
ramp_time_ps = sup_ramp_thermo[:, 0] * 0.0002
ramp_temp_K = sup_ramp_thermo[:, 1]

chemiscope.show(
    structures=sup_ramp_traj,
    properties={
        "time [ps]": {"target": "structure", "values": ramp_time_ps},
        "temperature [K]": {"target": "structure", "values": ramp_temp_K},
    },
    mode="default",
    settings=chemiscope.quick_settings(
        trajectory=True,
        x="time [ps]",
        y="temperature [K]",
        structure_settings={"playbackDelay": 5, "unitCell": True},
        map_settings={"markerOutline": False},
    ),
)

Loading icon


Where to go next

Throughout this recipe we used a foundational model out of the box, changing only the system and never the potential. That is often enough for a qualitative picture, a starting structure, or a screening study. For quantitative accuracy at a specific thermodynamic state, though, one often needs fine-tuning: a small, targeted set of DFT calculations specializes the universal model to the system or conditions of interest, at a fraction of the cost of training from scratch.

To go further:

  • PET-MAD tutorial—how to set up and run PET-MAD yourself with ASE, i-PI and LAMMPS, for a diverse array of applications.

  • Fine-tuning PET-MAD—how to specialize a foundational model to a target system for production-quality accuracy.

  • Mendeleev’s nano-soup—the same model pushed to the limit: sampling a 102-element nanoparticle with replica-exchange MD and Monte Carlo atom swaps.

Total running time of the script: (5 minutes 8.736 seconds)

Gallery generated by Sphinx-Gallery