Calculators

The calculator module provides a unified interface to MLIP, classical, ACE and LAMMPS backends.

Calculator factory

amorphgen.utils.calculators.get_calculator(model='mace-mpa-0', device='auto', model_path=None, **kwargs)[source]

Build and return an ASE calculator for the given foundation model.

This is the unified entry point for all supported MLFF backends. The returned object is always a standard ASE calculator that can be attached to any ase.Atoms object.

Parameters:
  • model (str) –

    Short name identifying the model. Examples:

    • MACE: "mace-mpa-0", "mace-mh-1", "mace-omat-0"

    • CHGNet: "chgnet"

    • SevenNet: "sevennet", "7net-mf-ompa", "7net-l3i5"

    • Classical: "lennard-jones", "buckingham"

    • ACE: "ace" (with model_path)

    • LAMMPS: "lammps" (with lammps_params)

    Use list_models() or --list-models to see all options. Ignored if model_path is provided (defaults to MACE backend), unless it is "ace".

  • device (str) – "auto" (default), "cuda", "mps", or "cpu". Auto selects CUDA, then MPS, then CPU, as in the pipeline stages. Without PyTorch installed, auto selects CPU.

  • model_path (str, optional) – Path to a local .model file (e.g. a fine-tuned MACE model). Takes priority over model. A pacemaker .yaml / .yace / .ace file loads an ACE potential instead.

  • **kwargs – Extra keyword arguments forwarded to the backend-specific calculator constructor. The parameter blocks classical_params, lammps_params and ace_params are only accepted by their own backend.

Returns:

A ready-to-use ASE calculator.

Return type:

ase.calculators.calculator.Calculator

Raises:
  • ValueError – If the model name is not recognised by any backend.

  • ImportError – If the required backend package is not installed.

  • FileNotFoundError – If model_path points to a non-existent file.

Examples

>>> calc = get_calculator("mace-mpa-0", device="cuda")
>>> calc = get_calculator("chgnet", device="cpu")
>>> calc = get_calculator("7net-mf-ompa", device="cuda")
>>> calc = get_calculator(model_path="/data/my_finetuned.model")
>>> calc = get_calculator("buckingham", classical_params={...})
>>> calc = get_calculator(model_path="potential.yace")
>>> calc = get_calculator("lammps", lammps_params={
...     "pair_style": "sw", "pair_coeff": "* * Si.sw Si"})
amorphgen.utils.calculators.list_models()[source]

Print the full model registry with per-backend installed markers.

Shows every known model regardless of what is installed (discovery), with a marker per backend section saying whether it is usable right now and, if not, the exact install command (diagnosis).

Return type:

None

Backend detection

amorphgen.utils.calculators.backend_for(model, model_path=None)[source]

The backend that get_calculator() uses for model / model_path.

A model path means MACE (it takes priority over model), except for an ACE potential: model='ace' or a .yaml / .yace / .ace path.

Parameters:
  • model (str)

  • model_path (str | None)

Return type:

str

amorphgen.utils.calculators.backend_available(backend)[source]

True if backend’s python package is importable.

"classical" is always available (NumPy implementation in the base install). Does not import the package — checks the module spec only, so it is cheap and safe on torch-free installs.

Parameters:

backend (str)

Return type:

bool

amorphgen.utils.calculators.available_backends()[source]

Installed-state of every backend, e.g. {"mace": False, "chgnet": True, "sevennet": False, "classical": True}.

Return type:

dict[str, bool]

amorphgen.utils.calculators.require_backend(model, model_path=None)[source]

Fail-fast check that model’s backend is importable.

Returns the backend name when available. Raises BackendNotInstalledError with a curated, copy-pasteable message otherwise (and propagates ValueError for unrecognised models). The CLI calls this BEFORE any setup work; get_calculator() keeps its own lazy import errors as the API-level backstop.

Parameters:
  • model (str)

  • model_path (str | None)

Return type:

str

amorphgen.utils.calculators.require_potential(model, model_path=None, *, engine=None, lammps_params=None, **_params)[source]

