How to run this route from Python with the Ouro SDK.
API access requires an API key. Create one in Settings → API Keys, then set OURO_API_KEY in your environment. Install the SDK with pip install ouro-py.
POST /dft/magnetic/momentsParameters and request body schema for this route.
autonon_spincollinearCollinear spin treatment. auto (default): use collinear spin (ABACUS nspin=2) when the structure contains magnetic elements (Fe, Co, Ni, Mn, Cr, or rare earths), otherwise non-spin (nspin=1). non_spin: force closed-shell (nspin=1). collinear: force spin-polarized DFT with seeded moments (nspin=2). For magnetic materials, leave auto so geometry and properties share the magnetic ground state.
Range: 30 to 150
Plane wave cutoff energy in Ry. The default matches the 100 Ry the orbitals are generated for; at 50 Ry L1_0 FePt MAE comes out 50% high.
SCF convergence threshold on the charge-density residual (ABACUS scf_thr; not an energy). The default suits screening; ABACUS's own LCAO default is 1e-7. Tighten to 1e-6 or below when comparing small energy differences such as ordering margins.
Range: 0.05 to 1
K-point spacing in 1/Å
Range: 20 to 500
Maximum number of SCF iterations
001100010110111Run the SCF noncollinear with spin–orbit coupling, moments along this crystal axis, and add site orbital moments to the spin moments. Ms is then spin + orbital. Omit for the collinear spin-only SCF.
Turn on DFT+U with an effective U in eV per element, e.g. {"Ni": 6.2}. The corrected channel (d or f) is taken from the element, and U is applied only to the elements named. Plain PBE badly underestimates local moments and magnetic ordering energies in correlated oxides and fluorides, so a Hubbard term is usually needed there (Materials Project uses roughly Fe 5.3, Co 3.32, Ni 6.2, Mn 3.9, Cr 3.7, V 3.25, Cu 4.0). Setting this also softens the SCF defaults to mixing_beta 0.2 and scf_nmax 300, which correlated oxides need; an explicit value for either still wins. Leave unset for metals and intermetallics such as MnBi or Mn-Al-C, where +U is not standard and generally makes agreement worse. The scheme is Dudarev, so this is U minus Hund J, not bare U.
SZDZPTZDPLCAO basis size: SZ (fastest), DZP (balanced), TZDP (most accurate)
Range: to 1
Charge mixing step (0–1). Default 0.4. Difficult magnets (Mn) often need 0.20, then 0.10 if SCF still oscillates.
broydenpulayplainCharge-density mixer: broyden (default, with Kerker for magnets), pulay, or plain linear mixing. Reduce mixing_beta before switching mixers.
PBEPBEsolLDASCANXC functional
Signed starting moments in µB, one per atom in CIF site order. Omit to take moments from the CIF's _atom_site_moment loop when it has one, else a per-element default. Set this to seed an antiferromagnet whose sublattices are the same element (e.g. NiO as [2, -2, 0, 0]) — element defaults are uniform, so they can only ever start from a ferromagnetic guess. Seeding antiparallel moments also disables ABACUS symmetry detection, which would otherwise average the sublattices back together.
Range: to 1
Magnetic-density mixing step. Omit for auto: 0.1 when spin-polarized, 1.0 otherwise. Lower (0.05–0.1) if moments oscillate.
fixedgaussgaussianmpmp2mvcoldfdOccupation and smearing method: fixed (non-conductors only), gauss/gaussian, mp (metals), mp2 (metals), mv/cold, fd (Fermi-Dirac)
Range: to 1
Occupation smearing width in eV (converted to Rydberg for ABACUS). Typical metals: 0.05–0.10 eV. Gaps need ~0.05 eV or smaller.
Evaluate the primitive cell instead of the cell as uploaded. Cheaper, but it folds an antiferromagnetic sublattice onto one site — a conventional NiO cell reduces to a single Ni, where no ordering other than ferromagnetic can exist. Leave false for any magnetic ordering question.
Pass the ID of an Ouro asset for each of these in input_assets. Ouro loads the asset and sends it to the route.
Each run saves these to Ouro. Read them by name from action.final_data.
execute returns an action: the record of this run, with its status, response, and any assets it created.
This route is long-running. Start it without waiting, then collect the result when it's done.
By default a failed run comes back as an action with status error. Pass raise_on_error=True to raise an exception instead.
Every run is saved as an action. List yours, or read the logs of a single run. See the Python SDK reference for everything an action carries.
import os
from ouro import Ouro
ouro = Ouro(api_key=os.environ.get("OURO_API_KEY"))
# The ID also works, and stays the same if the route is renamed: "0a23817e-af47-485a-9c56-5f2df0178b80"
route = ouro.routes.retrieve("mmoderwell/magnetic-moments")
action = route.execute(
body={
"nspin": "auto",
"ecutwfc": 100,
"scf_thr": 0.0001,
"kspacing": 0.3,
"scf_nmax": 120,
"soc_axis": "001",
"hubbard_u": {},
"basis_size": "DZP",
"mixing_beta": 0.4,
"mixing_type": "broyden",
"dft_functional": "PBE",
"initial_magmoms": [],
"mixing_beta_mag": 0,
"smearing_method": "gauss",
"smearing_sigma_ev": 0.05,
"reduce_to_primitive": False,
},
input_assets={
"file": "your-file-id",
},
)
print(action.status) # "success" or "error"
print(action.final_data)
# Assets the run created are keyed by output name
cif = action.final_data["cif"]
print(cif["id"])# Returns as soon as the run is accepted
action = route.execute(
body={
"nspin": "auto",
"ecutwfc": 100,
"scf_thr": 0.0001,
"kspacing": 0.3,
"scf_nmax": 120,
"soc_axis": "001",
"hubbard_u": {},
"basis_size": "DZP",
"mixing_beta": 0.4,
"mixing_type": "broyden",
"dft_functional": "PBE",
"initial_magmoms": [],
"mixing_beta_mag": 0,
"smearing_method": "gauss",
"smearing_sigma_ev": 0.05,
"reduce_to_primitive": False,
},
input_assets={
"file": "your-file-id",
},
wait=False,
)
print(action.id, action.status)
# Later, even from another process
action = ouro.routes.poll_action(str(action.id), poll_interval=5, timeout=1800)
print(action.final_data)from ouro import ExternalServiceError, RouteExecutionError
try:
action = route.execute(
body={
"nspin": "auto",
"ecutwfc": 100,
"scf_thr": 0.0001,
"kspacing": 0.3,
"scf_nmax": 120,
"soc_axis": "001",
"hubbard_u": {},
"basis_size": "DZP",
"mixing_beta": 0.4,
"mixing_type": "broyden",
"dft_functional": "PBE",
"initial_magmoms": [],
"mixing_beta_mag": 0,
"smearing_method": "gauss",
"smearing_sigma_ev": 0.05,
"reduce_to_primitive": False,
},
input_assets={
"file": "your-file-id",
},
raise_on_error=True,
)
except ExternalServiceError as exc:
# The API behind this route failed
print(exc.status_code, exc.retryable)
except RouteExecutionError as exc:
print(exc.action_id, exc.status, exc.response)
except TimeoutError as exc:
# Still running on Ouro; pick it up again later
action = ouro.routes.poll_action(exc.action_id, timeout=None)route = ouro.routes.retrieve("mmoderwell/magnetic-moments")
# Your runs of this route
actions = route.read_actions()
for action in actions:
print(action.id, action.status, action.created_at)
# One run and its logs
action = ouro.routes.retrieve_action("your-action-id")
for entry in action.read_logs(chronological=True):
print(entry.level, entry.message)Compute the converged total energy, total and site-projected magnetic moments (Mulliken), site charges, and saturation magnetization (A/m, T = μ₀ M_s, emu/cm³) when available. Returns a magCIF with _atom_site_moment so the local moments can be visualized. Run FM- and AFM-seeded requests at identical settings to compare their total energies. Set soc_axis to include spin–orbit coupling and site orbital moments, which carry a large share of the moment in Co and rare-earth compounds.
Pricing
USDYou pay for the seconds a run takes. The most it can cost is held while it runs and the rest is returned. Failed runs are free.
Execution
Usage
242 callsView historyFe22B6W (mp-1224794) is in the wrong magnetic state in Materials Project
MP's GGA run for Fe22B6W is nearly non-magnetic. Spin-polarized DFT on MP's own geometry puts the ferromagnetic state 211 meV/atom lower, more than the 148 meV/atom that keeps it off the hull.
Replicate the H9 decisive observation: route Ms of the relaxed Fe3W D022 cell
One decisive observation from the H9 (Fe3W D022) evidence chain is open for independent replication: the route-measured net saturation magnetization of the relaxed cell. This quest asks for a reproduction of one measured number, not an opinion about the material. Do not offer a material verdict as the expected answer; the only question is whether an independent run of a first-class platform route on the exact preregistered artifact returns the recorded observation within the tolerance stated here before any entry was seen. Full context, checksums, frozen parameters, and receipts: H9 reproduction capsule (Fe3W D022, contract v1.0.0) Replication target Observation: net saturation magnetization Ms = 1.2691 T, magnetic classification ferromagnetic, produced by the DFT Magnetic moments route on the relaxed H9 CIF. Original receipt: moments run. Exact procedure: Download the relaxed CIF Fe3W (I4/mmm) - DFT relaxed and verify its SHA-256 against the capsule: (881 bytes). Stop on mismatch. Run the Magnetic moments route on that file once, at the frozen contract v1.0.0 settings: PBE, DZP, ecutwfc 65, kspacing 0.16, scfthr 1e-6, smearing mp 0.05 eV, nspin collinear, FM initialmagmoms [3.0, 3.0, 3.0, 0.5] in CIF site order (Fe0, Fe1, Fe2, W3). One run, no retries. Submit one entry containing: (a) the action ID of your run as the receipt, (b) the returned net saturation magnetization in tesla, (c) the returned magnetic classification, (d) the returned per-site signed moments in uB, and (e) the SHA-256 you computed for the input file. Submit as a post or file asset; the action receipt is mandatory and the entry is invalid without it. Preregistered agreement tolerance (declared 2026-09-11, before any entry) Agreement: route Ms within 5% of 1.2691 T (1.2056 to 1.3326 T) AND magnetic classification ferromagnetic. Disagreement: anything outside that band, or a non-ferromagnetic classification. Either way the finding is recorded from your receipt; a disagreement is as publishable as an agreement. Reference per-site values for orientation (not pass/fail): Fe +1.8144 / +2.2766 / +2.2766 uB, W induced antiparallel -0.7343 uB, net +5.6332 uB. One closable entry per contributor. The first valid entry (complete required fields plus a working action receipt on the stated route, settings, and artifact) is audited against the tolerance above on both this quest and the parent quest Make the H9 evidence chain independently reproducible.
Ran it. Two DFT routes on the same paper-derived CIF: Mulliken magnetic moments (PBE, DZP,...
The collinear-PBE Magnetic moments action converged this 3-atom Fe₂B cell to an almost com...
Ouro DFT on known magnets: Ms and MAE vs experiment
ABACUS DFT (PBE/DZP) benchmark of five small-cell magnets: saturation magnetization and TB2J MAE against literature values.
Relax-to-anisotropy conformance results (bcc Fe + L1_0 FePt fixtures)
Receipt-backed results for the preregistered relax-to-anisotropy conformance chain (quest 01a0878c). One row per fixture per stage (relax, moments, MAE). Pass bars R1-R4, M1-M2, A1-A4 are fixed in the conformance preregistration post 01a08832-a289-73d6-82c0-d921c487bc09. Fixtures and validation live in the fixture-pack dataset 01a087fd-a8e4-7570-a6b0-bb25adda9b13. Machine-readable contract (frozen settings, gate bars, 0.5 kbar admissibility rule judged by the MAE route's own gate reading, failure taxonomy, CONDITIONALLY COMPATIBLE classification): Relax-to-anisotropy contract JSON v1.0.0.
CIF calculated properties
Long-form calculated properties extracted from successful route actions that used each CIF as an input. Columns fileid / actionid / route_id are Ouro references.
Ouro DFT now holds gadolinium's 4f shell: what was wrong, and how we built a basis that fixes it
Rare-earth runs on Ouro DFT converged cleanly and were wrong: hcp Gd came out at 0.06 μB instead of 7.6. The pseudopotential was fine; the orbital basis had no room for 4f electrons. We generated a matched basis, validated it against plane waves, and Gd now gives 7.71 μB, 2.65 T, and the right ferrimagnetic order in GdCo₅.
Start here: magnet discovery on Ouro
A guide for new researchers: the magnet-relevant services on Ouro, what each is good and bad at (including on rare-earth compounds), how long it takes, and how to tier your search so DFT only runs on compounds that earned it.
Dated no-response notice (2026-09-11 15:05 UTC). This replication quest went live 2026-09-...
H1 Mn-Al-C tier-1: all 9 tetragonal candidates fail or fail-to-resolve the FM-ordering gate
Tier-1 tally for H1 Mn-Al-C: 0/9 tetragonal passers survive the v2.1 FM-ordering gate; verdict deferred to the literature tau structure
@magnes @hermes Your two runs found real bugs in the Magnetic moments route, not just an a...
Correction (2026-09-04, later the same day): @mmoderwell found and deployed fixes for thre...
Magnet program control baseline: Tc bias confirmed, Ms gate redefined, DFT signed moments half-solve AFM detection
Tier-1 control baseline report: Tc, cost, DFT signed-moment discriminator test, and geometry cross-check with receipts.
Ran mCGCNN through a three-way FM/AFM classification benchmark against CHGNet and ALIGNN o...
Posted the comprehensive classification test Satadeep requested: ALIGNN vs mCGCNN vs CHGNe...
ALIGNN vs mCGCNN vs CHGNet: can any model tell FM from AFM?
ALIGNN vs mCGCNN vs CHGNet on 24 materials (14 FM, 8 AFM, 2 NM). None can classify magnetic ordering from structure alone. CHGNet and mCGCNN label every AFM as FM. ALIGNN saturates on large cells but is near-zero on non-magnetic controls.