Milestone 8 — Cruise M import completeness¶
A coverage-driven roadmap. The acceptance criterion for each phase is "this Cruise M element type imports cleanly into a runnable aeolus1d case." Where Milestone 7 has a parallel feature-driven phase, this doc cross-references it; the two are scheduled together but tracked separately so we can see Cruise M parity specifically.
The driver: a typical engine + aftertreatment Cruise M .proj
contains 15-25 element types. The current importer
(post-Phases A21–A26) covers aftertreatment_pipe /
TWCTopology / mass_flow_boundary / boundary / monitor
plus the supporting catalogues — that's ~5 of the 15-25.
Everything else falls into lossy_components even when aeolus1d
already has the physics. This milestone closes that gap.
Update 2026-07: this roadmap has since been largely
executed and is retained as a historical planning record. Nearly
every phase has shipped, though a few landed under different
names/shapes than proposed below (the plan predates the final
implementation): 8b DOC/SCR + 8a breathing-path recognition
(src/aeolus1d/io/interop/avl_cruise_m/); 8c multi-injector
cylinders (InjectorSpec / CylinderSpec.injectors, ADR-0009);
8d heat-exchanger ε-NTU as EGR-cooler / charge-air-cooler heat
kinds (closures/heat.py); 8e urea as [pipe.urea]
kind="urea_spray" + the hnco_hydrolysis reaction (not a
urea_decomposition kind); 8f DPF as a [pipe.filter]
kind="diesel_particulate_filter" block with a per-cell
soot_loading accumulator (closures/filter.py), which also
covers 8i; 8g wastegate control (control/wastegate_controller.py);
8z FMI 2.0 export scaffolding (src/aeolus1d/fmi.py). The scope
boundary was also superseded: rather than deferring everything
to FMI, aeolus1d grew native vehicle/powertrain models —
vehicle.py, driveline.py, transmission_shift.py, hybrid.py,
coolant.py, drive_cycles.py, driver.py. Treat the
per-phase approach text below as the original design intent, not
the as-built implementation.
Scope boundary. Vehicle dynamics, transmission, hybrid drive (electric machine, battery, inverter), cooling system, and ECU controller logic are explicitly out of scope — those belong in a coupled-simulation tool that calls aeolus1d via FMI. Phase 8z covers the FMI-export surface for that hand-off.
Importer-side gaps (aeolus1d has the physics)¶
These phases are pure plumbing — no new aeolus1d closures needed; the importer's element-recognition list just needs extending. Roughly 3-5 days for the whole bucket.
Phase 8a — Engine breathing-path elements¶
Goal. Recognise cylinder.Topology, injector.Topology,
valve.Topology, compressor.Topology, turbine.Topology,
shaft.Topology, intake / exhaust manifold elements; map each
to its existing aeolus1d model.
Mappings (existing aeolus1d):
| Cruise M element | aeolus1d model |
|---|---|
cylinder.Topology |
Cylinder (slider-crank + Wiebe + ports) |
injector.Topology |
injection schedule on Cylinder (or [[cylinder.injector]] after 8b ships) |
valve.Topology |
CylinderPort valve windows |
compressor.Topology |
Compressor with TurboMap |
turbine.Topology |
Turbine with TurboMap |
shaft.Topology |
Shaft (I·dω/dt = (Ẇ_T − Ẇ_C)/ω) |
| Intake / exhaust manifold | Junction (plenum) |
Effort. ~3-4 days. Per-element parameter extraction is the
work; the dispatch shape is the same as the existing
aftertreatment_pipe / TWCTopology branches.
Risk. Medium. Cruise M's per-template parameter layouts
vary; the existing gt_suite_native importer's parameter
mapping is the cautionary tale. Some parameters (cylinder
bore / stroke / clearance volume) live in well-known fields;
others (valve lift schedules, turbine map data) may live in
referenced sub-objects we'd need to graph-walk to.
Done when. A Cruise M .proj with a single-cylinder
naturally-aspirated engine imports as a runnable aeolus1d
network without lossy-element warnings for the breathing path.
Phase 8b — DOC / SCR catalyst topology recognition¶
Goal. Extend the catalyst-pipe branch to recognise
DOCTopology and SCRTopology alongside the existing
TWCTopology. The _closure_for_class dispatcher already
maps each to the right aeolus1d reaction kind
(doc_oxidation / nh3_scr_kinetics); the topology parser
just needs to add the elements to its recognition list.
Effort. ~1 day. Mostly testing — the dispatcher already handles the catalyst-kind selection.
Done when. A Cruise M case with a DOC + SCR + TWC chain imports with each catalyst pipe carrying the right aeolus1d reaction kind.
Aeolus-feature gaps (new physics needed)¶
Phase 8c — Multi-injector cylinders (same as Phase 7a sub-1)¶
Goal. Per-cylinder [[cylinder.injector]] blocks for
split injection (pilot + main of the same fuel) and dual-fuel
(H₂ pilot + NH₃ main, or diesel pilot + NG main). Each
injector carries its own (cad, rate, m_fuel_per_cycle,
T_fuel, cv_fuel, fuel_species_name).
Approach. Schema: InjectorSpec dataclass +
CylinderSpec.injectors: list[InjectorSpec]. Runtime:
Cylinder.injectors: list[dict] with cached cycle integral
per injector; rates sum into composite ṁ_fuel; Wiebe uses
the summed m_fuel_per_cycle. Per-injector
fuel_species_name writes to the matching pipe inflow
channel during open-valve windows.
Effort. ~3-4 days. Already started — partial work in
git stash@{0} (schema + parser + half of cylinder
runtime).
Risk. Medium. The Cylinder runtime touches species-
coupling, blowback bookkeeping, and Wiebe heat release —
fanning multiple injectors through that needs careful
treatment of the cylinder's composite Y_fuel scalar.
Done when. A pilot+main diesel cylinder runs to steady state with per-injector rate shapes summing into the right total fuel mass per cycle; per-fuel species columns at connected pipes show separate H₂ vs NH₃ inflows in a dual-fuel test case.
Cross-ref. Milestone 7, Phase 7a sub-piece "multi-injector cylinders for dual-fuel cases".
Phase 8d — Heat-exchanger ε-NTU component¶
Goal. A new pipe-mounted closure or standalone component modelling intercooler / EGR cooler / charge-air cooler heat extraction. Effectiveness-NTU formulation:
Q̇ = ε · ṁ · c_p · (T_hot_in − T_cold_in)
with ε and the cold-side conditions (T_coolant) as user inputs. Energy sink on the gas side; coolant side is a prescribed T (no coolant-loop solver — that's out of scope).
Approach. Either a new closure kind on Pipe (similar
shape to heat's constant_twall) parameterised by
(epsilon, T_coolant, ntu_units), or a new HeatExchanger
component sitting between two Junctions. The closure
approach is simpler — one new kind in the heat family +
parameter packing. Distributed along the pipe length.
Effort. ~1 week.
Done when. A Cruise M case with an intercooler.Topology
imports with the imported pipe carrying an ε-NTU heat
extraction closure; charge temperature drop matches the
project's calibration to ~1 % at a reference operating point.
Cross-ref. Milestone 7, Phase 7d "EGR cooler" piece.
Phase 8e — Urea injector + urea-water spray decomposition¶
Goal. New BC kind: urea_spray_inlet injecting an
NH₃ + HNCO mixture at a specified spray rate. Plus a
hydrolysis decomposition reaction
HNCO + H₂O → NH₃ + CO₂ that fires on the pipe just
downstream of the injector. The combined BC + reaction lets
the SCR catalyst downstream see the right NH₃ feed
concentration as a function of urea-dosing rate.
Approach. Schema: new BCSpec.kind = "urea_spray_inlet"
+ extra fields (urea_mass_flow_t / urea_mass_flow_v,
droplet_size, evaporation_model). Reaction: new kind
urea_decomposition on SpeciesSpec.reaction. Both wire
through the existing schema-vs-registry consistency tests.
Effort. ~1-2 weeks. The droplet evaporation model is the chunky part — droplet diameter, residence time, ambient T effect on evaporation rate.
Done when. A Cruise M case with a urea-spray
AftertreatmentInjectorTopology imports with the injection
BC + decomposition reaction wired correctly; the imported
SCR sees an NH₃-feed schedule shaped like the dosing
schedule × hydrolysis efficiency.
Cross-ref. Milestone 7, Phase 7b "urea-water spray BC + decomposition".
Phase 8f — DPF (Diesel Particulate Filter)¶
Goal. New aftertreatment closure modelling soot loading, soot-loading-dependent pressure drop, passive O₂ regeneration (via NO₂), and active T-driven thermal regeneration (above ~600 °C).
Approach. New Pipe.dpf_state per-cell soot-mass array
(kg/m³). New reaction kind dpf_soot_burn that consumes
soot when local T crosses a threshold or NO₂ is present.
Pressure drop via the Phase-A25 darcy_forchheimer_kc
closure with K(soot_loading) — i.e. permeability shrinks as
soot accumulates. Soot tracked as either a new species
column (passive convection through the network) or as a
per-cell scalar accumulator (the cleaner choice — soot
doesn't really advect like a gas species).
Effort. ~2-3 weeks. Most of the work is the soot-loading calibration + regeneration kinetics. The pressure-drop coupling rides on Phase A25.
Risk. High — DPF physics is genuinely complex and the calibration is fixture-specific. Plan to ship a Tier-1 model matching MIT lit defaults; tuning per project is manual.
Done when. A Cruise M case with a DPFTopology imports
with the soot-loaded pipe + regeneration reaction; a
hot-exhaust transient triggers active regeneration with
visible soot-mass decay.
Cross-ref. Milestone 7, Phase 7b "DPF with soot loading + passive / active regeneration".
Phase 8g — VGT + wastegate + twin-/sequential-turbo topology¶
Goal. Variable-geometry turbine (vane position as 3rd map axis); wastegate (parallel-pipe bypass with controlled-area orifice); twin / sequential turbo topology.
Approach. VGT: extend TurboMapSpec with a
vane_position axis on the lookup. Wastegate: parallel pipe
with a valve_orifice BC on the bypass — already supported
by the existing aeolus1d components, just needs the importer
to recognise the topology.
Effort. ~1 week (VGT) + ~1 week (wastegate); twin / sequential turbo is wiring (no new physics).
Done when. A Cruise M case with a VGT-equipped engine imports with the turbine map carrying a 3rd vane-position axis; wastegate-bypass cases route the right fraction of exhaust around the turbine.
Cross-ref. Milestone 7, Phase 7c "Turbocharger depth".
Phase 8h — Combined SCRF + two-stage SCR¶
Goal. A single brick that's both an SCR (urea + NH₃ → N₂) and a DPF (soot loading + regen). Two-stage SCR is just two SCR pipes in series — covered by Phase 8b once DOC / SCR topology recognition lands.
Approach. Combined SCRF composes Phase 8e (urea decomposition + NH₃ SCR) and Phase 8f (DPF). Most of the work is fixture validation; the closures already compose when both are attached to the same pipe.
Effort. ~1 week (mostly tests + cross-validation).
Done when. A Cruise M case with an SCRFTopology
imports with both SCR reactions and DPF soot loading on the
same pipe.
Cross-ref. Milestone 7, Phase 7b "combined SCRF" + "two- stage SCR".
Phase 8i — Particulate matter species column¶
Goal. First-class species tracking for soot mass — a non-advecting accumulator per cell that the DPF (Phase 8f) reads/writes and that tracer/writer can serialise.
Approach. New Pipe.soot_mass per-cell array,
analogous to T_solid for catalysts. Snapshot helper
extension so the writer + tracer pick it up automatically.
Cruise M's ParticulateMatterSpecie declarations map to
this column.
Effort. ~1 week. Mostly persistence + GUI plot integration; the soot accumulator math itself comes with Phase 8f.
Done when. A run with a DPF brick records the per-cell soot mass over time in the HDF5; the GUI plot dock has a soot-loading visualisation; resume-from-HDF5 restores the soot state.
Cross-ref. Milestone 7, Phase 7b context.
Out-of-scope items — go through FMI¶
Phase 8z — FMI export surface for vehicle / powertrain integration¶
Goal. Aeolus exports an FMU. Vehicle dynamics, transmission, hybrid drive, cooling system, and ECU controller logic stay out of aeolus1d's native scope; coupled-simulation tools wrap the FMU + their own vehicle / control models.
Approach. Phase 7e in the original roadmap. The Phase
A14a _cmd_run decomposition + Phase A17 live-control
checkpoint + Phase A19 CI infrastructure all support a
clean FMI 2.0 export. Most of the work is the FMU envelope:
modelDescription.xml, the C wrapper around the Python
solver, signal mapping for inlet ṁ / T / Y(t) and outlet
T / p / Y(t).
Effort. ~2-3 weeks for FMI 2.0 co-simulation export. FMI 3.0 (with array signals) is a follow-up.
Done when. An aeolus1d aftertreatment case can be imported into AVL Cruise M as an FMU sub-system and stepped from Cruise M's vehicle solver, with NH₃ / urea / NOx round- tripping correctly across the FMU boundary.
Cross-ref. Milestone 7, Phase 7e "Co-simulation interfaces".
Summary¶
| Phase | Effort | Cumulative | Cruise M coverage delta |
|---|---|---|---|
| 8a — engine breathing recognition | 3-4 d | 4 d | Cylinder, valve, compressor, turbine, shaft, manifold |
| 8b — DOC/SCR topology recognition | 1 d | 5 d | DOC, SCR catalyst kinds |
| 8c — multi-injector cylinders | 3-4 d | 9 d | split / dual-fuel injection |
| 8d — heat-exchanger ε-NTU | 1 w | 16 d | intercooler, EGR cooler |
| 8e — urea injector + decomposition | 1-2 w | 26 d | urea dosing, hydrolysis |
| 8f — DPF | 2-3 w | 47 d | soot loading + regen |
| 8g — VGT + wastegate | 2 w | 61 d | modern diesel turbo control |
| 8h — combined SCRF + two-stage SCR | 1 w | 68 d | combined aftertreatment |
| 8i — PM species column | 1 w | 75 d | soot persistence |
| 8z — FMI export | 2-3 w | 96 d | vehicle integration via co-sim |
~14-19 weeks for the whole milestone if executed strictly sequentially. Phases 8a / 8b / 8c can run in parallel with 8d-8i; 8z is the natural last step (consumes the rest as a Tier-1 FMU).
Cross-reference¶
- The architecture-refactor plan (
architecture-refactor-plan.md) ships the foundations Milestone 8 builds on: closure registry (Phase 1) for the new reaction / heat-exchanger / porous kinds, snapshot value type (Phase 2) for the soot state persistence, Component protocol (Phase 5) for any new network components. - Milestone 7 (in
phase-log.md) covers the same physics from a feature-driven angle. Phases marked "Cross-ref" above show the mapping.