Skip to content

API reference

This section documents the programmatic entry points — the functions and objects you call when you drive aeolus1d from Python instead of the aeolus1d CLI or the desktop GUI. It is the reference for code that looks like the bundled plot scripts under examples/plots/:

import aeolus1d

case = aeolus1d.load_case("examples/01_single_pipe_sod.toml")  # TOML → Case dataclass
pipes, junctions, t_final = aeolus1d.run_case(case)  # build + advance
pipe = pipes["tube"]
rho, u, p = pipe.primitives()                       # (ρ, u, p) over the cells

It is curated, not exhaustive. aeolus1d is a ~100k-line package; this reference covers the public surface you compose against, not every internal solver kernel or importer. For the data the API moves around — every [case] knob, every closure kind, the mechanism / species file formats — see the hand-written field references, which this section links to rather than restates:

Looking for… Page
Every [case] / CaseHeader field Run / case settings
Every closure kind + its TOML fields Closures — reference table
Mechanism + species-DB file formats Chemistry file formats
Which component maps to which model / theory Component index

The public-API contract

import aeolus1d re-exports exactly three names — the smallest surface that takes you from a TOML file to an advanced network:

Name What it does Defined in
load_case Parse + validate a TOML case into a Case dataclass aeolus1d.io.parsers
build_network Materialise a Case into Pipe / junction / BC objects aeolus1d.io.build
run_case Build and advance a Case to t_end aeolus1d.io.case

These three are imported lazily (PEP 562 __getattr__) so a bare import aeolus1d — or aeolus1d --version — stays light and does not pull in the numba / solver stack. The stack imports the first time you touch one of the three names. The canonical definitions live in the modules above; aeolus1d.io.case re-exports build_network and load_case so from aeolus1d.io.case import build_network, load_case also works.

Two ways to advance a network

run_case is the one-call path: it builds the network, wires controllers into the step callback, and advances to t_end. When you need a handle on the built network before it runs — to attach a sampler, seed state for a resume, or trace per-step — build and advance in two steps with build_network + dispatch_advance. That two-step form is what the time-series plot scripts use, because the HDF5 output holds only the final snapshot:

from aeolus1d.io.case import (
    load_case, build_network, dispatch_advance, _case_has_transient_bcs,
)
from aeolus1d.bc.transient import Clock

case  = load_case("examples/74_twc.toml")
clock = Clock() if _case_has_transient_bcs(case) else None
net   = build_network(case, clock=clock)
pipe  = net.pipes["twc"]

samples = []
def on_step(t):            # fires once per completed step
    samples.append((t, pipe.primitives()[2][-1]))   # (t, outlet pressure)

dispatch_advance(
    case, net.pipes, net.junctions, net.bcs,
    clock=clock, on_step=on_step,
    coolant_couplings=net.coolant_couplings,
    wall_thermal_pairs=net.wall_thermal_pairs,
)

dispatch_advance — not the lower-level advance_network — is the correct call: it inspects the case (solver, rk, and whether the network needs the multi-pipe path — junctions, species, catalyst, real-gas EOS, coolant or wall-thermal couplings) and routes to the matching driver — explicit, Strang, implicit (implicit_euler / bdf2 / radau_iia), or quasi-steady — for you. It also forwards the coolant / wall-thermal couplings and live-control handle that each driver needs.

Continue to Driving the solver for the full signatures, Runtime objects for the Pipe / network state you read in on_step, and Closure registry to enumerate the closure kinds programmatically.