OpenSWMM Engine  6.0.0-alpha.4
Data-oriented, plugin-extensible SWMM Engine (6.0.0-alpha.4)
Loading...
Searching...
No Matches
LagrangianSolver.hpp File Reference

LARD (Lagrangian ARD) quality engine — X2: LTD transport core. More...

Include dependency graph for LagrangianSolver.hpp:

Go to the source code of this file.

Classes

struct  openswmm::lard::SpeciesRowLayout
 The segment store's species-row layout, computed in ONE place. More...
 
class  openswmm::lard::LagrangianSolver
 

Namespaces

namespace  openswmm
 
namespace  openswmm::lard
 

Functions

SpeciesRowLayout openswmm::lard::rowLayout (const SimulationContext &ctx)
 

Variables

constexpr double openswmm::lard::kTinyFlow = 1.0e-8
 cfs; below this a link moves nothing
 

Detailed Description

LARD (Lagrangian ARD) quality engine — X2: LTD transport core.

Subplan X2 (plans/transport/LARD_AGE_EXPEDITE_SUBPLAN_2026-08-23.md; strategy plans/LAGRANGIAN_QUALITY_STRATEGY.md §2/§4, §16 amendments D-L1/D-L2/D-L5 binding). X3a: [OPTIONS] QUALITY_STEP splits each routing step into equal transport substeps (strategy §4.2) — flows are frozen within the routing step, so refining dtq refines transport ALONE, which is what the dt-reference instrument leans on; MAX_SEGMENTS_PER_LINK sizes the slabs. Both keys warn when set under other engines.

Step orchestration (§4.2, trimmed to X2 scope):

  1. flow-reversal detection → ring reversal + topo invalidation
  2. DRAIN — every conduit sends |Q|·dt of back-end segment water (and its mass) to its downstream node's inflow ledger; a link whose new volume is below the remainder sheds the difference through its FRONT to the upstream ledger, so segment volume always sums exactly to links.volume and the volume change is booked, never rescaled away (the E2 unbooked-resync family).
  3. MIX — nodes in flow-aware topological order (Kahn; cycles broken in index order, their residue carried in the ledger to the next step rather than dropped): CSTR over the node's own old volume — junctions, dividers, storages (CMSTR) and outfalls all reduce to the same formula. External loads join here from the SHARED loader seam (qual_mass_in rate × dt, qual_vol_in volume — assembled by QualitySolver::assembleExternalLoads, the ARD precedent). Zero-volume links (pump/orifice/weir/outlet) pass the node's NEW concentration through in the same step — the reason the order is topological (§4.3, Davis et al.).
  4. RELEASE — each conduit gains a front segment at its upstream node's new concentration, sized so the slab total equals links.volume exactly; §4.5 merge tolerance collapses plug flow.
  5. DECAY — exact-exponential kdecay on segments and node stores (species-major stripes), booked to qual_routing_reacted.
  6. PUBLISH — links.conc = volume-weighted segment mean (so engine-side final-storage and outfall bookings are exact), then conc_old = conc (the ARD convention).

X4: water age rides the segments as species row np — exact aging (+dt on every live parcel and node store BEFORE transport, the routeLegacyAge convention), volume-weighted mixing through the same drain/mix/release phases, sources from node_age_vol_in (the D-UT10 parallel accumulator, all seven loader pathways), state published to water_age_state (seconds), no decay on the age row, and the dry-link state keeps aging (the A2b state/report separation).

X3b: [OPTIONS] DISPERSION RWPT activates resolved vertical-shear dispersion on the segments (RwptDispersion.hpp, D-X3b1: particles estimate inter-segment exchange, carry no mass themselves), keyed by the deterministic RWPT_SEED (D-L6). Runs on the substep's final field, conduits only.

Deliberately NOT here: reactions module binding (deferred L3), heat (H7 — does not advance under this dispatch and the open() warning says so), treatment interop (warned bypass), storage mixing models beyond CMSTR, the legacy evaporation up-concentration factor (recorded deviation — steady gates cannot see it; parity work owns it), D-NS1's clamp counter/warning (the max(0,·) floor is here, but its observer — a negative source reaching a node — only exists once X6 lands negative loads in the shared loaders).

Header-only for the same reason X1 was: the engine source glob lacks CONFIGURE_DEPENDS, and a patch-applied .cpp silently does not compile.

Author
Caleb Buahin caleb.nosp@m..bua.nosp@m.hin@g.nosp@m.mail.nosp@m..com
License\n Apache-2.0