![]() |
OpenSWMM Engine
6.0.0-alpha.4
Data-oriented, plugin-extensible SWMM Engine (6.0.0-alpha.4)
|
Namespaces | |
| namespace | fvkernels |
| namespace | heat |
Classes | |
| class | ArdEngine |
| struct | Cell |
| struct | ClassEnables |
Allocation-free class enables for one domain — what the engines size from. n_msx is the reactions component's species count when MSX is on for the domain; msx_has_wall tells ARD / 2D that the component declares WALL species (their own fallback / warning). More... | |
| struct | Donors |
| struct | Draft |
| Build the full matrix (states + reasons). Pure: never writes warnings. More... | |
| struct | Matrix |
| class | ReactionIntegrator |
| struct | RowLayout |
| struct | RxEvalEnv |
| Evaluation environment: pre-gathered pointers, no lookups. More... | |
| struct | RxExprSpan |
| Compiled expression = span into the shared pool. len 0 ⇒ no expression. More... | |
| struct | RxRateContext |
| struct | RxStepReport |
| struct | RxSymbols |
| struct | RxToken |
| class | RxWorkspace |
| class | Tokenizer |
| Stateless multi-delimiter tokenizer for SWMM input lines. More... | |
Enumerations | |
| enum class | Domain : int { RUNOFF = 0 , GROUNDWATER = 1 , NETWORK_1D = 2 , SURFACE_2D = 3 , COUNT = 4 } |
| Rows of the matrix. Values are the C API's SWMM_TRANSPORT_DOMAIN_* codes. More... | |
| enum class | SpeciesClass : int { POLLUTANTS = 0 , MSX = 1 , AGE = 2 , TEMPERATURE = 3 , COUNT = 4 } |
| Columns of the matrix. Values are the C API's SWMM_TRANSPORT_CLASS_* codes. More... | |
| enum class | CellState : int { ENABLED = 0 , DISABLED_BY_USER = 1 , UNAVAILABLE = 2 } |
| One cell's state. Values are the C API's SWMM_TRANSPORT_* state codes. More... | |
| enum class | RxHydVar |
Functions | |
| void | warnIfFvDispersionKeyIgnored (SimulationContext &ctx) |
| Warn when FV_DISPERSION is set while EULERIAN_ARD reads its own component coefficients. | |
| bool | ardBoundariesNeedExternalVolumes (const SimulationContext &ctx) |
| Test whether resolved ARD boundary rows need shared external carrier assembly. | |
| void | resolveArdTransportRows (SimulationContext &ctx, std::vector< std::string > &errors) |
| Resolve deferred MSX boundary/source rows to native element/species/time-series arrays. | |
| void | registerArdComponent () |
| Register built-in ARD parser/serializer callbacks in process singleton. | |
| bool | heatAttrValueOk (HeatAttr attr, double value) noexcept |
| Validate a public numeric heat attribute value with parser-equivalent range policy. | |
| void | registerHeatComponent () |
| Register built-in heat configuration parser and serializer callbacks. | |
| void | routeLegacyHeat (SimulationContext &ctx, double dt) |
| Apply heat flux then legacy complete-mix transport of node/link temperatures. | |
| double | lidLayerHeatCapacity (const SimulationContext &ctx, const lid::LIDGroupSoA &g, std::size_t unit, int layer) noexcept |
| Compute current areal thermal capacity of a conventional-LID layer. | |
| void | initLidLayerTemperature (SimulationContext &ctx, const lid::LIDSolver &solver) |
| Size shared layer scalar state and seed all conventional-LID temperatures. | |
| void | setLidInflowTemperature (SimulationContext &ctx, int type_index, int unit, int subcatch, double rain_rate, double q_imperv, double q_perv, double q_runon, double lid_area) |
| Set one LID unit's incoming degC from rainfall and captured/run-on surface water. | |
| void | routeLidLayerTemperature (SimulationContext &ctx, const lid::LIDSolver &solver, double dt) |
| Mix accepted layer inflows then solve optional LID heat conduction/atmospheric exchange. | |
| void | addRunonTemperature (SimulationContext &ctx, int donor_sc, int receiver_sc, double q) |
| Add donor runoff temperature times routed flow to receiver thermal run-on assembly. | |
| void | addRunonTemperatureAt (SimulationContext &ctx, int receiver_sc, double q, double temp_c) |
| Add a known-temperature positive run-on carrier to one receiver's thermal numerator. | |
| void | routeSubcatchmentTemperature (SimulationContext &ctx, const runoff::RunoffSoA &soa, double dt) |
| Mix snow-adjusted precipitation/run-on and atmospheric heat into subarea thermal stores. | |
| Donors | donorsFor (lid::LIDType t, bool has_soil) |
| Resolve immediate inflow donors/physical vertical adjacency for each LID layer. | |
| void | layerVolumes (const lid::LIDGroupSoA &g, std::size_t ui, double(&v)[kNL]) |
Void-weighted water held in each layer, as a depth per unit area (ft). The four terms are exactly those LIDSolver::storedVolume() sums, so a layer's age is weighted by the same water the mass balance counts. | |
| std::vector< int > | buildOffsets (const lid::LIDSolver &solver) |
| Build flattened conventional-LID group/unit prefix offsets. | |
| void | armMsxRoutingLedger (SimulationContext &ctx) |
| Initialize native network species continuity ledger when absent or row shape changes. | |
| void | routeLegacyMsx (SimulationContext &ctx, double dt) |
| Transport native BULK species through legacy node/link complete-mix routing and LID ports. | |
| void | drainMsxCouplingQueue (SimulationContext &ctx, double dt) |
| Convert accepted queued coupling inventory into native external mass rate for this substep. | |
| void | bookMsxSystemOutflow (SimulationContext &ctx, int node, double q, bool flooding, double dt) |
| Add native BULK species inventory carried by accepted system discharge to continuity ledger. | |
| bool | ardReactionsActive (const SimulationContext &ctx) |
| Test configured/compiled native reaction flags for ARD binding. | |
| bool | ardHasWallSpecies (const SimulationContext &ctx) |
| Test whether any configured reaction species is marked WALL. | |
| void | reactArdStage (SimulationContext &ctx, double dt, double *cell_phi, const double *cell_a, const double *cell_dx, int n_cells, double *node_mass, const double *node_vol, int n_nodes, int n_pollut, int ns_total, double min_store_vol, int temp_row, const int *cell_conduit, const int *conduit_link) |
| Decay pollutant rows and integrate native reaction rows in ARD cell/node stores. | |
| std::string | compileReactionExpression (const std::string &src, const RxSymbols &symbols, std::vector< RxToken > &pool, RxExprSpan &out, int &error_col) |
| Compile an infix scalar reaction expression into appended stack-machine tokens. | |
| double | evalReactionExpression (const std::vector< RxToken > &pool, const RxExprSpan &span, const RxEvalEnv &env) noexcept |
| Evaluate a validated compiled reaction span with stack-local scratch. | |
| int | reactionFunctionCount () |
| Read number of supported compiled scalar function entries. | |
| bool | reactionFunctionInfo (int idx, const char **name, int *arity) |
| Read name and argument count of one supported expression function. | |
| int | reactionHydVarCount () |
| Read number of declared hydraulic/thermal/groundwater expression variables. | |
| bool | reactionHydVarInfo (int idx, const char **name, const char **description) |
| Read canonical variable name and description including its declared units/support. | |
| std::string | reactionContextDiagnostic (const ReactionData &rx, const std::vector< RxToken > &pool, const RxExprSpan &span, int context) |
| Recursively reject hydraulic/species/pollutant references unavailable in one reactor context. | |
| bool | reactionHydVarPopulated (int idx) |
| Test the network-quality variable range currently populated by native routing. | |
| std::string | unpopulatedHydVarDiagnostic (const std::string &src, const std::vector< RxToken > &pool, const RxExprSpan &span, int &error_col) |
| Report first compiled hydraulic variable not in the network-populated range. | |
| double | reactionAreaFactor (ReactionAreaUnits units) |
| Convert native square feet to configured reaction wall/dry-store area units. | |
| double | reactionWallArea (const SimulationContext &c, bool link_element, int e, bool reference=false) |
| Resolve explicit or hydraulic wetted reaction wall area for an element. | |
| double | reactionAreaVolume (const SimulationContext &c, bool link_element, int e, double volume) |
| Compute active wetted reaction wall area per litre of water. | |
| void | reactionWallScales (const SimulationContext &c, bool link_element, int e, double volume, std::vector< double > &scales) |
| Build per-species active-to-reference wall coverage multipliers. | |
| void | ensureMsxState (SimulationContext &ctx) |
| Lazily size + seed the MSX element state; warn once about the R4b transport limitation when any RATE MSX species exists in either scope (LEGACY only — under LARD the species ride the segments as of L3). | |
| void | noteNegativeClamp (SimulationContext &ctx, const char *where) |
| Review A2: one warning per run when the reaction step had to clamp a negative concentration. The LEGACY binding also books the mass the clamp added (msx_ledger.clamped); the other engines report it here only. | |
| double | clampRateSpecies (const ReactionData &rx, bool tank, double *block, double *added) |
| Floor negative RATE species only and optionally report each concentration addition. | |
| void | reactSpeciesBlock (SimulationContext &ctx, bool tank, double dt, double *species_block, const double *pollut, double hrt_seconds, double temp_c, int element) |
| React one LARD-owned tuple with held HRT/temperature and optional element geometry. | |
| bool | legacyReactionsActive (const SimulationContext &ctx) |
| Test configured and compiled native reaction readiness. | |
| void | reactLegacyNodes (SimulationContext &ctx, double dt) |
| Run legacy-bound exact pollutant decay and native node kinetics once. | |
| void | reactLegacyLinks (SimulationContext &ctx, double dt) |
| Run legacy-bound exact pollutant decay and native link kinetics once. | |
| void | warnIfLegacyBindingBypassed (SimulationContext &ctx) |
| Warn when configured compiled reactions are bypassed by IGNORE_QUALITY. | |
| const std::vector< std::string > & | reactionSectionTags () |
| Borrow the complete fixed set of supported embedded/external reaction section names. | |
| void | applyReactionSections (SimulationContext &ctx, const components::ComponentConfigSections &config, std::vector< std::string > &errors) |
| Parse, validate, compile and register one native multispecies reaction system. | |
| void | applyEmbeddedReactionSections (SimulationContext &ctx, bool external_component_registered, std::vector< std::string > &errors) |
| Apply retained INP reaction sections unless an external component has precedence. | |
| void | registerReactionsComponent () |
| Register native reaction parser/serializer callbacks under the built-in component ID. | |
| bool | recompileReactionSystem (SimulationContext &ctx, std::vector< std::string > &errors) |
| Rebuild all compiled reaction expressions and validate scoped availability/profile constraints. | |
| double | reactionSourceFactor (const ReactionData &r, const ReactionData::Source &source, double seconds) |
| Read a periodic reaction-source pattern factor at an elapsed simulation time. | |
| double | reactionBoosterMass (SimulationContext &ctx, int node, int species, double mass, double mixed_volume, double arriving_volume) |
| Compute and book the first matching node/species booster inventory addition. | |
| std::string | serializeReactionSystem (const SimulationContext &ctx) |
| Serialize configured native reaction metadata and scoped laws to INP section text. | |
| std::string | serializeWaterAgeConfig (const SimulationContext &ctx) |
| Serialize configured constant water-age source rows to canonical component text. | |
| void | registerWaterAgeComponent () |
| Register the built-in water-age configuration parser and serializer callbacks. | |
| void | routeLegacyAge (SimulationContext &ctx, double dt) |
| Advance age seconds through legacy node/conduit mixing without altering pollutants. | |
| void | initLidLayerAge (SimulationContext &ctx, const lid::LIDSolver &solver) |
| Size shared conventional-LID scalar storage and seed retained-water layer ages. | |
| void | setLidInflowAge (SimulationContext &ctx, int type_index, int unit, int subcatch, double rain_rate, double q_imperv, double q_perv, double q_runon, double lid_area) |
| Set one unit's scalar inflow age from rainfall and captured/run-on surface water. | |
| void | routeLidLayerAge (SimulationContext &ctx, const lid::LIDSolver &solver, double dt) |
| Advance and mix conventional-LID layer ages after accepted layer hydraulics. | |
| void | addRunonAge (SimulationContext &ctx, int donor_sc, int receiver_sc, double q) |
| Add donor subcatchment runoff-age rate to receiver run-on numerator. | |
| void | routeSubcatchmentAge (SimulationContext &ctx, const runoff::RunoffSoA &soa, double dt) |
| Age/mix subarea water stores with snow-adjusted precipitation and assembled run-on. | |
| double | arrivingPrecipRate (const SimulationContext &ctx, std::size_t ui, int subarea) noexcept |
| Read arriving liquid precipitation after optional snowpack storage/melt. | |
| double | arrivingMeltFraction (const SimulationContext &ctx, std::size_t ui, int subarea) noexcept |
| Read the melt fraction of arriving liquid precipitation. | |
| double | arrivingPrecipTemperature (const SimulationContext &ctx, std::size_t ui, int subarea) noexcept |
| Mix rain and zero-degree meltwater temperatures by arriving melt fraction. | |
| double | arrivingPrecipAge (const SimulationContext &ctx, std::size_t ui, int subarea) noexcept |
| Mix configured rain age with retained meltwater age by arriving melt fraction. | |
| double | initialAgeSecondsFor (const SimulationContext &ctx, bool is_link, int idx, double fallback) |
Per-element initial age (SECONDS) for one node/link, falling back to fallback (normally the INITIAL_STATE global) when no [INITIAL_QUALITY] row targets the element. Later rows win. | |
| double | initialTempFor (const SimulationContext &ctx, bool is_link, int idx, double fallback) |
Per-element initial temperature (degC) for one node/link, falling back to fallback (normally the INITIAL_STATE global). | |
| void | applyInitialAgeOverrides (SimulationContext &ctx) |
| Apply WATER_AGE rows onto water_age_state.node_age/link_age (hours -> seconds). No-op when a hotstart state is loaded (D-IQ7) or the arrays are unsized. | |
| void | applyInitialTempOverrides (SimulationContext &ctx) |
| Apply TEMPERATURE rows onto heat_state.node_temp/link_temp (degC). No-op on unsized arrays. | |
| bool | initialQualityHasMsxRow (const SimulationContext &ctx, bool is_link, int elem_idx, int species) |
| Test whether a resolved initial-quality table already owns an element/reaction species seed. | |
| std::vector< std::string > | mirrorInitialQualityMsxRows (SimulationContext &ctx) |
| Mirror resolved MSX initial seeds into the native reaction component's element seed table. | |
| ClassEnables | network1DEnables (const SimulationContext &ctx) noexcept |
| Resolve allocation-free native network class counts from current project policy. | |
| ClassEnables | surface2DEnables (const SimulationContext &ctx) noexcept |
| Resolve allocation-free surface native class eligibility from project and 2D opt-outs. | |
| ClassEnables | groundwaterEnables (const SimulationContext &ctx) noexcept |
| Resolve allocation-free canonical aquifer class eligibility for an active integrated kernel. | |
| RowLayout | canonicalRows (const SimulationContext &ctx, const ClassEnables &e) |
| Build an owned canonical pollutant/MSX/age/temperature row layout for supplied enables. | |
| Matrix | resolve (const SimulationContext &ctx, const Draft *draft) |
| Build a domain-by-species transport capability matrix with explicit reasons and counts. | |
| const char * | domainName (Domain d) noexcept |
| Format a transport matrix domain as a human-readable label. | |
| const char * | speciesClassName (SpeciesClass c) noexcept |
| Format a transport species class as a human-readable label. | |
| const char * | cellStateName (CellState s) noexcept |
| Format a transport capability state as its canonical uppercase label. | |
| std::string | formatReportBlock (const Matrix &m) |
| Format a capability matrix as a readable fixed-column report and unavailable explanations. | |
Variables | |
| constexpr int | kNL = LidLayerSpeciesState::kLayerCount |
| constexpr int | kExternal = -1 |
| -1 means "external to the unit"; -2 means "this type has no such layer". | |
| constexpr int | kAbsent = -2 |
| constexpr int | kSurf = static_cast<int>(LidLayer::SURFACE) |
| constexpr int | kPave = static_cast<int>(LidLayer::PAVEMENT) |
| constexpr int | kSoil = static_cast<int>(LidLayer::SOIL) |
| constexpr int | kStor = static_cast<int>(LidLayer::STORAGE) |
| constexpr int | kSubIMPERV0 = 0 |
| constexpr int | kSubIMPERV1 = 1 |
| constexpr int | kSubPERV = 2 |
| constexpr double | kMeltwaterTempC = 0.0 |
| constexpr double | ZERO_DEPTH |
| constexpr double | LEGACY_ZERO |
| constexpr double | ZERO_DEPTH |
| constexpr double | LEGACY_ZERO |
| constexpr int | kRxMaxStackDepth |
| constexpr double | ZERO_DEPTH |
| constexpr double | LEGACY_ZERO |
|
strong |
|
strong |
|
strong |
Hydraulic variables available in reaction expressions (reactions plan §2; engines populate the evaluation environment at R6). Order is the ABI of the evaluator's hydvar array.
|
strong |
| void openswmm::transport::addRunonAge | ( | SimulationContext & | ctx, |
| int | donor_sc, | ||
| int | receiver_sc, | ||
| double | q ) |
Add donor subcatchment runoff-age rate to receiver run-on numerator.
| [in,out] | ctx | Enabled water-age state with prepared donor and receiver arrays. |
| [in] | donor_sc | Valid nonnegative donor subcatchment ID; uncovered returns. |
| [in] | receiver_sc | Valid nonnegative receiver ID; uncovered returns. |
| [in] | q | Routed run-on ft3/s, not interval volume; finite sign is not checked. |
Accumulate run-on age-volume from a donor subcatchment to its receiver. Called from the run-on assembly beside the flow it mirrors.
| void openswmm::transport::addRunonTemperature | ( | SimulationContext & | ctx, |
| int | donor_sc, | ||
| int | receiver_sc, | ||
| double | q ) |
Add donor runoff temperature times routed flow to receiver thermal run-on assembly.
Accumulate run-on temperature from donor_sc onto receiver_sc.
| [in,out] | ctx | Enabled thermal state with covered donor runoff and receiver numerator/rate arrays. |
| [in] | donor_sc | Valid nonnegative donor subcatchment identity; uncovered returns. |
| [in] | receiver_sc | Valid nonnegative receiver identity; uncovered returns. |
| [in] | q | Routed run-on ft3/s; addRunonTemperatureAt accepts only positive values. |
The RATE convention every loader uses: donors add q · T, the consumer divides by the total rate. Mirrors addRunonAge, and must be called at every contributor to runon_inflow — the subcatchment cascade, the LID underdrain return, and the outfall return. A3 filled this numerator from one of the three and divided by all three, which produced arriving water younger than anything entering the model. The temperature analogue of that defect is quieter and worse: a missing contributor pulls the arriving temperature toward 0 °C, which is a plausible number.
| void openswmm::transport::addRunonTemperatureAt | ( | SimulationContext & | ctx, |
| int | receiver_sc, | ||
| double | q, | ||
| double | temp_c ) |
Add a known-temperature positive run-on carrier to one receiver's thermal numerator.
Accumulate run-on at an explicitly supplied temperature.
| [in,out] | ctx | Enabled thermal state; writes matching receiver rate and temperature-rate arrays. |
| [in] | receiver_sc | Valid nonnegative subcatchment ID; uncovered returns. |
| [in] | q | Positive finite ft3/s; nonpositive/NaN returns. |
| [in] | temp_c | Flow temperature degC, copied without finite/range validation. |
For contributors whose donor is not another subcatchment: the outfall return (which carries heat_state.node_temp) and, from H5b, the LID underdrain. Adds to the numerator and the rate together — the pairing is why this is one function and not two array writes at each call site.
| void openswmm::transport::applyEmbeddedReactionSections | ( | SimulationContext & | ctx, |
| bool | external_component_registered, | ||
| std::vector< std::string > & | errors ) |
Apply retained INP reaction sections unless an external component has precedence.
| [in,out] | ctx | Embedded component rows and final reaction/name state, warnings/config updated. |
| [in] | external_component_registered | True warns/ignores embedded sections; external owner wins. |
| [in,out] | errors | Passed to applyReactionSections, append-only except underlying reaction metadata reset. |
Embedded fallback (called from SWMMEngine::open after component resolution): if [REACTION_*] sections were found in the legacy .inp, apply them with a style warning — unless an external reactions component was registered, in which case the external file wins wholesale and the embedded sections are reported ignored.
|
inline |
Apply WATER_AGE rows onto water_age_state.node_age/link_age (hours -> seconds). No-op when a hotstart state is loaded (D-IQ7) or the arrays are unsized.
| [in,out] | ctx | Stable resolved initial-quality rows and already-sized native node/link age arrays in s. Matching in-range age targets receive authored hours*3600 in row order, last wins. |
|
inline |
Apply TEMPERATURE rows onto heat_state.node_temp/link_temp (degC). No-op on unsized arrays.
| [in,out] | ctx | Stable resolved initial-quality rows and already-sized native node/link degC arrays, overwritten at matching valid targets in row order (last wins). |
| void openswmm::transport::applyReactionSections | ( | SimulationContext & | ctx, |
| const components::ComponentConfigSections & | config, | ||
| std::vector< std::string > & | errors ) |
Parse, validate, compile and register one native multispecies reaction system.
| [in,out] | ctx | Final native node/link/subcatch/landuse/LID names and pollutant registry; replaces reaction metadata, installs compiled tokens/spans and successful native registry species. |
| [in] | config | Supported REACTION_* sections and source path used in diagnostics; read synchronously. |
| [in,out] | errors | Appends parse/profile/compile diagnostics; any nonempty vector at final parse check (including preexisting caller errors) clears reaction metadata and prevents registration. |
Parse + validate a set of reaction sections into ctx.reactions and the species registry. Shared by the component apply hook (external file) and the embedded fallback. Diagnostics are appended to errors (fatal).
| bool openswmm::transport::ardBoundariesNeedExternalVolumes | ( | const SimulationContext & | ctx | ) |
Test whether resolved ARD boundary rows need shared external carrier assembly.
| [in] | ctx | Stable selected quality solver, ignore flag and resolved boundary-node array. |
True when the external-load loaders must run even though the model has no pollutants: a [TRANSPORT_BOUNDARIES] row injects qual_vol_in * concentration, and qual_vol_in is accumulated by those loaders. Without this an MSX-ONLY model — the nh2cl shape, and the one E5a exists to enable — assembles no inflow volume and its boundary delivers exactly nothing.
| bool openswmm::transport::ardHasWallSpecies | ( | const SimulationContext & | ctx | ) |
Test whether any configured reaction species is marked WALL.
| [in] | ctx | Stable species_is_wall vector. |
True when any declared MSX species is WALL — unsupported under the ARD engine (no transport semantics for attached species yet); the engine falls back to LEGACY, whose R4 binding runs them element-locally.
| bool openswmm::transport::ardReactionsActive | ( | const SimulationContext & | ctx | ) |
Test configured/compiled native reaction flags for ARD binding.
| [in] | ctx | Stable reaction metadata. |
True when the reactions component is active (configured + compiled) — the ARD engine's condition for carrying MSX species on the mesh.
| void openswmm::transport::armMsxRoutingLedger | ( | SimulationContext & | ctx | ) |
Initialize native network species continuity ledger when absent or row shape changes.
| [in,out] | ctx | Prepared old native water volumes, reaction initial state and native LID held inventories; ensures MSX concentration state then arms/resets matching ledger as needed. |
Advect the MSX element state one routing step on the LEGACY CSTR path. No-op unless a reaction system with at least one species is configured.
|
noexcept |
Read the melt fraction of arriving liquid precipitation.
Fraction of the arriving water that is MELTWATER, in [0, 1].
| [in] | ctx | Stable configured source scalars and prepared subcatchment snow/rain/melt receipt arrays. |
| [in] | ui | Zero-based subcatchment index; missing optional per-subcatch arrays use fallback. |
| [in] | subarea | kSubPERV selects pervious snow data; any other value selects impervious. |
Under a pack the arriving water is two different waters: meltwater, and rain that reached the ground through the snow-free fraction. arrivingPrecipRate returns their sum, and a sum cannot say what either is worth — this is the split.
Returns 0 wherever there is no pack, IGNORE_SNOWMELT is on, or nothing arrived, so a caller can blend unconditionally and a bare deck is bit-identical to its pre-S2 behaviour.
|
noexcept |
Mix configured rain age with retained meltwater age by arriving melt fraction.
Water age of the water arriving at one subarea [seconds] (S2b).
| [in] | ctx | Stable configured source scalars and prepared subcatchment snow/rain/melt receipt arrays. |
| [in] | ui | Zero-based subcatchment index; missing optional per-subcatch arrays use fallback. |
| [in] | subarea | kSubPERV selects pervious snow data; any other value selects impervious. |
The age analogue of arrivingPrecipTemperature, and it uses the same arrivingMeltFraction — not an equivalent expression, the same call. Under a pack the arriving water is meltwater carrying the pack's residence time plus rain that reached the ground through the snow-free fraction carrying the configured WaterAgeSource::RAINFALL age:
a = (1 − f)·a_rain + f·a_pack
If the two tracks ever computed f separately they could drift, and the drift would be invisible: both answers stay inside their brackets, and only a deck comparing arriving age against arriving temperature could see it. One call is what makes that unrepresentable.
snow_melt_age_*, published beside snow_melt_* under theIGNORE_SNOWMELT is on, nothing arrived, or the pack published no melt — so a caller blends unconditionally and a bare deck is bit-identical to its pre-S2b behaviour.
|
noexcept |
Read arriving liquid precipitation after optional snowpack storage/melt.
Net precipitation actually reaching one subarea this step [ft/s].
| [in] | ctx | Stable configured source scalars and prepared subcatchment snow/rain/melt receipt arrays. |
| [in] | ui | Zero-based subcatchment index; missing optional per-subcatch arrays use fallback. |
| [in] | subarea | kSubPERV selects pervious snow data; any other value selects impervious. |
This is the mixing volume, and it is not always the rainfall.
ctx.subcatches.rainfall is set once, at Runoff.cpp:294-295, to rain + SNOWFALL, and never updated. On a subcatchment with a snowpack the runoff solver does not use it: it uses snow_net_imperv for IMPERV0/IMPERV1 and snow_net_perv for PERV (Runoff.cpp:548-552), each built as imelt + rainfall·(1 − asc) — melt, plus the rain falling on the snow-free fraction (SWMMEngine.cpp:1608-1616).
Reading the rainfall field on such a deck is wrong twice over:
The second of those is A3's own net-gain failure (lessons 64, 68) reappearing through a different field: the mixing volume is again not the arriving volume. They do not cancel — they are displaced by the whole residence time of the pack, which is precisely the quantity a snow-aware age model exists to measure.
-1.0 sentinel is the whole guard snow_net_* initialise to -1.0SubcatchData.hpp:642), and the solver's own test is >= 0.0 (Runoff.cpp:551-552). A subcatchment with a pack but no melt this step publishes 0.0, which is a real rate; only the negative sentinel means "no pack, use the gage". This function mirrors that test exactly rather than inventing its own.Runoff.cpp:548's!ctx.options.ignore_snow_melt and legacy subcatch.c:784.kSubIMPERV0 / kSubIMPERV1 / kSubPERV.
|
noexcept |
Mix rain and zero-degree meltwater temperatures by arriving melt fraction.
Temperature of the water arriving at one subarea [°C] (S2).
| [in] | ctx | Stable configured source scalars and prepared subcatchment snow/rain/melt receipt arrays. |
| [in] | ui | Zero-based subcatchment index; missing optional per-subcatch arrays use fallback. |
| [in] | subarea | kSubPERV selects pervious snow data; any other value selects impervious. |
Meltwater is at 0 °C essentially by definition — that is what melting means — so the arriving temperature is the melt fraction blended against the configured HeatSource::RAINFALL value:
T = (1 − f)·T_rain + f·0
On a winter deck this is not a small approximation to make: it is the difference between a stream fed by snowmelt and one fed by rain. Unlike the age half, it needs no pack state at all — the freezing point is not something the pack has to remember.
| void openswmm::transport::bookMsxSystemOutflow | ( | SimulationContext & | ctx, |
| int | node, | ||
| double | q, | ||
| bool | flooding, | ||
| double | dt ) |
Add native BULK species inventory carried by accepted system discharge to continuity ledger.
| [in,out] | ctx | Armed native MSX ledger and stable node concentrations/species flags. |
| [in] | node | Native node ID; negative/uncovered returns. |
| [in] | q | Positive finite outflow ft3/s; nonpositive/NaN returns. |
| [in] | flooding | True books flooding row, false regular outflow. |
| [in] | dt | Matching accepted positive finite duration s, not independently checked. |
Review B14: book species leaving the system at node at flow q (ft³/s, > 0) for dt into the routing ledger's outflow or flooding row, at the node's published concentration. No-op until the LEGACY ledger is armed. Called from the same classification that books pollutants.
| std::vector< int > openswmm::transport::buildOffsets | ( | const lid::LIDSolver & | solver | ) |
Build flattened conventional-LID group/unit prefix offsets.
Flat index of each per-type group's first unit; back() == n_units.
| [in] | solver | Stable group counts/order; nonnegative counts and signed-int sum must fit. |
| RowLayout openswmm::transport::canonicalRows | ( | const SimulationContext & | ctx, |
| const ClassEnables & | e ) |
Build an owned canonical pollutant/MSX/age/temperature row layout for supplied enables.
| [in] | ctx | Stable pollutant and reaction names/flags covering supplied counts. |
| [in] | e | Nonnegative qualified class counts and optional age/temperature/BULK-only flags, consistent with available native name/flag arrays. |
|
noexcept |
Format a transport capability state as its canonical uppercase label.
| [in] | s | State enum, invalid values permitted for fallback. |
| double openswmm::transport::clampRateSpecies | ( | const ReactionData & | rx, |
| bool | tank, | ||
| double * | block, | ||
| double * | added ) |
Floor negative RATE species only and optionally report each concentration addition.
| [in] | rx | Stable n_species and selected pipe/tank form arrays. |
| [in] | tank | True selects tank forms, false pipe. |
| [in,out] | block | Writable n_species concentrations, finite expected; negative RATE becomes0, EQUIL/FORMULA/NONE remain unchanged even if negative. |
| [out] | added | Optional n_species tuple replaced with added concentration per row (not inventory). |
Review A2: set every negative RATE species in block (scope tank) to zero; writes the concentration added per species to added when it is non-null, returns the sum.
| std::string openswmm::transport::compileReactionExpression | ( | const std::string & | src, |
| const RxSymbols & | symbols, | ||
| std::vector< RxToken > & | pool, | ||
| RxExprSpan & | out, | ||
| int & | error_col ) |
Compile an infix scalar reaction expression into appended stack-machine tokens.
Compile src into the shared pool.
| [in] | src | Stable expression text; space/tab whitespace only. Supports unary signs, arithmetic, parentheses and fixed-arity functions; identifiers are case-sensitive except functions/hydraulic vars. |
| [in] | symbols | Borrowed optional species/coefficient/term/pollutant name vectors, alive through call. Resolution priority follows that order then hydraulic names; max_term excludes later term rows. |
| [in,out] | pool | Existing compiled token pool; appended only after complete syntax/stack validation. Products/span indices must fit int32_t; no rollback guarantee for unexpected allocation exception. |
| [out] | out | Initially {original pool end,0}; on success appended token span. May hold planned span if final insertion throws. No ownership of pool transferred. |
| [out] | error_col | 0 on success, otherwise1-based source column (some malformed/stack failures1). |
|
noexcept |
Format a transport matrix domain as a human-readable label.
| [in] | d | Domain enum; COUNT/invalid values are permitted for fallback. |
| Donors openswmm::transport::donorsFor | ( | lid::LIDType | t, |
| bool | has_soil ) |
Resolve immediate inflow donors/physical vertical adjacency for each LID layer.
| [in] | t | Conventional LID type; unknown value uses surface external and other layers absent. |
| [in] | has_soil | For permeable pavement, storage donor is soil when true, pavement otherwise. |
| void openswmm::transport::drainMsxCouplingQueue | ( | SimulationContext & | ctx, |
| double | dt ) |
Convert accepted queued coupling inventory into native external mass rate for this substep.
| [in,out] | ctx | Reaction queue [node*species+m], external native rate array and held coupling_delivery_remaining seconds; remaining duration is read, not decremented here. |
| [in] | dt | Positive finite accepted routing subinterval s; empty/no species/nonpositive/NaN returns. |
Review D1/F21: drain ReactionData::msx_coupling_queue (species mass handed to nodes by the 2D surface and the aquifer) into msx_ext_mass_in, by the coupling-volume queue's remaining-span rule. Call after msxsurf::deliver, before assembleLateralInflows.
| void openswmm::transport::ensureMsxState | ( | SimulationContext & | ctx | ) |
Lazily size + seed the MSX element state; warn once about the R4b transport limitation when any RATE MSX species exists in either scope (LEGACY only — under LARD the species ride the segments as of L3).
Seed native node/link species state when node-shaped storage differs from current model.
| [in,out] | ctx | Stable species/global/element initial rows and model counts; mismatch replaces node/link concentration vectors and applies covered element overrides after global seeds. |
L3: lazily size + seed the MSX element state (GLOBAL fill + [REACTION_QUALITY] overrides). Shared by the LEGACY dispatch and the LARD engine's init — one seeding spelling for both engines.
|
noexcept |
Evaluate a validated compiled reaction span with stack-local scratch.
Tier-1 evaluation: one pass, fixed-depth stack, allocation-free.
| [in] | pool | Stable compiled token storage, span fully covered and validated by compiler. |
| [in] | span | Nonnegative begin/len, valid opcode/stack shape and max depth<=kRxMaxStackDepth; len<=0 returns0 without pool/environment access. |
| [in] | env | Borrowed species/coefficient/term/hydraulic/pollutant tuples covering every referenced index; each pointer may be null only when that category is not referenced. Units follow expression. |
| std::string openswmm::transport::formatReportBlock | ( | const Matrix & | m | ) |
Format a capability matrix as a readable fixed-column report and unavailable explanations.
| [in] | m | Stable fully initialized4x4matrix; reason strings and counts already resolved. |
The .rpt block: a fixed-width table, one line per domain, one column per class, each cell "on(n)" / "off:KEY" / "n/a:reason". Ends with '
'.
|
noexcept |
Resolve allocation-free canonical aquifer class eligibility for an active integrated kernel.
| [in] | ctx | Stable twod_io aquifer state/options and complete native reaction/pollutant metadata. |
T7.1: two-zone groundwater enables — the 2D surface rule plus the [GW_TRANSPORT_OPTIONS] TRANSPORT_* keys. Like the surface, age and temperature are not gated by IGNORE_QUALITY. Every row is 0 unless a [2D_AQUIFER] actually resolved: the sections are authorable on a deck with no kernel, and they transport nothing there.
|
noexcept |
Validate a public numeric heat attribute value with parser-equivalent range policy.
| [in] | attr | Supported HeatAttr selector; unknown returnsfalse. |
| [in] | value | Finite scalar in stored SI/degC/dimensionless attribute units. |
The parser's per-attribute value rule (fractions in [0,1], strictly positive lengths and material properties, non-negative diffusivity and velocity), shared so the C API and the deck refuse the same values.
|
inline |
Per-element initial age (SECONDS) for one node/link, falling back to fallback (normally the INITIAL_STATE global) when no [INITIAL_QUALITY] row targets the element. Later rows win.
| [in] | ctx | Stable resolved initial_quality parallel arrays, each covering count(). |
| [in] | is_link | True for a link seed, false for node. |
| [in] | idx | Resolved zero-based element index to match; not dereferenced or bounds-checked here. |
| [in] | fallback | Already-internal default age s, retained when no matching row. |
| bool openswmm::transport::initialQualityHasMsxRow | ( | const SimulationContext & | ctx, |
| bool | is_link, | ||
| int | elem_idx, | ||
| int | species ) |
Test whether a resolved initial-quality table already owns an element/reaction species seed.
| [in] | ctx | Stable resolved initial-quality parallel arrays covering count(). |
| [in] | is_link | True selects links, false nodes. |
| [in] | elem_idx | Resolved zero-based element identity, compared without dereference. |
| [in] | species | Valid nonnegative native reaction species index encoded as MSX initial-quality kind. |
True when ctx.initial_quality carries an MSX row for (is_link, elem, species) — the ReactionsWriter's "already written elsewhere" test.
|
inline |
Per-element initial temperature (degC) for one node/link, falling back to fallback (normally the INITIAL_STATE global).
| [in] | ctx | Stable resolved initial_quality arrays covering count(). |
| [in] | is_link | True for link, false node. |
| [in] | idx | Zero-based resolved element index used only for equality. |
| [in] | fallback | Default Celsius temperature. |
| void openswmm::transport::initLidLayerAge | ( | SimulationContext & | ctx, |
| const lid::LIDSolver & | solver ) |
Size shared conventional-LID scalar storage and seed retained-water layer ages.
| [in,out] | ctx | WATER_AGE option/config and shared layer species state. Ensures unit/row shapes, writes previous layer water depth ft and initial age seconds for layers holding>1e-12ft. |
| [in] | solver | Final stable grouped LID geometry/order with covered layer arrays. |
Size the per-layer block against the model's LID units and seed the layers that already hold water at t = 0. Call after the LID manager has built its groups; repeating reseeds existing wet-layer ages.
| void openswmm::transport::initLidLayerTemperature | ( | SimulationContext & | ctx, |
| const lid::LIDSolver & | solver ) |
Size shared layer scalar state and seed all conventional-LID temperatures.
| [in,out] | ctx | Enabled thermal config/shared layer state; ensures shapes and writes initial degC plus previous water depths ft, including currently dry/absent layers. |
| [in] | solver | Final stable grouped unit order and parallel geometry arrays. |
Size the shared layer block if needed and seed the TEMPERATURE row from HeatSource::INITIAL_STATE. Independent of initLidLayerAge: either may run first, neither wipes the other (LidLayerSpeciesState::ensureSized).
| void openswmm::transport::layerVolumes | ( | const lid::LIDGroupSoA & | g, |
| std::size_t | ui, | ||
| double(&) | v[kNL] ) |
Void-weighted water held in each layer, as a depth per unit area (ft). The four terms are exactly those LIDSolver::storedVolume() sums, so a layer's age is weighted by the same water the mass balance counts.
Compute four void-weighted retained layer water depths per unit footprint area.
| [in] | g | Prepared parallel LID depth, porosity, thickness and moisture arrays. |
| [in] | ui | Valid unit index covered by all accessed arrays, unchecked. |
| [out] | v | Exactly kNL depths ft: surface, pavement, soil, storage. These are not total ft3; caller multiplies by footprint area if absolute water volume is required. |
Void-weighted water held in each layer, as a depth per unit area (ft). The four terms are exactly those LIDSolver::storedVolume() sums.
| bool openswmm::transport::legacyReactionsActive | ( | const SimulationContext & | ctx | ) |
Test configured and compiled native reaction readiness.
| [in] | ctx | Stable reaction flags. |
True when the reactions component is active (configured + compiled) — the QualitySolver's branch condition.
|
noexcept |
Compute current areal thermal capacity of a conventional-LID layer.
Heat capacity of one layer, J/m²/K over the layer's footprint.
| [in] | ctx | Stable conduction material and water density/specific heat SI configuration. |
| [in] | g | Prepared unit layer geometry/moisture arrays. |
| [in] | unit | Valid zero-based unit covered by every accessed array. |
| [in] | layer | Layer selector0..kNL-1; invalid returns0. |
Exported so a gate can sum a column's heat content and assert conservation WITHOUT restating the water/matrix mixture — a second copy of it in the test would make the gate agree with itself rather than with the code. Zero for an absent layer.
| std::vector< std::string > openswmm::transport::mirrorInitialQualityMsxRows | ( | SimulationContext & | ctx | ) |
Mirror resolved MSX initial seeds into the native reaction component's element seed table.
| [in,out] | ctx | Prepared configured reaction names/counts and resolved initial_quality rows; appends missing parallel init_elem kind/index/species/value entries, preserving existing values. |
Mirror every MSX-kind [INITIAL_QUALITY] row into ctx.reactions.init_elem_* (upsert; a conflicting .rxn row is reported). Returns the diagnostics (empty on success).
|
noexcept |
Resolve allocation-free native network class counts from current project policy.
1D network enables: LEGACY / ARD / LARD all size from this.
| [in] | ctx | Stable prepared pollutant/reaction counts and process flags. |
| void openswmm::transport::noteNegativeClamp | ( | SimulationContext & | ctx, |
| const char * | where ) |
Review A2: one warning per run when the reaction step had to clamp a negative concentration. The LEGACY binding also books the mass the clamp added (msx_ledger.clamped); the other engines report it here only.
Append one context-wide diagnostic after a negative RATE result is floored.
| [in,out] | ctx | Reaction warning latch and warnings list; latch set before string append. |
| [in] | where | Nonnull null-terminated element category, read synchronously/copied into warning. |
Review A2: record (once per run) that a reaction step clamped a negative concentration to zero at where.
| void openswmm::transport::reactArdStage | ( | SimulationContext & | ctx, |
| double | dt, | ||
| double * | cell_phi, | ||
| const double * | cell_a, | ||
| const double * | cell_dx, | ||
| int | n_cells, | ||
| double * | node_mass, | ||
| const double * | node_vol, | ||
| int | n_nodes, | ||
| int | n_pollut, | ||
| int | ns_total, | ||
| double | min_store_vol, | ||
| int | temp_row, | ||
| const int * | cell_conduit, | ||
| const int * | conduit_link ) |
Decay pollutant rows and integrate native reaction rows in ARD cell/node stores.
The E4 reaction stage over one routing step.
| [in,out] | ctx | Compiled reaction metadata/coefficients and node HRT/geometry, pollutant decay and reacted ledger plus once-only native reaction diagnostics. No hydraulic or engine clock advance. |
| [in] | dt | Positive finite accepted stage duration s; nonpositive returns (NaN not explicitly rejected). |
| [in,out] | cell_phi | Species-major [row*n_cells+cell] concentrations, writable n_cells*ns_total. |
| [in] | cell_a | Per-cell water area ft2. |
| [in] | cell_dx | Per-cell length ft, product with area yields represented native volume. |
| [in] | n_cells | Nonnegative cell count. |
| [in,out] | node_mass | Node-major [node*ns_total+row] concentration*ft3 inventories. |
| [in] | node_vol | Per-node retained native ft3, n_nodes entries. |
| [in] | n_nodes | Matching native node count, nonnegative. |
| [in] | n_pollut | Number of leading pollutant rows, matching ctx pollutant decay arrays. |
| [in] | ns_total | Total flattened row count; native n_species follow pollutant rows for this binding. |
| [in] | min_store_vol | Native ft3 threshold below/equal which node native kinetics skip. |
| [in] | temp_row | Optional valid thermal row, negative uses default reaction degC. |
| [in] | cell_conduit | Optional n_cells conduit indices, must be valid with conduit_link. |
| [in] | conduit_link | Optional conduit->native-link IDs; both mapping pointers required for geometry/overrides. |
|
inline |
Convert native square feet to configured reaction wall/dry-store area units.
| [in] | units | M2, CM2 or FT2/other selector. |
|
inline |
Compute active wetted reaction wall area per litre of water.
| [in] | c | Stable prepared wall/geometry configuration. |
| [in] | link_element | True link, false node identity. |
| [in] | e | Valid element ID for geometry resolution. |
| [in] | volume | Native water ft3; only>.0353147 triggers geometry lookup. |
|
inline |
Compute and book the first matching node/species booster inventory addition.
| [in,out] | ctx | Resolved reaction source patterns and current elapsed clock (read only); updates booster_mass and armed MSX inflow ledger, never physical concentration directly. |
| [in] | node | Native node ID matched against source rows. |
| [in] | species | Valid native species row with covered ledger arrays. |
| [in] | mass | Existing mixed native concentration*ft3 inventory. |
| [in] | mixed_volume | Total mixed water ft3; <=1e-12/NaN returns0. |
| [in] | arriving_volume | Positive arriving water ft3; <=1e-12/NaN returns0 even for setpoint. |
| std::string openswmm::transport::reactionContextDiagnostic | ( | const ReactionData & | rx, |
| const std::vector< RxToken > & | pool, | ||
| const RxExprSpan & | span, | ||
| int | context ) |
Recursively reject hydraulic/species/pollutant references unavailable in one reactor context.
context: 0=network, 1=shared term definition, 2=groundwater, 3=wet subcatchment.
| [in] | rx | Stable compiled species wall flags, wall-geometry switch and acyclic forward term graph. |
| [in] | pool | Token storage covering supplied span; recursive term spans use rx.token_pool. |
| [in] | span | Compiled expression span with fitting integer extent and valid species indices. |
| [in] | context | 0 pipe,1 tank (ground variables permitted),2 groundwater,>=3 wet/LID contexts. |
| int openswmm::transport::reactionFunctionCount | ( | ) |
Read number of supported compiled scalar function entries.
Number of built-in functions.
| bool openswmm::transport::reactionFunctionInfo | ( | int | idx, |
| const char ** | name, | ||
| int * | arity ) |
Read name and argument count of one supported expression function.
Name + arity of function idx; false when out of range.
| [in] | idx | Zero-based table row; invalid returnsfalse without touching outputs. |
| [out] | name | Optional pointer receiving static nonowned null-terminated function name. |
| [out] | arity | Optional pointer receiving required operand count. |
| int openswmm::transport::reactionHydVarCount | ( | ) |
Read number of declared hydraulic/thermal/groundwater expression variables.
Number of built-in hydraulic variables.
| bool openswmm::transport::reactionHydVarInfo | ( | int | idx, |
| const char ** | name, | ||
| const char ** | description ) |
Read canonical variable name and description including its declared units/support.
Name + one-line description of hydraulic variable idx.
| [in] | idx | Zero-based RxHydVar row; invalid returnsfalse and preserves outputs. |
| [out] | name | Optional pointer receiving static borrowed variable name. |
| [out] | description | Optional pointer receiving static borrowed unit/population description. |
| bool openswmm::transport::reactionHydVarPopulated | ( | int | idx | ) |
Test the network-quality variable range currently populated by native routing.
| [in] | idx | Integer RxHydVar identity. |
Physics review A1 (2026-10-15): whether any engine fills hydraulic variable idx. D, Q, U, RE, US and FF remain unavailable. AV requires WALL_GEOMETRY; HRT, DT and TEMP have their documented reactor contexts.
| const std::vector< std::string > & openswmm::transport::reactionSectionTags | ( | ) |
Borrow the complete fixed set of supported embedded/external reaction section names.
The recognised [REACTION_*] tags (upper-case, no brackets) — shared by the embedded-fallback handlers and the config parser.
|
inline |
Read a periodic reaction-source pattern factor at an elapsed simulation time.
| [in] | r | Stable source_patterns, positive finite pattern_timestep seconds and nonempty factor arrays. |
| [in] | source | Resolved source; pattern<0 means unpatterned, otherwise valid pattern index. |
| [in] | seconds | Finite elapsed seconds; negatives floor0 before phase wrap. |
|
inline |
Resolve explicit or hydraulic wetted reaction wall area for an element.
| [in] | c | Stable wall override rows and prepared native conduit geometry/subtype tables. |
| [in] | link_element | True identifies a link, false a node. |
| [in] | e | Native element ID; explicit matching override returned before generic validity check. |
| [in] | reference | True uses full section depth, false accepted current link depth. Explicit area overrides use same fixed value for reference and active requests. |
|
inline |
Build per-species active-to-reference wall coverage multipliers.
| [in] | c | Stable configured species wall flags and prepared wall/geometry arrays. |
| [in] | link_element | True selects link identity, false node. |
| [in] | e | Valid native element ID. |
| [in] | volume | Water ft3; <=one litre/NaN uses active area0. |
| [out] | scales | Resized/reset n_species to1 for BULK and clamp(active/reference,0,1) for WALL; reference<=0 gives WALL0. Owns no geometry pointers after return. |
| void openswmm::transport::reactLegacyLinks | ( | SimulationContext & | ctx, |
| double | dt ) |
Run legacy-bound exact pollutant decay and native link kinetics once.
| [in,out] | ctx | Configured/compiled reactions and matching prepared native species/pollutant, hydraulic, thermal/geometry and mass-ledger arrays; seeds species only if node-shaped state mismatches. |
| [in] | dt | Positive finite accepted routing duration s; inactive/nonpositive returns. |
Link-side step: exact-exponential pollutant decay + MSX pipe-scope integration. Runs AFTER updateLinkQuality() (whose internal linear decay is zeroed when reactions are active), so the reacted concentrations are not overwritten by the mixing pass.
| void openswmm::transport::reactLegacyNodes | ( | SimulationContext & | ctx, |
| double | dt ) |
Run legacy-bound exact pollutant decay and native node kinetics once.
| [in,out] | ctx | Configured/compiled reactions and matching prepared native species/pollutant, hydraulic, thermal/geometry and mass-ledger arrays; seeds species only if node-shaped state mismatches. |
| [in] | dt | Positive finite accepted routing duration s; inactive/nonpositive returns. |
Node-side step: exact-exponential pollutant decay + MSX tank-scope integration. Runs where applyDecay() ran (before updateLinkQuality).
| void openswmm::transport::reactSpeciesBlock | ( | SimulationContext & | ctx, |
| bool | tank, | ||
| double | dt, | ||
| double * | species_block, | ||
| const double * | pollut, | ||
| double | hrt_seconds, | ||
| double | temp_c, | ||
| int | element ) |
React one LARD-owned tuple with held HRT/temperature and optional element geometry.
| [in,out] | ctx | Stable compiled reaction data/coefficients and once-only diagnostic flags/list. |
| [in] | tank | True tank laws, false pipe laws. |
| [in] | dt | Accepted positive finite reaction duration s, forwarded to integrator. |
| [in,out] | species_block | Writable n_species local tuple, retained unchanged on returned solve failure; accepted RATE negatives floor0. Must not alias private static workspace/pollutant input. |
| [in] | pollut | Optional stable np current concentrations required by referenced tokens. |
| [in] | hrt_seconds | Held reactor HRT seconds. |
| [in] | temp_c | Held degC; nonfinite selects reaction default. |
| [in] | element | Matching native node/link ID or negative for no element geometry/override lookup; when wall geometry enabled nonnegative ID must be valid. |
L3: integrate ONE species block in place over dt through the shared integrator. pollut may be null (no pollutant context); tank selects tank-scope expressions; hrt_seconds feeds RxHydVar::HRT and temp_c feeds RxHydVar::TEMP (NaN ⇒ the [REACTION_OPTIONS] TEMPERATURE constant). On an integrator failure the block is left unchanged and the once-per-run failure warning fires — the reactElements contract.
| bool openswmm::transport::recompileReactionSystem | ( | SimulationContext & | ctx, |
| std::vector< std::string > & | errors ) |
Rebuild all compiled reaction expressions and validate scoped availability/profile constraints.
| [in,out] | ctx | Internally consistent species/coefficient/term/source form arrays and final native geometry/control/name tables; clears compiled flag/token pool and replaces spans before compilation. |
| [in,out] | errors | Appends qualified source/column diagnostics; prior errors alone do not make this routine fail (success tests only newly appended count). |
Recompile every reaction expression (terms, pipes, tanks) into a fresh flat token pool from the sources in ctx.reactions (E-C2: the one compile path, shared by the file apply and the CRUD API's eager validation — D-RC4, no second compiler). Returns true and sets rx.compiled on success; on failure appends diagnostics and leaves rx.compiled false (the pool/spans hold the partial result — callers roll back or clear).
| void openswmm::transport::registerArdComponent | ( | ) |
Register built-in ARD parser/serializer callbacks in process singleton.
Register org.hydrocouple.openswmm.transport.ard with the process-component registry (idempotent; called from SWMMEngine::open before resolution, next to registerReactionsComponent).
| void openswmm::transport::registerHeatComponent | ( | ) |
Register built-in heat configuration parser and serializer callbacks.
Register org.hydrocouple.openswmm.heat with the process-component registry (idempotent; called from SWMMEngine::open before resolution).
| void openswmm::transport::registerReactionsComponent | ( | ) |
Register native reaction parser/serializer callbacks under the built-in component ID.
Register org.hydrocouple.openswmm.reactions with the process-component registry (idempotent; called from SWMMEngine::open before resolution).
| void openswmm::transport::registerWaterAgeComponent | ( | ) |
Register the built-in water-age configuration parser and serializer callbacks.
Register org.hydrocouple.openswmm.waterage with the process-component registry (idempotent; called from SWMMEngine::open before resolution).
| Matrix openswmm::transport::resolve | ( | const SimulationContext & | ctx, |
| const Draft * | draft ) |
Build a domain-by-species transport capability matrix with explicit reasons and counts.
| [in] | ctx | Stable complete model/process, native reaction/surface-loading, optional 2D mesh, aquifer and domain policy metadata. Read only, including warnings. |
| [in] | draft | Optional borrowed preview overrides for quality/age/heat/mesh/groundwater/2D ignore and four surface class flags; null resolves current configuration. No pointer retained. |
| void openswmm::transport::resolveArdTransportRows | ( | SimulationContext & | ctx, |
| std::vector< std::string > & | errors ) |
Resolve deferred MSX boundary/source rows to native element/species/time-series arrays.
| [in,out] | ctx | Final native node/conduit names and reaction species/series registry; clears dense BC/source arrays, binds accepted unique element/species tuples and sets transport_rows_resolved true at normal return, even with appended errors. |
| [in,out] | errors | Appends unknown element/species/series or duplicate errors; preserves prior entries. |
E5a: resolve the raw [TRANSPORT_BOUNDARIES]/[TRANSPORT_SOURCES] rows to node/link/species/timeseries indices. Called from SWMMEngine::open AFTER all process components (and the embedded reactions fallback) have applied, because the rows name MSX species and the reactions component may apply before or after transport.ard in file order. Pushes fatal diagnostics into errors; pollutant species are refused (their loading surface is the legacy pathways). Source VALUE rates convert from species mass/s to internal conc·ft³/s here (kLitersPerFt3).
| void openswmm::transport::routeLegacyAge | ( | SimulationContext & | ctx, |
| double | dt ) |
Advance age seconds through legacy node/conduit mixing without altering pollutants.
| [in,out] | ctx | Enabled age config/state, completed old/new hydraulics and assembled qual_vol_in ft3 plus external age-volume rate (age seconds*ft3/s); writes node/link ages and clamp diagnostics. |
| [in] | dt | Positive finite accepted routing interval s; disabled/nonpositive returns. |
One LEGACY age routing step (call at the END of QualitySolver::execute, after qual_vol_in is fully accumulated). No-op when WATER_AGE is off.
| void openswmm::transport::routeLegacyHeat | ( | SimulationContext & | ctx, |
| double | dt ) |
Apply heat flux then legacy complete-mix transport of node/link temperatures.
| [in,out] | ctx | Enabled thermal config/state, completed old/new native hydraulics and assembled qual_vol_in ft3 plus external temperature-volume rate degC*ft3/s; writes node/link degC and heat/bed state. |
| [in] | dt | Positive finite accepted routing interval s; disabled/nonpositive returns. |
One LEGACY temperature routing step (call at the END of QualitySolver::execute, after qual_vol_in is fully accumulated). No-op when HEAT_TRANSPORT is off.
| void openswmm::transport::routeLegacyMsx | ( | SimulationContext & | ctx, |
| double | dt ) |
Transport native BULK species through legacy node/link complete-mix routing and LID ports.
| [in,out] | ctx | Prepared old/current native hydraulics, matching reaction stores and assembled qual_vol_in ft3/external native concentration*ft3/s; updates native node/link concentrations, LID captures, source boosters and network inflow/seep/dry continuity ledger. |
| [in] | dt | Positive finite accepted routing interval s; nonpositive/no species returns. |
| void openswmm::transport::routeLidLayerAge | ( | SimulationContext & | ctx, |
| const lid::LIDSolver & | solver, | ||
| double | dt ) |
Advance and mix conventional-LID layer ages after accepted layer hydraulics.
Advance the per-layer ages one runoff step, after LIDSolver::execute.
| [in,out] | ctx | Enabled active shared layer scalar state with initialized old water depth ft, inflow age seconds, writable age/old-water/drain rows and matching group offsets. |
| [in] | solver | Completed grouped layer inflows ft/s and current water depths/void fractions; exact initialized group/unit order, parallel arrays covered. |
| [in] | dt | Positive finite accepted runoff interval s; nonpositive/NaN returns. |
| void openswmm::transport::routeLidLayerTemperature | ( | SimulationContext & | ctx, |
| const lid::LIDSolver & | solver, | ||
| double | dt ) |
Mix accepted layer inflows then solve optional LID heat conduction/atmospheric exchange.
| [in,out] | ctx | Enabled active shared layer thermal state, initialized old water depths and inflow temperatures, material/weather/override configuration; writes layer/drain degC and old-water depths. |
| [in] | solver | Completed layer inflow ft/s, new retained depths ft and configured thickness/porosity, exact matching initialized group/unit order and covered parallel arrays. |
| [in] | dt | Positive finite accepted runoff duration s; disabled/inactive/nonpositive/NaN returns. |
Advance every LID column one runoff step: advective mixing per layer, then one coupled thermal solve over the stack. Publishes the underdrain temperature, retiring HeatSource::RAINFALL's "(and LID drains until
H5)" marker.
< holds or receives WATER → advection
< has THERMAL MASS → conduction, policy
| void openswmm::transport::routeSubcatchmentAge | ( | SimulationContext & | ctx, |
| const runoff::RunoffSoA & | soa, | ||
| double | dt ) |
Age/mix subarea water stores with snow-adjusted precipitation and assembled run-on.
| [in,out] | ctx | Enabled age config/state and prepared rainfall/snow/run-on receipts; writes subarea ages seconds, old water volumes ft3 and runoff age. |
| [in] | soa | Completed runoff area ft2, area fractions and new subarea depths ft, matching source order. |
| [in] | dt | Positive finite accepted runoff interval s; disabled/nonpositive or no sources returns. |
One runoff-step update of the subarea ages and the published runoff age. Call immediately AFTER the runoff solver has stepped, so the depths are this step's. No-op when WATER_AGE is off.
| void openswmm::transport::routeSubcatchmentTemperature | ( | SimulationContext & | ctx, |
| const runoff::RunoffSoA & | soa, | ||
| double | dt ) |
Mix snow-adjusted precipitation/run-on and atmospheric heat into subarea thermal stores.
Advance ponded subarea temperatures one runoff step.
| [in,out] | ctx | Enabled thermal configuration and prepared rain/snow/run-on receipts/weather; updates subarea degC, old volume ft3, runoff degC and solar forcing. |
| [in] | soa | Completed runoff geometry: native ft2 area, fractions and new depth ft, matching sources. |
| [in] | dt | Positive finite accepted runoff interval s; disabled/nonpositive/no sources returns. |
Per subarea, in order: apply the surface energy balance to the water that was already there, mix in what arrived by GROSS inflow volume, then publish the subcatchment's runoff temperature as the volume-weighted mean of the subareas holding water. Outflow leaves at the subarea's own temperature, so only the inflow is needed — the same complete-mix argument A3 arrived at after its net-gain estimate proved to be a 6.3× defect.
ctx.subcatches.ponded_depth is declared but written by nobody; reading it would give zeros.| std::string openswmm::transport::serializeReactionSystem | ( | const SimulationContext & | ctx | ) |
Serialize configured native reaction metadata and scoped laws to INP section text.
| [in] | ctx | Stable internally consistent reaction arrays/enums, species/coefficient/element/control names, initial-quality ownership and retained expression source strings. |
Canonical .rxn text for the current reaction system (empty system -> a header comment plus an empty [REACTION_SPECIES] shell is NOT emitted; the result is an empty string when nothing is configured).
| std::string openswmm::transport::serializeWaterAgeConfig | ( | const SimulationContext & | ctx | ) |
Serialize configured constant water-age source rows to canonical component text.
| [in] | ctx | Stable config, node names and covered parallel override arrays. |
Render [WATER_AGE_SOURCES] from the live config in FILE units (HOURS, shortest-exact) — the single spelling shared by the ComponentConfigSave hook and swmm_water_age_save (IO3c), the same sharing the reactions component has with serializeReactionSystem. Empty when the component never applied (save DECLINES → the carry-alongside copy runs).
| void openswmm::transport::setLidInflowAge | ( | SimulationContext & | ctx, |
| int | type_index, | ||
| int | unit, | ||
| int | subcatch, | ||
| double | rain_rate, | ||
| double | q_imperv, | ||
| double | q_perv, | ||
| double | q_runon, | ||
| double | lid_area ) |
Set one unit's scalar inflow age from rainfall and captured/run-on surface water.
| [in,out] | ctx | Enabled active layer scalar store and current subcatchment runoff age/config. |
| [in] | type_index | Valid group index; absent offset pair returns. |
| [in] | unit | Unit within that group; flattened global bound checked, not group-specific extent. |
| [in] | subcatch | Source subcatch ID; missing/nonpositive runoff age uses rainfall age. |
| [in] | rain_rate | Arriving rainfall depth ft/s, caller-qualified finite value. |
| [in] | q_imperv | Captured impervious runoff ft3/s. |
| [in] | q_perv | Captured pervious runoff ft3/s. |
| [in] | q_runon | Captured whole-subcatchment run-on ft3/s. |
| [in] | lid_area | Unit footprint ft2, converts rain_rate to carrier flow. |
Flow-weighted age of the water arriving at each LID unit this step, stored into ctx.lid_layer_state.inflow_value. Called where LIDGroupSoA::inflow is assembled, because that is the only place the contributing rates (rain, captured impervious and pervious runoff, whole-subcatchment run-on) exist together.
| void openswmm::transport::setLidInflowTemperature | ( | SimulationContext & | ctx, |
| int | type_index, | ||
| int | unit, | ||
| int | subcatch, | ||
| double | rain_rate, | ||
| double | q_imperv, | ||
| double | q_perv, | ||
| double | q_runon, | ||
| double | lid_area ) |
Set one LID unit's incoming degC from rainfall and captured/run-on surface water.
| [in,out] | ctx | Enabled active shared layer store and subcatchment thermal runoff/config values. |
| [in] | type_index | Valid group ID; absent offset pair returns. |
| [in] | unit | Valid unit in group; only flattened global bounds checked. |
| [in] | subcatch | Source ID; missing runoff temperature uses rainfall default. |
| [in] | rain_rate | Arriving precipitation depth ft/s. |
| [in] | q_imperv | Captured impervious runoff ft3/s. |
| [in] | q_perv | Captured pervious runoff ft3/s. |
| [in] | q_runon | Captured whole-subcatchment run-on ft3/s. |
| [in] | lid_area | Footprint ft2 multiplying rain_rate. |
Temperature of the water arriving at one unit this step, flow-weighted over the same four rates setLidInflowAge weights. Mirrors it exactly, including its hard-won choice to take the SUBCATCHMENT's published runoff value rather than reconstructing a mean from the subarea rows.
|
noexcept |
Format a transport species class as a human-readable label.
| [in] | c | Class enum; COUNT/invalid values use fallback. |
|
noexcept |
Resolve allocation-free surface native class eligibility from project and 2D opt-outs.
| [in] | ctx | Stable process/reaction/pollutant metadata and optional borrowed 2D options. |
2D surface enables: the 1D rule plus the [2D_OPTIONS] TRANSPORT_* keys. Age and temperature are NOT gated by IGNORE_QUALITY here (pre-E2 rule: "IGNORE_QUALITY turns off the pollutant and MSX rows only").
| std::string openswmm::transport::unpopulatedHydVarDiagnostic | ( | const std::string & | src, |
| const std::vector< RxToken > & | pool, | ||
| const RxExprSpan & | span, | ||
| int & | error_col ) |
Report first compiled hydraulic variable not in the network-populated range.
| [in] | src | Original expression used only to recover case-insensitive token-boundary column. |
| [in] | pool | Stable valid compiled token pool. |
| [in] | span | Covered compiled span with valid hydraulic indices; out-of-range token extent stops scan. |
| [out] | error_col | 1-based first source spelling match for refused variable, otherwise-1; reset on entry. |
Diagnostic for the first unpopulated hydraulic variable the compiled expression span reads, or empty. error_col is its 1-based column in src (or -1). The evaluator still accepts every variable; this is the contract check that the system-level compile and the validator apply.
| void openswmm::transport::warnIfFvDispersionKeyIgnored | ( | SimulationContext & | ctx | ) |
Warn when FV_DISPERSION is set while EULERIAN_ARD reads its own component coefficients.
| [in,out] | ctx | Stable shared dispersion/quality options and writable warning list. |
Warn when [OPTIONS] FV_DISPERSION is set under QUALITY_SOLVER EULERIAN_ARD. The component's own bypass warnings only cover models that HAVE a transport.ard file; this is the reverse case — the user spelled dispersion the familiar way, selected the engine that now supports it, and got nothing. FV_DISPERSION reaches no solver today (WARN 105 says so under FLOW_ROUTING FV, and nothing says it under DYNWAVE), so E3's arrival is what makes the silence misleading rather than merely inert.
| void openswmm::transport::warnIfLegacyBindingBypassed | ( | SimulationContext & | ctx | ) |
Warn when configured compiled reactions are bypassed by IGNORE_QUALITY.
| [in,out] | ctx | Reaction readiness and option flags; appends explanatory warning each qualifying call. |
Warn (once, at open) when a reactions component is configured but no engine will run it this simulation. As of E4/R6 the only remaining bypass is IGNORE_QUALITY — EULERIAN_ARD now runs its own binding (ReactionArdBinding) with MSX species transported on the mesh. Without this a user who wrote a .rxn file gets a run in which nothing reacted and nothing said so.
|
constexpr |
|
constexpr |
-1 means "external to the unit"; -2 means "this type has no such layer".
|
inlineconstexpr |
The temperature meltwater leaves a pack at, °C. Zero, and named rather than written as a literal so a gate can assert against the constant the code uses instead of against a number a reader hopes it uses.
|
constexpr |
|
constexpr |
|
inlineconstexpr |
Maximum operand-stack depth; the compiler rejects deeper expressions so the evaluator's fixed stack can never overflow.
|
constexpr |
|
constexpr |
|
constexpr |
Subarea ordering shared by SubArea (A3) and HeatSubArea (H5a). Both enums are deliberately separate types; this is the ordinal they agree on.
|
constexpr |
|
constexpr |
|
constexpr |
|
constexpr |
Legacy's effective-zero flow (ZERO in src/legacy/engine/consts.h). The mixing kernels test the inflow RATE against this, not against 0.0. Published here because the water-age, heat and MSX transport mirrors run the same kernels and must not drift from them.
|
constexpr |
Legacy's effective-zero flow (ZERO in src/legacy/engine/consts.h). The mixing kernels test the inflow RATE against this, not against 0.0. Published here because the water-age, heat and MSX transport mirrors run the same kernels and must not drift from them.
|
constexpr |
Legacy's effective-zero flow (ZERO in src/legacy/engine/consts.h). The mixing kernels test the inflow RATE against this, not against 0.0. Published here because the water-age, heat and MSX transport mirrors run the same kernels and must not drift from them.
|
constexpr |
The quality path's own thresholds — one litre and one millimetre, the numbers legacy qualrout.c routes on. This mirror previously carried a local 1e-10, so it dispatched differently from the family it mirrors.
|
constexpr |
The quality path's own thresholds — one litre and one millimetre, the numbers legacy qualrout.c routes on. This mirror previously carried a local 1e-10, so it dispatched differently from the family it mirrors.
|
constexpr |
The quality path's own thresholds — one litre and one millimetre, the numbers legacy qualrout.c routes on. This mirror previously carried a local 1e-10 under a comment claiming it matched the quality path; it did not, and the two families dispatched differently as a result.