Fail-fast check of the ACE / LAMMPS potential before any work starts.

ACE needs an existing potential file and LAMMPS a usable lammps_params block (the same check its loader runs); neither runs on the torch-sim engine. Other backends pass.

Parameters:
  • model (str)

  • model_path (str | None)

  • engine (str | None)

  • lammps_params (dict | None)

Return type:

None

MACE models

The following MACE foundation model names are registered by AmorphGen. Install the mace extra to use them; model weights may download on first use. Slash-separated sizes below represent separate keys (for example, mace-mp-0b3-small, mace-mp-0b3-medium, and mace-mp-0b3-large).

Key

Variant

mace-mp-0a-small/medium/large

MP-0a (initial release)

mace-mp-0b-small/medium/large

MP-0b (improved pair repulsion)

mace-mp-0b2-small/medium/large

MP-0b2 (high-pressure stability)

mace-mp-0b3-small/medium/large

MP-0b3 (fixed phonons)

mace-mpa-0, mace-mpa-0-medium

MPA-0; AmorphGen default

mace-omat-0-small/medium, mace-omat-0

OMAT-0; unsuffixed alias selects medium

mace-matpes-pbe, mace-matpes-r2scan

MATPES models

mace-mh-0, mace-mh-1

Multi-domain models

mace-omol

Molecular model

CHGNet

get_calculator("chgnet", device="auto") loads CHGNet. Install the chgnet extra; CHGNet supports float32 only, which default_dtype="auto" selects.

SevenNet models

Key

Variant

sevennet, sevennet-mf, 7net-mf-ompa

Multi-fidelity foundation (OMat+MPtrj+Alexandria); SevenNet default

7net-mf-0

Multi-fidelity baseline

7net-omat

OMat-only

7net-l3i5

Improved equivariant features

7net-0

Original release (Jul 2024)

7net-omni

Multi-task

Multi-fidelity (mf) variants accept a modal kwarg ('mpa' default, or 'omat24'):

from amorphgen.utils.calculators import get_calculator

calc = get_calculator("7net-mf-ompa", device="auto")  # MPtrj+Alexandria modality
calc = get_calculator("7net-mf-ompa", device="auto", modal="omat24")  # OMat modality

Install the sevennet extra in its own environment because its e3nn requirement conflicts with the MACE extra. Use amorphgen --list-models or list_models() for the registered models and backend installation status.

Classical potentials

Built-in pair potentials for initial structure preparation. No extra install needed.

These calculators provide energy and forces, but no stress tensor. Use cell_filter: none for optimisation and ensemble: NVT for MD; cell relaxation and NPT require a calculator that provides stress. CPU execution uses NumPy; GPU execution requires PyTorch.

Model name

Potential

Parameters required

lennard-jones / lj

4eps[(sig/r)^12 - (sig/r)^6]

epsilon, sigma per pair

buckingham / buck

A*exp(-r/rho) - C/r^6 + Coulomb

A, rho, C per pair + charges

Parameters are passed via classical_params in YAML config or Python API:

from amorphgen.utils.calculators import get_calculator

calc = get_calculator("buckingham", classical_params={
    "params": {("Si", "O"): {"A": 18003.76, "rho": 0.2052, "C": 133.54}},
    "charges": {"Si": 2.4, "O": -1.2},
    "cutoff": 10.0,
})
class amorphgen.utils.classical.LennardJonesCalculator(params, cutoff=10.0, device='cpu', **kwargs)[source]

Bases: Calculator

Lennard-Jones pair potential calculator (vectorized).

V(r) = 4 * epsilon * [(sigma/r)^12 - (sigma/r)^6]

Parameters:
  • params (dict) – Per-pair LJ parameters, e.g. {(“Ar”, “Ar”): {“epsilon”: 0.0104, “sigma”: 3.40}} Pairs are symmetric: (“A”,”B”) == (“B”,”A”).

  • cutoff (float) – Cutoff distance in Angstrom.

  • device (str) – “cpu” (default, vectorized NumPy) or “cuda”/”mps” (PyTorch GPU).

