Monte Carlo and swaps¶
Experimental
MC moves carry an "experimental: not yet qualified" line in the run report until their qualification study is recorded.
FastMACE runs hybrid MD/MC: MD steps on the graph engine, with blocks of MC attempts in between. Species changes are transactional events inside the captured graph, so a swap does not cost a re-capture. The species superset (every species the run may contain) is declared up front.
Move records¶
| Record | Move |
|---|---|
fm.mc.Swap(pairs=[("O", "Cl")], every=100, attempts=50) |
swap the species of two atoms; velocities="exchange" (default), "rescale", "redraw" or "redraw_all" |
fm.mc.Transmute(species=("Na", "K"), every=..., attempts=..., mu={...}) |
semi-grand canonical species change; mu are configurational chemical-potential differences in eV, fm.mc.configurational_mu converts full ones |
fm.mc.Displace(delta_A=0.1, every=..., attempts=...) |
displace one atom in a sphere; adaptive=True retunes δ after every block (equilibration only; sample with a fixed δ) |
Each attempt is accepted by the Metropolis rule at the thermostat's current
target temperature. The thermo output has mc_<move>_attempted and
mc_<move>_accepted columns, and the counters survive restarts.
With fm.md¶
import fastmace as fm
run = fm.md("NaNbOCl4.cif", model="mh1", head="matpes_r2scan",
temperature_K=600, steps=200_000,
mc=fm.mc.Swap(pairs=[("O", "Cl")], every=100, attempts=50),
output="swap/", seed=1)
fm.md infers the species superset and the workload from mc=. With a
constant temperature the MC temperature is that temperature, which must be
positive. With a schedule, min_mc_temperature_K= is required: MC blocks
attach only where the schedule's target is at or above it.
With Simulation¶
model = fm.load("mh1", head="matpes_r2scan")
ff = fm.ForceField(model, atoms, species=["Na", "Nb", "Cl", "O"])
sim = fm.Simulation(
atoms, ff,
integrator=fm.integrators.Langevin(timestep_fs=1.0, temperature_K=600, friction_per_fs=0.002),
workload=fm.Workload(max_temperature_K=1000, species_changes=True, mc_moves=("swap",),
min_mc_temperature_K=250),
output=fm.Output("run/"), seed=1,
)
sim.run(steps=100_000) # MD only
sim.run(steps=100_000, mc=fm.mc.Swap(pairs=[("O", "Cl")], every=100, attempts=50))
sim.run(steps=50_000) # the swap block stays attached
sim.run(steps=50_000, mc=None) # detach
A move set stays attached until a later run passes another mc= or
mc=None. A species outside the superset raises SpeciesNotInSuperset.
From TOML¶
[[mc]]
move = "swap"
pairs = [["O", "Cl"]]
every = 100
attempts = 50
Charge and spin¶
For models that read charges (PolarMACE) or a total charge or spin
(OMOL-0), a transmutation must keep ΔZ − Δq even (formal_charges=), or it
is refused with ChargeParityRefused.
See also: Monte Carlo, Command line and TOML.