Interoperability¶
aeolus1d speaks several neighbouring formats so it slots into existing 1D-engine workflows without forcing a full rewrite of the team's toolchain.
| Direction | Tool / format | Module | CLI |
|---|---|---|---|
| Mechanism import | Cantera YAML | aeolus1d.chemistry.importers.cantera_yaml |
n/a (Python API) |
| Result export | CGNS | aeolus1d.io.cgns_writer |
aeolus1d run --cgns OUT.cgns |
| Case import / export | GT-Power XML | aeolus1d.io.interop.gt_power |
aeolus1d import gt_power / aeolus1d export gt_power |
| Case import / export | AVL Boost XML | aeolus1d.io.interop.avl_boost |
aeolus1d import avl_boost / aeolus1d export avl_boost |
| Case import / export | Ricardo WAVE XML | aeolus1d.io.interop.wave |
aeolus1d import wave / aeolus1d export wave |
| Case import | GT-Suite native .gtm |
aeolus1d.io.interop.gt_suite_native |
aeolus1d import gt_suite_native / aeolus1d inspect-gtm |
| Case import | AVL Cruise M .proj |
aeolus1d.io.interop.avl_cruise_m |
aeolus1d import avl_cruise_m |
| Live co-simulation | FMI 2.0 FMU | aeolus1d.io.interop.fmu |
aeolus1d export-fmu CASE.toml OUT.fmu |
Cantera YAML mechanism import¶
from aeolus1d.chemistry.importers.cantera_yaml import import_cantera_yaml
species, reactions = import_cantera_yaml("examples/cantera_h2_air.yaml")
Supported reaction types: elementary / modified Arrhenius,
three-body, falloff (Troe or SRI broadening),
pressure-dependent Arrhenius (PLOG). A type-less bare-(+M)
equation (Cantera ≥ 3.0 made type: three-body optional) is
auto-routed to the three-body path so its [M] dependence and
concentration scaling aren't dropped. Chebyshev rates are
skipped with a warning, as is any unknown type:. NASA-7 thermo
round-trips exactly.
The units: block (Cantera's per-mechanism override) is honoured
for activation-energy units, and a per-reaction local units:
override refines it. Pre-exponential A factors are rescaled
to the internal CHEMKIN cgs cm³-mol convention using the declared
length / quantity units and the reaction order n = Σ ν (a
(+M) collider adds one concentration power), so imported rates
are consistent regardless of the source's volume / quantity
convention.
Install the optional pyyaml dep: pip install -e ".[chemistry-yaml]".
CGNS result export¶
aeolus1d run case.toml --out run.h5 --cgns run.cgns
Each pipe becomes one Structured Zone with GridCoordinates and a
FlowSolution carrying Density, VelocityX, Pressure,
Temperature arrays; junctions emit single-cell zones with the
volume's scalar state. Time-series traces (when --trace-dt is
set) become BaseIterativeData + per-zone FlowSolution_t<idx>
nodes that ParaView / Tecplot can scrub.
Install: pip install -e ".[interop]" (pulls pycgns).
Commercial 1D-tool case import / export¶
The interop layer is best-effort structural: it captures pipe
geometry (length / diameter / friction factor), junction volumes +
connectivity, and the four BC kinds every tool understands (wall,
transmissive, stagnation_inlet, pressure_outlet). Anything
proprietary on the source side (turbo maps, fuel injection, valve
cam tables, combustion sub-models) is dropped at import and listed
in the returned InteropReport; anything aeolus1d-specific
(real-gas EOS, MUSCL / MP5 schemes, LODI port BC, Strang-split
chemistry, Wiebe combustion, learned-NN closures) is similarly
flagged on export.
from aeolus1d.io.interop import import_case, export_case
case, report = import_case("project.gt.xml", kind="gt_power")
print(report.summary())
# ... edit the case in TOML or the GUI ...
export_case(case, "translated.bws", kind="avl_boost")
CLI:
aeolus1d import gt_power path/to/case.gt.xml /tmp/from_gt.toml
aeolus1d run /tmp/from_gt.toml --out /tmp/from_gt.h5
aeolus1d export avl_boost /tmp/from_gt.toml /tmp/to_boost.bws
Vendor case files (GT-Power XML, AVL Boost .bws, WAVE
.wvm, AVL Cruise M .proj, GT-Suite .gtm /
.gtsub) carry proprietary engine-program data and are not
bundled with the repo. The integration tests under
tests/integration/test_avl_cruise_m_* and
tests/integration/test_interop.py skip cleanly when the
fixture path is empty; drop your own file at the path the test
references to enable the run.
Supported tools:
kind |
Source format | Direction |
|---|---|---|
gt_power |
GT-Power Standard Input File (XML) | import + export |
avl_boost |
AVL Boost case (.bws XML) |
import + export |
wave |
Ricardo WAVE case (.wvm XML) |
import + export |
gt_suite_native |
GT-Suite native model (.gtm XML) |
import only (best-effort heuristic) |
avl_cruise_m |
AVL Cruise M project (.proj archive) |
import only |
For gt_power / avl_boost / wave / gt_suite_native a neutral
schematic dataclass (Schematic with NeutralPipe /
NeutralJunction / NeutralBC, plus richer NeutralCylinder /
NeutralShaft / NeutralTurbo / NeutralHeatExchanger /
NeutralController members) sits between aeolus1d and each tool so
adding another target is a small per-tool XML adapter rather than
pairwise translations. gt_suite_native reads GT-Suite's native
.gtm editor XML (<part> / <object> / <va> tags with
t_id database references), as opposed to the clean Standard
Input File (SIF) XML that gt_power reads. It is a best-effort
heuristic — import-only; aeolus1d inspect-gtm prints a diagnostic
summary of a .gtm's object counts before you attempt the import. Cruise M's
component set is richer than
the neutral Schematic (catalysts with full Brinkmeier kinetics,
Monitor → probe translation, fuel routing); its importer reads
straight to aeolus1d.Case and is import-only.
Cruise M import example:
aeolus1d import avl_cruise_m project.proj /tmp/from_cruise.toml
The InteropReport flags catalyst Darcy-Forchheimer α / β
coefficients (held in a binary .ucp file the importer can't
read) and the Brinkmeier rate constants (same source) — both
default to literature values, tune in the inspector.
Brick geometry + initialization (Cruise-S). Cruise M
specifies a monolith brick by Volume + Length and stores a
stale template diameter (often a 56.42 mm default) and
cross_sectional_area alongside that it does not keep in sync.
The importer therefore re-derives the diameter from the
Geometry's geometry_input_selection: volume →
D = sqrt(4V/(πL)), cross_sectional_area → D = sqrt(4A/π);
a stored diameter is used verbatim only when the brick was input
by diameter. Catalyst / filter bricks pair only with
commons_aftertreatment.Geometry objects (never a pipe's), by the
matching-type object emitted immediately before the Topology in
document order — so a brick can't inherit a neighbour pipe's
length / diameter, and adjacent bricks don't collide onto one
geometry. The brick's initial state is lifted too: a catalyst's
solid_temperature → CatalystSpec.T_solid_init, a particulate
filter's substrate solid_temperature →
FilterSpec.T_solid_init (which seeds the soot-cake temperature
when the [pipe.filter.thermal] model is active — the DPF's only
solid thermal mass today), and a filter's initial soot mass →
FilterSpec.trap.soot_loading_init. On the inlet boundary, a
transient temperature table ramp is preferred over an alternate
model's flat const, and mass-fraction compositions stored on a
0–100 percent scale are renormalised to unity.
examples/avl_cruise_m/compare/ holds a harness that runs a
converted case and plots the channels matching each AVL "Results"
figure beside the original screenshot. It is a qualitative
cross-code check: the AVL docs ship results only as screenshots
(no numeric tables), and the full AVL transients (500–7200 s) are
wall-clock-impractical in aeolus1d's density-based, acoustic-CFL-
bound solver — see compare/README.md.
Supported catalyst topology classes (Cruise-E + Cruise-H):
| Cruise M class | aeolus1d closure | Notes |
|---|---|---|
TWCTopology |
twc / twc_brinkmeier |
Three-way (gasoline) — the original Cruise-A..D path. Brinkmeier wins over plain TWC when the AUCI mechanism name says so. |
DOCTopology |
doc_oxidation |
Diesel oxidation. |
SCRTopology |
nh3_scr_kinetics |
Selective Catalytic Reduction (NH3 / urea). |
PNATopology |
none |
Passive NOx Adsorber — geometry + heat path import, kinetics dropped (no aeolus1d closure today; backlog). |
ASCTopology |
doc_oxidation |
Ammonia Slip Catalyst — collapsed onto DOC for the NH3-ox step until a dedicated NH3-slip closure ships. |
AdvancedModelTopology |
model-name-driven | Cruise M's user-defined kinetics container. The AUCI mechanism string (e.g. "SCR transient") selects the closure. |
EEDOCTopology, EESCRTopology, EETWCTopology, EEASCTopology |
same as the non-EE variant | Embedded Element family used in compact / coupled-system studies. |
EEDCPFTopology, EECGPFTopology |
pipe.filter.kind = "diesel_particulate_filter" |
Embedded Element diesel + gasoline soot filters — same trap+cake+regen physics as the full TransientFilterTopology. |
Bundled examples for each: examples/avl_cruise_m/c02001…c02030.
Drop the source .proj next to your own work and rerun
aeolus1d import avl_cruise_m to regenerate.
Supported filter topology classes (Cruise-F):
| Cruise M class | aeolus1d closure | Notes |
|---|---|---|
TransientFilterTopology (cruise.elements.particulate_filter) |
pipe.filter.kind = "diesel_particulate_filter" |
Trap + cake + regen kernels auto-attached with literature defaults. pm_species_name set from the project's ParticulateMatterSpeciesTransport declaration. |
Legacy DPFTopology / DieselParticulateFilterTopology |
same | Kept for back-compat with older .proj exports. |
Supported engine flow elements (Cruise-K + Cruise-L + Cruise-M + Cruise-N + Cruise-O):
| Cruise M class | aeolus1d representation | Notes |
|---|---|---|
gas_flow_pipe.Topology |
aeolus1d pipe | Standard engine-side 1D pipe; same Geometry schema as aftertreatment_pipe. |
plenum.Topology, plenum.GasNodeTopology |
aeolus1d pipe with cubic-root shape | total_volume lifted from cruise.props.plenum.General. First-order 1D approximation of 0-D mixing. |
restriction.Topology, gas_flow_loss.Topology |
aeolus1d pipe with throat diameter | 10 mm-long throat derived from ref_cross_section. Pressure-drop physics is approximate. |
throttle.Topology |
aeolus1d pipe with body diameter | Discharge-coefficient-vs-angle physics drops. |
flange.Topology, elastic_flange.Topology |
aeolus1d pipe (thin pass-through) | Manifold-to-manifold connector. |
air_cleaner.Topology |
aeolus1d pipe (3 L plenum-equivalent) | Air filter — capacitance only. |
gas_heat_exchanger.Topology |
aeolus1d pipe + constant_twall HeatSpec |
Intercoolers / CACs / EGR coolers — total_volume + diameter + Friction.turbulent_coef lifted; default UA + T_coolant attached. |
fan.Topology |
aeolus1d pipe (pass-through) | Fan PR curve drops. |
compressor.Topology, turbine.Topology, turbo_charger.Topology |
aeolus1d pipe (pass-through) | Topology closes end-to-end; turbo map / PR / efficiency dropped (future Cruise-O+ wires TurboSpec). |
generic_transfer.Topology |
aeolus1d pipe (pass-through) | Generic mass-flow transfer block. |
The following Cruise M classes are silently skipped (no aeolus1d topology equivalent at the importer layer; future phases will wire some of them via the closure / component / state layers): FMU databus in/out, PID controllers, MassFlowConnection / Port + Direct injectors, solid_wall / Piston / Liner thermal masses, heat-transfer connections + LHT thermal in/out, combustion_chamber + super_cylinder + cylinder_bank, vehicle / wheel / brake / gearbox / clutch / differential / cockpit, fuel_tank + dosing controllers, general_map / map_of_tables / constants, delay + signal_decoupling, intake/exhaust ports + serial heat-transfer arrangements, UCI databuses, multi_map TopologyCharacteristic, subsystems.
Bundled examples for the full set: 117 TOMLs in examples/avl_cruise_m/ — 30 aftertreatment cases at the top level (c02001–c02030, covering catalyst / DPF / EAT-system / EE studies) plus 87 engine cases under ice/: 6 loose (c060xx dual-fuel / 2-stroke etc.), crank_resolved (30), gas_path (29), gas_exchange (9), tde_vehicle (6), heat_exchanger (4), epw (2) and surrogate_engine (1). All validate via aeolus1d.io.parsers.load_case, lay out via aeolus1d_gui.io.layout_heuristic.layout_for_case, round-trip via aeolus1d_gui.io.case_io.save_case, and advance 0.1 ms in aeolus1d.io.case.run_case (fresh-process smoke).
Cruise M's DPF comparison projects (C02008 layered vs reference,
C02009 multi-collector vs unit-collector, C02010 standard vs
approximated cake-resistance) wire two alternate brick variants
into the same Mass Flow Boundary. The importer keeps the variant
whose connection comes first in flow-graph order and trims the
dangling alternate with a Cruise-F: dropped … warning, so the
imported case stays single-DPF and runnable.
Multi-Modeller projects (typical for the AVL EAT demo set: a
baseline + a coldstart-with-E-Heater variant in the same .proj)
import the model wired to the project's primary flow boundaries.
Orphan catalyst topologies from alternate models are dropped with
a Cruise-E: skipped N orphan catalyst topologies warning so the
user sees which alternates got skipped.
BC translation (Cruise-R)¶
The boundary-condition layer uses an element-class-first dispatch.
The element's short class name (from _short_type) determines the
BC direction without consulting role wording, which fixes the
silent-drop class of bug where AVL's subsystem-nested role names
(e.g. "Air Cleaner Assembly.Restriction 3.Gas Flow IN") didn't
match any of the legacy keyword filters and got dropped without a
warning. Role wording is only consulted as a tiebreaker for the
ambiguous pressure-based classes.
Supported BC element classes:
| Cruise M class | aeolus1d BC kind | Notes |
|---|---|---|
mass_flow_boundary.Topology |
transient_mass_flow_inlet |
ṁ + T₀ schedules from BoundaryConditions::mass_flow + …::temperature. |
boundary.Topology |
transient_pressure_outlet |
Back-pressure schedule from the LAST BoundaryConditions::pressure block in file order. Legacy class — always outlet, preserving the bundled-corpus mapping. |
boundary.TemperatureBoundaryTopology |
(absorbed) | Temperature schedules feed T0_t / T0_v on the paired inlet BC via _extract_t0_spec — no separate BC face emitted. |
pressure_boundary / PressureBoundaryTopology |
transient_stagnation_inlet (pipe end = left) or transient_pressure_outlet (right) |
Defensive class added in Cruise-R; pipe-end + role wording decide direction. |
flow_boundary / node.FlowBoundaryTopology |
transient_mass_flow_inlet |
Mass-flow inlet, same schedule plumbing as mass_flow_boundary. |
volumetric_flow_boundary / VolumetricFlowBoundaryTopology |
transient_velocity_inlet |
u = V̇ / A_pipe using the attached pipe's cross-section. |
A BC follows gas links only (2026-09-23). Cruise M connects elements
with links of several kinds -- gas, mechanical, data bus, thermal -- and a
BC reaches its pipe only along gas: a direct gas link, two gas links through
an intermediate such as a subsystem, or a gas link plus an exposed_port
link on the same port of the intermediate. When several routes through one
intermediate exist, the one that stays inside one of its sub-parts wins, so
a boundary on a turbocharger's compressor inlet attaches to the pipe on the
compressor outlet, not the turbine's. A BC with no such route within two
links is skipped, and the import report names the routes it refused and why.
Before this, a temperature signal or a shaft could carry a gas inlet onto a
flange or across to the intake side. One case is not guarded: a port that
carries a gas link and is also exposed to a mechanical part would still let
a BC through. None of the 143 example projects has one.
Always-transient emission. Every BC kind the importer produces
is one of the transient_* variants. A constant inlet ṁ / V̇ /
p / T₀ or a constant outlet p_back collapses to a single-row
schedule (t=[0.0], v=[const]), eliminating the dual
const/transient code paths the old importer carried. The BC
engine treats a single-row table as a constant at run time, so
there's no runtime cost.
FMI 2.0 FMU export¶
aeolus1d export-fmu examples/03_two_pipes_junction.toml /tmp/aeolus1d.fmu
Produces a single .fmu archive any FMI 2.0 master can load —
GT-SUITE, AVL Boost, MATLAB / Simulink, OpenModelica, Dymola,
Twinmotion. Inputs: one Real per BC marked stagnation_inlet
(p0) or pressure_outlet (p_back). Outputs: pipe-end
pressures + velocities + junction (p, T, m) at each step
boundary. The slave's do_step(t, dt) calls advance_network
once per step; pipe / volume state persists across steps.
Install: pip install -e ".[interop]" (pulls pythonfmu).
Round-trip fidelity¶
Each per-tool import/export is verified by an integration test that round-trips a synthetic XML fixture: schematic → write XML → read XML → schematic, expecting pipe / junction / BC counts and geometry to match. Fidelity against actual GT-Power / AVL Boost / WAVE files would need the proprietary licences and is the caller's responsibility to validate — the warning report documents what the layer dropped.