Skip to content

GPUMD

MDAPY writes the model.xyz that GPUMD starts from, reads the extended XYZ files GPUMD writes, computes with the NEP potentials GPUMD trains, and builds their training sets.

import numpy as np
from mdapy.build import build_crystal
from mdapy.io import write

crystal = build_crystal("fcc", 3.615, elements="Cu", repeat=(10, 10, 10))
rng = np.random.default_rng(0)
upper = crystal["positions"][:, 2] > crystal.box.matrix[2, 2] / 2
crystal = crystal.with_columns(
    velocities=rng.normal(0.0, 2.0, (len(crystal), 3)),  # Å/ps
    group=upper.astype(np.int64),  # one grouping method: lower 0, upper 1
)
write("model.xyz", crystal)
# Properties=species:S:1:pos:R:3:vel:R:3:group:I:1, velocities in Å/fs

Then, after the run:

from mdapy.calculators import NEP
from mdapy.io import read_trajectory

with read_trajectory("dump.xyz") as frames:  # from dump_exyz
    last = frames[-1]
potential = NEP("nep.txt")
potential.compute(last, ("energy", "forces", "virial"))

What goes between them

GPUMD MDAPY Page
model.xyz: species, pos, mass, charge, vel (Å/fs), group mdapy.io.write of extended XYZ: element, positions, mass, charge, velocities (Å/ps), group Extended XYZ
dump_exyz, train.xyz, test.xyz mdapy.io.read_trajectory Extended XYZ
NEP potentials, nep.txt the calculator NEP NEP
training sets OUTCARs to extended XYZ, choosing frames, perturbed structures Training sets from VASP

GPUMD needs at least two atoms and a Lattice, which MDAPY always writes. A group column of integers, or of k integers per atom for k grouping methods, is written as group:I:k. GPUMD has no origin of the box and ignores the Origin that MDAPY writes for a box with one.

See also