implemented_properties: list[str] = ['energy', 'forces']

Properties calculator can handle (energy, forces, …)

calculate(atoms=None, properties=['energy'], system_changes=['positions', 'numbers', 'cell', 'pbc', 'initial_charges', 'initial_magmoms'])[source]

Do the calculation.

properties: list of str

List of what needs to be calculated. Can be any combination of ‘energy’, ‘forces’, ‘stress’, ‘dipole’, ‘charges’, ‘magmom’ and ‘magmoms’.

system_changes: list of str

List of what has changed since last calculation. Can be any combination of these six: ‘positions’, ‘numbers’, ‘cell’, ‘pbc’, ‘initial_charges’ and ‘initial_magmoms’.

Subclasses need to implement this, but can ignore properties and system_changes if they want. Calculated properties should be inserted into results dictionary like shown in this dummy example:

self.results = {'energy': 0.0,
                'forces': np.zeros((len(atoms), 3)),
                'stress': np.zeros(6),
                'dipole': np.zeros(3),
                'charges': np.zeros(len(atoms)),
                'magmom': 0.0,
                'magmoms': np.zeros(len(atoms))}

The subclass implementation should first call this implementation to set the atoms attribute and create any missing directories.

class amorphgen.utils.classical.BuckinghamCalculator(params, charges=None, cutoff=10.0, alpha=None, coulomb=True, coulomb_method='ewald', device='cpu', **kwargs)[source]

Bases: Calculator

Buckingham + Coulomb pair potential calculator (rigid-ion, vectorized).

V(r) = A * exp(-r/rho) - C/r^6 + q_i * q_j / (4*pi*eps0*r)

The Coulomb term is evaluated by Ewald summation (default; real-space sum over the neighbour list + reciprocal-space sum + self term) or, if coulomb_method="wolf", by the damped-shifted Wolf sum. This is an approximation to full Ewald – accurate for amorphous structures but not for crystalline long-range order.

Parameters:
  • params (dict) – Per-pair Buckingham parameters, e.g. {(“Si”, “O”): {“A”: 13702.905, “rho”: 0.193817, “C”: 54.681}}

  • charges (dict) – Per-element charges in electron units, e.g. {“Si”: 2.4, “O”: -1.2}

  • cutoff (float) – Cutoff distance in Angstrom.

  • alpha (float, optional) – Splitting/damping parameter (1/Angstrom). Default 3.5/cutoff for Ewald (real-space part converged at the cutoff), 0.2 for Wolf.

  • coulomb_method ({"ewald", "wolf"}, default "ewald") – Ewald reproduces the exact periodic Coulomb energy and forces; the Wolf sum is faster but only approximate (~10 % force error for an ionic melt at a 10 A cutoff).

  • coulomb (bool) – If True, include Coulomb interactions. Default True.

  • device (str) – “cpu” (default, vectorized NumPy) or “cuda”/”mps” (PyTorch GPU).

implemented_properties: list[str] = ['energy', 'forces']

Properties calculator can handle (energy, forces, …)

calculate(atoms=None, properties=['energy'], system_changes=['positions', 'numbers', 'cell', 'pbc', 'initial_charges', 'initial_magmoms'])[source]

Do the calculation.

properties: list of str

List of what needs to be calculated. Can be any combination of ‘energy’, ‘forces’, ‘stress’, ‘dipole’, ‘charges’, ‘magmom’ and ‘magmoms’.

system_changes: list of str

List of what has changed since last calculation. Can be any combination of these six: ‘positions’, ‘numbers’, ‘cell’, ‘pbc’, ‘initial_charges’ and ‘initial_magmoms’.

Subclasses need to implement this, but can ignore properties and system_changes if they want. Calculated properties should be inserted into results dictionary like shown in this dummy example:

