Simulation¶
Simulation ¶
MD on the graph engine with a plan, an optional gate, schedules and complete restarts.
Simulation(atoms, force_field, *, species=None, integrator, workload=None, output=None, seed,
check="skip", allow_naive_cueq=False, mode=None, allow_reference=False, fallback=None, gate=None,
runner=None, engine=None, neighbours=None, adaptation=None, calibration=None):
atoms: ASEAtoms, full 3D PBC (§4.4); copied, the caller's object is never changed;force_field: afm.ForceField, anfm.loadresult or a label; a model is wrapped in a float32ForceFieldwithspecies=(default: the structure's species). A path raisesTypeError(load it withfm.load, the trust decision needs one);specieswith aForceFieldraisesValueError(theForceFieldowns the superset);integrator: anfm.integratorsrecord (fm.integrators.RECORDS); a scheme not registered yet is refused by the plan (rule 1);workload:fm.Workload; defaultWorkload(max_temperature_K=integrator.temperature_K);output:fm.Output; thermo rows, trajectory frames andmetadata.jsongo to its directory, in chunks (§10.6).Nonewrites no file;seed: the integrator's noise seed, recorded;check: one ofCHECK_MODES;allow_naive_cueq: accept cuEquivariance's naive kernels (§9.2), recorded;- the planner inputs (
PlannerOptions, recorded insimulation.json):mode(§9.3;Nonelets the planner choose),allow_reference(rule 1),fallback(FallbackConfig, §9.4),gate(GateConfig, §12.3 "Resources"; the record issim.gate_config, the resultsim.gate),runner(RunnerConfig, §8.7),engine(EngineConfig) andneighbours(NeighbourConfig),adaptation(AdaptationConfig, §9.6) andcalibration(CalibrationConfig, §9.1; both phase 5, plan task 5-T01).Nonetakes the defaults, and forengineandneighboursthe default planner's.
fallback
property
¶
fallback: FallbackConfig
The FallbackConfig this simulation was made with (§9.4).
gate_config
property
¶
gate_config: GateConfig
The GateConfig this simulation was made with (§12.3 "Resources"); gate is the result.
gate
property
¶
gate: Any
The gate record (planner.selfcheck.GateRecord, §12.3): status passed, unavailable (with
check="allow_unavailable") or skipped; a failed gate raised GateFailed at construction.
schedule
property
¶
schedule: Any
The attached schedule position (protocols.ScheduleState), or None.
degrees_of_freedom
property
¶
degrees_of_freedom: int
The degrees of freedom of this run's reported temperatures: 3N - 3 under the "mass_weighted"
fixcm projection, 3(N - n_fixed) with FixAtoms, else 3N (io.trajectory.degrees_of_freedom;
SPEC §10.4, decisions 37 and 45).
reference_volume_A3
property
¶
reference_volume_A3: float | None
V0 of the cell-divergence stop: the NPT run's starting volume (ų), kept across a resume.
committed ¶
committed() -> Committed
The committed step as read-only host arrays (flushes any step in flight).
submit_frame ¶
submit_frame(
sink: Callable[[int, Mapping[str, Any]], Any],
) -> None
Queue the committed step's output values for sink(step, values) (host arrays: positions,
momenta, forces, energy, kinetic; cell and stress for NPT). The copies run behind the GPU;
sink is called after the next step has been launched, or by flush_output.
add_sink ¶
add_sink(
sink: Callable[[int, Mapping[str, Any]], Any],
interval: int,
) -> None
Call sink(step, values) for every step of run that is a multiple of interval, with
the values of submit_frame, through the same asynchronous queue as the chunked output (for
fastmace.ase's trajectory and log files). interval is independent of the Output
cadences; the queue is drained, oldest first, at every restart point and at the end of each
run, so a sink has seen every due step up to there. Step 0 is the caller's
(submit_frame).
metadata ¶
metadata() -> dict[str, Any]
The metadata.json record of the run as it stands (provenance.metadata_record).
close ¶
close() -> None
Write what is queued, close the output files and write the final metadata.json.
run ¶
run(
steps: int | None = None,
schedule: Any = None,
mc: Any = ...,
) -> None
Advance steps steps, or along schedule to its end (§7.2 "Schedules and step counts").
schedule=None continues the attached schedule, or keeps the target without one.
mc=... (the default) keeps the attached move set, mc=None detaches it, a move set
attaches it in place of any attached one (§7.6): one fm.mc record (Swap, Transmute,
Displace) or a sequence of them. Every check runs before the first step: a schedule above
Workload.max_temperature_K raises PlanRefused, steps beyond the schedule
ValueError, and the move set that will be attached (given or kept) is checked against the
workload over every step of this call (PlanRefused; SpeciesNotInSuperset for a species
outside the superset).
switch_tier ¶
switch_tier(request)
The tier switch of SPEC §9.6 at the committed step, for request (a planner.adapt.SwitchRequest):
the compiled revision, built from the pristine model, validated, then given the committed state. A
candidate that fails leaves the run on its revision, with a warning (adapt.SWITCH_FAILED_CODE);
returns whether the switch was made. Not inside an MC block, nor from an uncommitted step.
add_metadata_block ¶
add_metadata_block(name: str, provider: Any) -> None
Add {name: provider()} to every metadata.json record this Simulation builds, evaluated at each
write: the fastmace.ase classes' "ase" block (4-T10), in the run's own durable write instead of
a second one per run(). name must not be a key of the record itself.
relax ¶
relax(
*, fmax: float = 0.05, steps: int = 100000000
) -> tuple[Any, dict[str, Any]]
Relax with the optimiser (SPEC §10.3; 4-T05): ASE's Optimizer.run(fmax=, steps=) on the engine.
A converged start takes no step; otherwise one step at a time until the largest constraint-adjusted
force is below fmax (eV/Angstrom) or steps steps are done, one force call per step. A second
call continues with the optimiser's history, as a second run of one ASE optimiser does.
Returns the relaxed Atoms (a copy of the structure at the committed positions and cell, no
calculator) and the summary of fastmace.optimize.driver.relax: steps, converged, seconds,
initial and final energies per atom, fmax, the per-step energies and max forces, and the engine's
neighbour rebuilds and re-captures.
save_restart ¶
save_restart(path: Any) -> None
Write the complete §10.6 state at the current committed step, a canonical restart point.
path is <directory>/restart.npz (or the directory): Simulation.resume(directory)
reads it there. The output queue is drained and the output chunks end here (§10.6), the
engine is canonicalised and written by io.restart.write_engine_restart (T05's format),
and simulation.json next to it holds what that format does not: the model source, the
integrator record, workload, Output, seed, allow_naive_cueq, the planner options,
species, masses and PBC. A plan that runs in a child copies the child's last hand-off, a
canonical restart point at the committed step (2-T07).
Only at a committed step: refused (RuntimeError) inside an MC block and while the engine
holds an uncommitted (overflowed) step, before anything is written (§10.6, 3-T08).
resume
classmethod
¶
resume(
directory: Any,
*,
allow_plan_change: bool = False,
check: Check = "skip",
) -> Simulation
Continue from the restart in directory. A different force-field identity raises
RestartMismatch, except that another MACE or FastMACE version alone warns and is recorded
as a plan revision and in the report (owner decision 23); a different plan needs
allow_plan_change=True and makes a new revision (§9.5, §10.6). check as in the
constructor.
The model is loaded again from simulation.json's file, checked against its SHA-256; the
engine is built at the restart's positions, cell and composition (species and masses at the
restart step, not the initial structure's; 3-T08) through the planner, then takes the
restart's state, edge bucket and neighbour capacity (io.restart.resume_engine). Output
chunks after the restart point are deleted and new ones opened; nothing is rewritten.
set_positions ¶
set_positions(positions: Any) -> None
Host write of positions at a canonical point: quiesce, write, rebuild, re-evaluate (owner
decision D4). positions in Å, shape (N, 3); the momenta stay.
set_momenta ¶
set_momenta(momenta: Any) -> None
Host write of momenta at a canonical point (owner decision D4). momenta in ASE units,
shape (N, 3); the engine integrates velocities, momenta / masses.
update ¶
update(
*,
species: Any = None,
masses: Any = None,
charges: Any = None,
total_charge: Any = None,
friction_per_fs: Any = None,
positions: Any = None,
momenta: Any = None,
cell: Any = None,
) -> None
Any combination of host changes as one transaction with one force evaluation (SPEC §8.5, §7.7).
species: atomic numbers or symbols,(N,); in theForceField's superset (SpeciesNotInSuperset). Masses follow the new species' standard masses unlessmassesis given too;masses: amu,(N,); the momenta stay (ASE), so the velocities change;charges: per-atom charges,(N,), andtotal_charge, for models that take them;friction_per_fs: the Langevin friction in 1/fs (the record's unit); it drops the captured graphs, which bake it in (a recorded re-capture), and with the default barostat τ movesP_tauand the barostat mass with it;positions(Å) andmomenta(ASE units),(N, 3); momenta use the new masses;cell(Å,(3, 3), rows the lattice vectors), fixed-cell runs only (4-T05; 4-T09 relaxes quench frames with their own NPT cells on one engine): the positions are not scaled, so give them too. The lists and cell inputs change in place, so the captured graphs stay unless the rebuild grows a capacity or the edge count needs a new padded size.
Everything is validated before anything is written. The changes apply in this order: species,
masses, charges, friction, cell, positions, momenta; then a canonical point (neighbour list rebuilt at the
committed positions, forces and stress evaluated once, integrator.start), as a host write of
positions (owner decision D4). Nothing given: nothing happens.
set_species ¶
set_species(species: Any) -> None
Set every atom's species (atomic numbers or symbols, shape (N,)), one event. Each must be in
the ForceField's superset (SpeciesNotInSuperset); masses follow the new species' standard
masses unless set_masses follows.
set_masses ¶
set_masses(masses: Any) -> None
Set every atom's mass in amu, shape (N,), one event; the momenta stay (ASE), so the velocities
change: v' = v m_old / m_new.
set_charges ¶
set_charges(
charges: Any, *, total_charge: float | None = None
) -> None
Set the per-atom charges (models that take them), shape (N,), and optionally the total charge,
one event. charges=None with total_charge changes the total only.
set_friction ¶
set_friction(friction_per_fs: float) -> None
Set the Langevin friction in 1/fs, one event; it drops the graphs that bake c1/c2 in (a
recorded re-capture).
Committed
dataclass
¶
The committed step as read-only host arrays: what an observer sees (Simulation.committed).
stress (3×3, eV/ų) is None for fixed-cell integrators; energy in eV. The composition
(3-T03): species atomic numbers (N,), masses amu (N,), charges (N,) or
None for models that take none.