Calculators

The calculator module provides a unified interface to MLIP and classical 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"

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

  • 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. Currently only MACE .model files are supported for custom paths.

  • **kwargs – Extra keyword arguments forwarded to the backend-specific calculator constructor.

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={...})
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_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

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.

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