Engine¶
MD engine abstractions for LAMMPS and CP2K.
Quick reference¶
| Symbol | Summary | Preferred for |
|---|---|---|
LAMMPSEngine |
LAMMPS simulation management | Running LAMMPS simulations |
CP2KEngine |
CP2K simulation management | Running CP2K simulations |
Related¶
- Guide: Crosslinked Networks (LAMMPS script generation)
Full API¶
Base¶
base ¶
Engine base classes for molecular simulation engines.
Provides :class:Engine, an abstract base for running external computational
chemistry programs (LAMMPS, CP2K, OpenMM, …). Each concrete engine handles
command construction, file management, and subprocess execution for its
specific program.
The two supported usage modes are:
-
Generate-only — write input files to disk without executing anything::
paths = engine.generate_inputs(frame, ff, config, "./output")
-
Execute — write files and run the engine subprocess::
result = engine.run(script, workdir="./calc")
MPI and job-scheduler launchers are supported via the launcher parameter::
engine = LAMMPSEngine("lmp", launcher=["mpirun", "-np", "16"])
engine = LAMMPSEngine("lmp", launcher=["srun", "--ntasks", "16"])
Engine ¶
Engine(
executable,
*,
workdir=None,
launcher=None,
env_vars=None,
env=None,
env_manager=None,
check_executable=True,
)
Bases: ABC
Abstract base class for computational chemistry engines.
Concrete subclasses implement :meth:_execute and
:meth:_get_default_extension. The base class handles script
normalization, working-directory management, and command prefixing
(launcher + environment wrapper).
Attributes:
| Name | Type | Description |
|---|---|---|
executable |
Path or command to the engine binary. |
|
work_dir |
Default working directory; |
|
launcher |
Optional MPI / scheduler prefix inserted before the
executable, e.g. |
|
env_vars |
dict[str, str]
|
Extra environment variables forwarded to the subprocess. |
env |
Conda / virtual-environment name to activate before execution. |
|
env_manager |
Environment manager; currently |
|
scripts |
list[Script]
|
Scripts registered by the last :meth: |
input_script |
Script | None
|
Primary input script resolved by the last :meth: |
Example
from molpy.core.script import Script from molpy.engine import LAMMPSEngine
script = Script.from_text( ... name="input", ... text="units real\natom_style full\n", ... language="other", ... ) engine = LAMMPSEngine(executable="lmp", check_executable=False) result = engine.run(script, workdir="./calc", check=False) print(result.returncode) 0
Initialise the engine.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
executable
|
str
|
Path or command to the engine binary (e.g. |
required |
workdir
|
str | Path | None
|
Default working directory. |
None
|
launcher
|
list[str] | None
|
MPI or scheduler prefix prepended before the executable,
e.g. |
None
|
env_vars
|
dict[str, str] | None
|
Extra environment variables set for the subprocess. |
None
|
env
|
str | None
|
Conda / virtual-environment name to activate. Must be provided together with env_manager. |
None
|
env_manager
|
str | None
|
Environment manager type. |
None
|
check_executable
|
bool
|
Verify the executable is on PATH at construction
time. Set to |
True
|
Raises:
| Type | Description |
|---|---|
FileNotFoundError
|
If check_executable is |
ValueError
|
If exactly one of env / env_manager is provided. |
name
abstractmethod
property
¶
Human-readable engine name (e.g. "LAMMPS").
Returns:
| Type | Description |
|---|---|
str
|
A short, stable identifier used for logging and |
check_executable ¶
Verify the executable is available on PATH.
Raises:
| Type | Description |
|---|---|
FileNotFoundError
|
If the executable cannot be found. |
run ¶
Write scripts to disk and execute the engine.
Accepts scripts as :class:~molpy.core.script.Script objects, raw
strings, :class:~pathlib.Path objects, or a list thereof. If
workdir is given it is used for this call only — self.work_dir
is not modified.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
scripts
|
Script | str | Path | Sequence[Script] | None
|
Input script(s) to run. If |
None
|
workdir
|
str | Path | None
|
Working directory for this run. Overrides
|
None
|
capture_output
|
bool
|
Capture stdout/stderr. |
False
|
check
|
bool
|
Raise on non-zero exit code. |
True
|
timeout
|
float | None
|
Timeout in seconds. |
None
|
**kwargs
|
Any
|
Forwarded to :meth: |
{}
|
Returns:
| Type | Description |
|---|---|
CompletedProcess
|
class: |
Raises:
| Type | Description |
|---|---|
ValueError
|
If no scripts are provided and none were registered previously. |
CP2K¶
cp2k ¶
CP2K quantum chemistry / molecular dynamics engine.
Wraps the CP2K <https://www.cp2k.org>_ program. The engine writes an
input script to the working directory and runs::
[launcher...] cp2k.psmp -i <input> -o cp2k.out
Standard CP2K output (log) is redirected to cp2k.out via the -o flag;
stdout is therefore empty, which avoids pipe-buffer deadlocks when the caller
captures output.
MPI and scheduler launchers are configured on the :class:~molpy.engine.base.Engine
base class::
engine = CP2KEngine("cp2k.psmp", launcher=["mpirun", "-np", "32"])
engine = CP2KEngine("cp2k.psmp", launcher=["srun", "--ntasks=32"])
Reference
Kühne, T. D. et al. (2020). CP2K: An electronic structure and molecular dynamics software package. J. Chem. Phys. 152, 194103. https://doi.org/10.1063/5.0007045
CP2KEngine ¶
CP2KEngine(
executable,
*,
workdir=None,
launcher=None,
env_vars=None,
env=None,
env_manager=None,
check_executable=True,
)
Bases: Engine
CP2K quantum chemistry / molecular dynamics engine.
Runs CP2K input scripts. The typical executable name is cp2k.psmp
(MPI + OpenMP build) or cp2k.popt (MPI only).
A minimal CP2K input must contain at least &GLOBAL, &FORCE_EVAL,
and &MOTION (or &ENERGY) sections.
Example
from molpy.core.script import Script from molpy.engine import CP2KEngine
inp = ( ... "&GLOBAL\n" ... " PROJECT water\n" ... " RUN_TYPE ENERGY\n" ... "&END GLOBAL\n" ... "&FORCE_EVAL\n" ... " METHOD Quickstep\n" ... "&END FORCE_EVAL\n" ... ) script = Script.from_text(name="input", text=inp, language="other") engine = CP2KEngine(executable="cp2k.psmp", check_executable=False) result = engine.run(script, workdir="./calc", check=False) print(result.returncode) 0
MPI execution::
engine = CP2KEngine("cp2k.psmp", launcher=["mpirun", "-np", "32"])
result = engine.run(script, workdir="./calc")
LAMMPS¶
lammps ¶
LAMMPS molecular dynamics engine.
Wraps the LAMMPS <https://www.lammps.org>_ molecular dynamics code.
The engine writes an input script to the working directory and runs::
[launcher...] lmp -in <input> -log log.lammps -screen none
The -screen none flag suppresses duplicate stdout output; all
per-timestep data is written exclusively to log.lammps.
MPI and scheduler launchers are configured on the :class:~molpy.engine.base.Engine
base class::
engine = LAMMPSEngine("lmp", launcher=["mpirun", "-np", "16"])
engine = LAMMPSEngine("lmp", launcher=["srun", "--ntasks=16"])
Reference
Thompson, A. P. et al. (2022). LAMMPS — A flexible simulation tool for particle-based materials modeling. Comput. Phys. Commun. 271, 108171. https://doi.org/10.1016/j.cpc.2021.108171
LAMMPSEngine ¶
Bases: Engine
LAMMPS molecular dynamics engine.
Runs LAMMPS input scripts. The engine binary is typically named lmp,
lmp_serial, or lmp_mpi depending on the build.
Example
from molpy.core.script import Script from molpy.engine import LAMMPSEngine
script = Script.from_text( ... name="input", ... text="units real\natom_style full\nrun 0\n", ... language="other", ... ) engine = LAMMPSEngine(executable="lmp", check_executable=False) result = engine.run(script, workdir="./calc", check=False) print(result.returncode) 0
MPI execution::
engine = LAMMPSEngine("lmp", launcher=["mpirun", "-np", "16"])
result = engine.run(script, workdir="./calc")
Initialise the LAMMPS engine.
Differs from :class:~molpy.engine.base.Engine only in that
executable is optional: when omitted, the first binary found on
PATH among lmp, lmp_serial, lmp_mpi is used, so
LAMMPSEngine() works out of the box on a typical install.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
executable
|
str | None
|
Path or command to the LAMMPS binary. |
None
|
check_executable
|
bool
|
Verify the resolved executable is on |
True
|
**kwargs
|
Any
|
Forwarded to :class: |
{}
|
md ¶
md(
frame,
ff,
*,
ensemble="nve",
steps=1000,
temperature=300.0,
timestep=1.0,
seed=12345,
limit=0.1,
pair_style="lj/cut/coul/cut 10.0",
atom_style="full",
units="real",
workdir=None,
capture_output=False,
timeout=None,
)
Run short MD on frame under ff and return a new frame.
A thin sibling of :meth:minimize for settling a packed box. Note that
a freshly packed box carries residual clashes; run :meth:minimize
first, or use ensemble="nve/limit", to avoid a blow-up under plain
nve.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
frame
|
Frame
|
Input structure; must carry a periodic box ( |
required |
ff
|
ForceField
|
Typified force field. |
required |
ensemble
|
str
|
One of |
'nve'
|
steps
|
int
|
Number of MD steps. |
1000
|
temperature
|
float
|
Initial / target temperature (K). |
300.0
|
timestep
|
float
|
Timestep in units time (fs for |
1.0
|
seed
|
int
|
RNG seed for the initial velocity distribution. |
12345
|
limit
|
float
|
Per-step displacement cap (Å) for |
0.1
|
pair_style
|
str
|
LAMMPS |
'lj/cut/coul/cut 10.0'
|
atom_style
|
str
|
LAMMPS |
'full'
|
units
|
str
|
LAMMPS |
'real'
|
workdir
|
str | Path | None
|
Working directory; temporary when |
None
|
capture_output
|
bool
|
Capture LAMMPS stdout/stderr. |
False
|
timeout
|
float | None
|
Subprocess timeout in seconds. |
None
|
Returns:
| Type | Description |
|---|---|
Frame
|
A new :class: |
Raises:
| Type | Description |
|---|---|
ValueError
|
If ensemble is unknown or frame has no box. |
minimize ¶
minimize(
frame,
ff,
*,
etol=0.0001,
ftol=1e-06,
max_iter=1000,
max_eval=10000,
pair_style="lj/cut/coul/cut 10.0",
atom_style="full",
units="real",
workdir=None,
capture_output=False,
timeout=None,
)
Energy-minimise frame under force field ff and return a new frame.
Writes a LAMMPS data file and coefficient settings from frame / ff,
runs minimize, then splices the relaxed coordinates back onto a copy
of frame (topology, types, and box preserved). frame is not mutated.
Typical use is removing residual overlaps after packing::
eng = LAMMPSEngine()
relaxed = eng.minimize(pack_result.frame, ff)
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
frame
|
Frame
|
Input structure; must carry a periodic box ( |
required |
ff
|
ForceField
|
Typified force field providing pair/bond/angle/... coefficients. |
required |
etol
|
float
|
Energy stopping tolerance (unitless). |
0.0001
|
ftol
|
float
|
Force stopping tolerance (force units). |
1e-06
|
max_iter
|
int
|
Maximum minimiser iterations. |
1000
|
max_eval
|
int
|
Maximum force/energy evaluations. |
10000
|
pair_style
|
str
|
LAMMPS |
'lj/cut/coul/cut 10.0'
|
atom_style
|
str
|
LAMMPS |
'full'
|
units
|
str
|
LAMMPS |
'real'
|
workdir
|
str | Path | None
|
Directory for input/output files; a temporary directory is
created when |
None
|
capture_output
|
bool
|
Capture LAMMPS stdout/stderr. |
False
|
timeout
|
float | None
|
Subprocess timeout in seconds. |
None
|
Returns:
| Type | Description |
|---|---|
Frame
|
A new :class: |
Raises:
| Type | Description |
|---|---|
ValueError
|
If frame has no box. |
CalledProcessError
|
If LAMMPS exits non-zero. |
RuntimeError
|
If LAMMPS produces no output structure. |