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/scfParameters 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
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.
# 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,
"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,
"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)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: "e4ed9888-0c34-4a9d-a227-02fa9d7521e0"
route = ouro.routes.retrieve("mmoderwell/ground-state-scf")
action = route.execute(
body={
"nspin": "auto",
"ecutwfc": 100,
"scf_thr": 0.0001,
"kspacing": 0.3,
"scf_nmax": 120,
"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
cube = action.final_data["cube"]
print(cube["id"])route = ouro.routes.retrieve("mmoderwell/ground-state-scf")
# 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 DFT ground state of a crystal: total energy, magnetization, site moments/charges, and the residual max force and stress on the uploaded geometry. Returns a compact JSON summary plus Gaussian cube charge-density file(s). Use as a baseline energy reference or starting point for other electronic and magnetic properties.
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
64 callsView history