self.results = {'energy': 0.0,
                'forces': np.zeros((len(atoms), 3)),
                'stress': np.zeros(6),
                'dipole': np.zeros(3),
                'charges': np.zeros(len(atoms)),
                'magmom': 0.0,
                'magmoms': np.zeros(len(atoms))}

The subclass implementation should first call this implementation to set the atoms attribute and create any missing directories.

ACE and LAMMPS potential files

Model name

Potential

Settings

ace

ACE potential file via pyace’s PyACECalculator

model_path (.yaml / .yace / .ace, which alone selects ACE); optional ace_params

lammps

any LAMMPS pair style via ASE’s LAMMPSlib

lammps_params (pair_style, pair_coeff, optional elements, commands, masses, lammps_header, amendments, log_file)

Both run on the CPU in float64 and supply stress; neither runs on the torch-sim engine. Install the ace or lammps extra. See Calculator backends for the LAMMPS type-order rules.

from amorphgen.utils.calculators import get_calculator

calc = get_calculator(model_path="output_potential.yaml")
calc = get_calculator("lammps", lammps_params={
    "pair_style": "tersoff", "pair_coeff": "* * SiC.tersoff Si C"})
amorphgen.utils.lammps_potential.lammps_setup(params)[source]

Validate a lammps_params block and build the LAMMPSlib arguments.

Pure: LAMMPS itself is not imported, so this also serves as the CLI’s fail-fast check.

Parameters:

params (dict) – pair_style (str) and pair_coeff (str or list) are required. Optional: elements (element of each LAMMPS type, in type order; inferred from pair_coeff * * <file> El1 El2 ... when omitted), commands (more LAMMPS commands run after the pair_coeff lines), masses (element → amu), lammps_header and amendments (passed to LAMMPSlib unchanged) and log_file.

Returns:

lmpcmds, elements, atom_types, files (absolute paths of the potential files found in the commands), masses, lammps_header, amendments and log_file.

Return type:

dict

class amorphgen.utils.lammps_potential.LAMMPSCalculator(*, potential_files=(), **kwargs)[source]

Bases: LAMMPSlib

LAMMPSlib with an explicit type map and absolute potential paths.

Build it with make_lammps_calculator(). elements lists the element of each LAMMPS type and potential_files the potential files its commands read (hashed into the run manifest).

start_lammps()[source]
calculate(atoms=None, properties=('energy',), system_changes=['positions', 'numbers', 'cell', 'pbc', 'initial_charges', 'initial_magmoms'])[source]

Do the calculation.

properties: list of str

List of what needs to be calculated. Can be any combination of ‘energy’, ‘forces’, ‘stress’, ‘dipole’, ‘charges’, ‘magmom’ and ‘magmoms’.

system_changes: list of str

List of what has changed since last calculation. Can be any combination of these six: ‘positions’, ‘numbers’, ‘cell’, ‘pbc’, ‘initial_charges’ and ‘initial_magmoms’.

Subclasses need to implement this, but can ignore properties and system_changes if they want. Calculated properties should be inserted into results dictionary like shown in this dummy example:

self.results = {'energy': 0.0,
                'forces': np.zeros((len(atoms), 3)),
                'stress': np.zeros(6),
                'dipole': np.zeros(3),
                'charges': np.zeros(len(atoms)),
                'magmom': 0.0,
                'magmoms': np.zeros(len(atoms))}

The subclass implementation should first call this implementation to set the atoms attribute and create any missing directories.

Deprecated aliases

amorphgen.utils.calculators.get_mace_calculator(model='mace-mpa-0', device='cuda', model_path=None, **kwargs)[source]

Build and return a MACE calculator.

Deprecated since version 2.0.0: Use get_calculator() instead, which supports MACE and all other backends (CHGNet, SevenNet).

Parameters:
  • model (str) – MACE model short name (e.g. "mace-mpa-0").

  • device (str) – "cuda" or "cpu".

  • model_path (str, optional) – Path to a local .model file.

  • **kwargs – Forwarded to MACECalculator or mace_mp().

Return type:

ASE calculator