Skip to main content
The EOS task calculates the equation of state (EOS) for a crystal. It:
  1. Fully relaxes the input structure (positions + cell) using OPT.
  2. Generates npoints uniformly strained copies of the relaxed cell spanning ±max_abs_strain.
  3. Relaxes atomic positions inside each strained cell (cell shape fixed).
  4. Fits a Birch-Murnaghan EOS to the resulting energy-volume data.
All per-strain optimizations can be dispatched concurrently via Prefect.

Function signature

from mlip_arena.tasks import EOS

result = EOS(
    atoms=atoms,
    calculator=calc,
    optimizer="BFGSLineSearch",
    optimizer_kwargs=None,
    filter="FrechetCell",
    filter_kwargs=None,
    criterion=None,
    max_abs_strain=0.1,
    npoints=11,
    concurrent=True,
    cache_opt=False,
)

Parameters

body.atoms
ase.Atoms
required
Input structure. A copy is made internally.
body.calculator
ase.calculators.calculator.BaseCalculator
required
ASE calculator for energies and forces.
body.optimizer
Optimizer | str
default:"BFGSLineSearch"
Optimizer passed to the internal OPT tasks. See structure optimization for valid values.
body.optimizer_kwargs
dict | None
default:"None"
Extra keyword arguments forwarded to the optimizer.
body.filter
Filter | str | None
default:"FrechetCell"
Cell filter used for the initial full relaxation. Set to None to skip cell relaxation.
body.filter_kwargs
dict | None
default:"None"
Extra keyword arguments forwarded to the filter.
body.criterion
dict | None
default:"None"
Convergence criterion dict forwarded to each OPT run (e.g. {"fmax": 0.01}).
body.max_abs_strain
number
default:"0.1"
Maximum absolute volumetric strain applied to the equilibrium cell. A value of 0.1 spans cell scale factors from 0.9^(1/3) to 1.1^(1/3) along each axis.
body.npoints
number
default:"11"
Number of volume points sampled along the strain range, including the endpoints.
body.concurrent
boolean
default:"true"
If True, all per-strain OPT tasks are submitted concurrently using OPT.submit() and collected with prefect.futures.wait. Set to False for serial execution.
body.cache_opt
boolean
default:"false"
If True, intermediate OPT results are persisted and cached in Prefect’s result store. Useful when re-running the EOS with the same structure.

Return value

Returns a dict with the following keys on success, or a Prefect State object if the initial relaxation fails:
KeyTypeDescription
atomsase.AtomsFully relaxed equilibrium structure
eosdict{"volumes": [...], "energies": [...]} — raw E-V data sorted by volume
KfloatBulk modulus in GPa (Birch-Murnaghan B0)
b0floatBulk modulus in eV/ų
b1floatPressure derivative of the bulk modulus
e0floatEquilibrium energy in eV
v0floatEquilibrium volume in ų

Example

1

Import and prepare

from ase.build import bulk
from mlip_arena.tasks import EOS
from mlip_arena.tasks.utils import get_calculator
from mlip_arena.models import MLIPEnum

atoms = bulk("Si", "diamond", a=5.43)
calc = get_calculator(MLIPEnum.MACE_MP)
2

Run the EOS task

result = EOS(
    atoms=atoms,
    calculator=calc,
    max_abs_strain=0.1,
    npoints=11,
    criterion={"fmax": 0.01},
)
3

Inspect results

print(f"Bulk modulus: {result['K']:.1f} GPa")
print(f"Equilibrium volume: {result['v0']:.3f} ų")
print(f"Equilibrium energy: {result['e0']:.4f} eV")

volumes  = result["eos"]["volumes"]
energies = result["eos"]["energies"]
The EOS task uses a Birch-Murnaghan fit via pymatgen.analysis.eos.BirchMurnaghan. At least 4 converged points are needed for a meaningful fit. Increase npoints if you need higher resolution on the E-V curve.