OpenSWMM Engine  6.0.0-alpha.4
Data-oriented, plugin-extensible SWMM Engine (6.0.0-alpha.4)
Loading...
Searching...
No Matches
ReactionData.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: Apache-2.0
2//
3// Copyright 2026 Caleb Buahin
4//
5// Licensed under the Apache License, Version 2.0 (the "License");
6// you may not use this file except in compliance with the License.
7// You may obtain a copy of the License at
8//
9// http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing, software
12// distributed under the License is distributed on an "AS IS" BASIS,
13// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14// See the License for the specific language governing permissions and
15// limitations under the License.
16
37
38#ifndef OPENSWMM_ENGINE_DATA_REACTION_DATA_HPP
39#define OPENSWMM_ENGINE_DATA_REACTION_DATA_HPP
40
41#include <cstdint>
42#include <string>
43#include <string_view>
44#include <utility>
45#include <vector>
46
47#include "ReactionTokens.hpp"
48#include "MsxSurfaceData.hpp"
49
50namespace openswmm {
51
52enum class ReactionSolverKind : int { EUL = 0, RK5 = 1, ROS2 = 2, BDF2 = 3 };
53enum class ReactionCoupling : int { NONE = 0, FULL = 1 };
54enum class ReactionRateUnits : int { SEC = 0, MIN = 1, HR = 2, DAY = 3 };
55enum class ReactionAreaUnits : int { FT2 = 0, M2 = 1, CM2 = 2 };
56enum class ReactionExprForm : int { NONE = 0, RATE = 1, EQUIL = 2, FORMULA = 3 };
57
59 // ---- [REACTION_OPTIONS] ------------------------------------------------
91 bool wall_geometry = false;
92 double timestep = 0.0;
93 double atol = 1.0e-6;
94 double rtol = 1.0e-4;
98 double default_temp_c = 20.0;
99
100 // ---- [REACTION_SPECIES] — index-aligned with the SpeciesRegistry MSX
101 // block (registry index = registry_base + i). ------------------------
102 int registry_base = -1;
103 std::vector<std::string> species_name;
104 std::vector<uint8_t> species_is_wall;
105 std::vector<std::string> species_units;
106 std::vector<double> species_atol;
107 std::vector<double> species_rtol;
108
109 // ---- [REACTION_COEFFICIENTS] -------------------------------------------
110 std::vector<std::string> coef_name;
111 std::vector<uint8_t> coef_is_param;
112 std::vector<double> coef_value;
114
118 bool link;
120 double value;
121 };
122 std::vector<ParameterOverride> parameter_overrides;
123 struct WallArea {
124 bool link;
126 double area;
127 }; // declared AREA_UNITS
128 std::vector<WallArea> wall_areas;
135 std::vector<int> lid_controls;
136 std::vector<LidLaw> lid_laws;
137 struct LidState {
138 std::vector<std::vector<double>> node_mass, node_outlet;
139 std::vector<double> node_mobile_old;
140 std::vector<int> group_offsets;
141 std::vector<double> mass, old_water, surface_conc,
142 drain_conc; // conventional units, conc*ft3
143 std::vector<double> surface_export, surface_carry; // [subcatchment*species], conc*ft3
144 std::vector<uint8_t> subcatchments;
152 bool lid_enabled(int control) const {
153 for (int c : lid_controls)
154 if (c == control)
155 return true;
156 return false;
157 }
158
172 const double* coefficients(bool link, int element, std::vector<double>& scratch) const {
173 if (parameter_overrides.empty() || element < 0)
174 return coef_value.data();
175 scratch = coef_value;
176 for (const auto& row : parameter_overrides)
177 if (row.link == link && row.element == element)
178 scratch[static_cast<std::size_t>(row.coefficient)] = row.value;
179 return scratch.data();
180 }
181
183 std::string name;
184 std::vector<double> factors;
185 };
186 struct Source {
187 bool mass;
189 double value;
190 int booster = 0;
191 }; // 1 FLOWPACED, 2 SETPOINT
192 std::vector<double> booster_mass; // actual cumulative injection, concentration*ft3
193 double pattern_timestep = 3600.0;
194 std::vector<SourcePattern> source_patterns;
195 std::vector<Source> sources;
196
199 std::vector<uint8_t> report_enabled;
200 std::vector<int> reported_species;
201
202 // ---- [REACTION_TERMS] --------------------------------------------------
203 std::vector<std::string> term_name;
204 std::vector<std::string> term_expr_src;
205
207 int scope = 0, cell = -1, zone = 0, layer = -1,
208 species = -1; // scope: global/tag/cell; zone: sat/unsat/layer
209 std::string tag, expression;
212 };
213 std::vector<SubsurfaceLaw> subsurface_laws;
214
215 // ---- [REACTION_PIPES] / [REACTION_TANKS] — dense per species -----------
216 std::vector<ReactionExprForm> pipe_form;
217 std::vector<std::string> pipe_expr_src;
218 std::vector<ReactionExprForm> tank_form;
219 std::vector<std::string> tank_expr_src;
220
227 std::vector<SurfaceLaw> wet_laws, buildup_laws;
236 bool wet_enabled(int sc) const noexcept {
237 for (auto f : subcatch_form)
238 if (f != ReactionExprForm::NONE)
239 return true;
240 for (const auto& l : wet_laws)
241 if (l.subcatchment == sc)
242 return true;
243 return false;
244 }
245 // Wet, non-LID subcatchment pools have their own reactor context.
246 std::vector<ReactionExprForm> subcatch_form;
247 std::vector<std::string> subcatch_expr_src;
248 std::vector<RxExprSpan> subcatch_expr;
254 bool has_subcatch_reactions() const noexcept {
255 for (const auto form : subcatch_form)
256 if (form != ReactionExprForm::NONE)
257 return true;
258 return !wet_laws.empty();
259 }
260
261 // ---- [REACTION_QUALITY] GLOBAL initial values (R1) ---------------------
262 std::vector<double> init_global;
265 std::vector<double> rain_conc;
266
267 // ---- [REACTION_QUALITY] NODE/LINK per-element overrides (E-B) ----------
268 // Sparse row table over the GLOBAL seed; covered by clear() via the
269 // *this = ReactionData{} reset.
270 std::vector<uint8_t> init_elem_is_link;
271 std::vector<int> init_elem_idx;
272 std::vector<int> init_elem_species;
273 std::vector<double> init_elem_value;
274
275 // ---- Compiled bytecode (R2 — D-L3 flat pool; spans index token_pool) ----
276 std::vector<RxToken> token_pool;
277 std::vector<RxExprSpan> term_expr;
278 std::vector<RxExprSpan> pipe_expr;
279 std::vector<RxExprSpan> tank_expr;
280 bool compiled = false;
283
284 // ---- R4: MSX species element state under QUALITY_SOLVER LEGACY --------
285 // [element * n_species + s]; sized lazily by the legacy binding. R4b
286 // (2026-09-01): species react per element AND advect between elements
287 // (routeLegacyMsx, the CSTR mirror family) — the not-transported
288 // warning and its once-per-run flag are gone with the limitation.
289 std::vector<double> msx_node_conc;
290 std::vector<double> msx_link_conc;
291
292 // ---- U2 (2026-09-07): external MSX loads at the node seam ------------
293 // [node * n_species + m], a mass RATE in the species' internal unit
294 // convention (conc-units × ft3/s — the qual_mass_in shape), assembled
295 // every routing step by InflowSolver::computeAll from [INFLOWS] rows
296 // that name a species (CONCEN × node external flow, or MASS ÷ LperFT3).
297 // Empty until a species inflow row exists. Consumed by every quality
298 // engine's node mixing: routeLegacyMsx (LEGACY), ArdEngine stage 1b /
299 // 1a' (EULERIAN_ARD) and the LARD node stage.
300 std::vector<double> msx_ext_mass_in;
301
307 std::vector<double> msx_coupling_queue;
308
316 bool armed = false;
326 void arm(std::size_t ns) {
327 armed = true;
328 for (auto* v :
330 v->assign(ns, 0.0);
331 }
332 };
334
341
342 bool configured = false;
343
348 int n_species() const noexcept { return static_cast<int>(species_name.size()); }
355 int find_species(std::string_view n) const {
356 for (std::size_t i = 0; i < species_name.size(); ++i)
357 if (species_name[i] == n)
358 return static_cast<int>(i);
359 return -1;
360 }
361
367 int find_coef(std::string_view n) const {
368 for (std::size_t i = 0; i < coef_name.size(); ++i)
369 if (coef_name[i] == n)
370 return static_cast<int>(i);
371 return -1;
372 }
373
379 int find_term(std::string_view n) const {
380 for (std::size_t i = 0; i < term_name.size(); ++i)
381 if (term_name[i] == n)
382 return static_cast<int>(i);
383 return -1;
384 }
385
394 void clear() {
395 MsxSurfaceData keep = std::move(surface);
396 *this = ReactionData{};
397 surface = std::move(keep);
398 }
399};
400
401} // namespace openswmm
402
403#endif // OPENSWMM_ENGINE_DATA_REACTION_DATA_HPP
BW-MSX (2026-09-19) — surface buildup / washoff / sweeping state and parameters for the reactions com...
POD reaction-VM instruction + span types (phase R2, D-L3 flat pool). Data-layer header: no dependenci...
@ NONE
Definition SimulationContext.hpp:183
Definition LID.cpp:39
Definition ExchangeLaw.hpp:60
ReactionSolverKind
Definition ReactionData.hpp:52
@ ROS2
Definition ReactionData.hpp:52
@ EUL
Definition ReactionData.hpp:52
@ BDF2
Definition ReactionData.hpp:52
@ RK5
Definition ReactionData.hpp:52
@ MIN
Definition NodeCoupling2DData.hpp:67
ReactionRateUnits
Definition ReactionData.hpp:54
@ DAY
Definition ReactionData.hpp:54
@ SEC
Definition ReactionData.hpp:54
@ HR
Definition ReactionData.hpp:54
ReactionCoupling
Definition ReactionData.hpp:53
@ NONE
Definition ReactionData.hpp:53
@ FULL
Definition ReactionData.hpp:53
ReactionExprForm
Definition ReactionData.hpp:56
@ EQUIL
Definition ReactionData.hpp:56
@ RATE
Definition ReactionData.hpp:56
@ FORMULA
Definition ReactionData.hpp:56
@ NONE
Definition ReactionData.hpp:56
ReactionAreaUnits
Definition ReactionData.hpp:55
@ CM2
Definition ReactionData.hpp:55
@ M2
Definition ReactionData.hpp:55
@ FT2
Definition ReactionData.hpp:55
Resolved MSX surface-quality parameters and state.
Definition MsxSurfaceData.hpp:98
Definition ReactionData.hpp:129
ReactionExprForm form
Definition ReactionData.hpp:131
int control
Definition ReactionData.hpp:130
RxExprSpan compiled
Definition ReactionData.hpp:133
int layer
Definition ReactionData.hpp:130
std::string expression
Definition ReactionData.hpp:132
int species
Definition ReactionData.hpp:130
Definition ReactionData.hpp:137
std::vector< std::vector< double > > node_mass
Definition ReactionData.hpp:138
std::vector< double > node_mobile_old
Definition ReactionData.hpp:139
std::vector< double > drain_conc
Definition ReactionData.hpp:142
std::vector< double > surface_conc
Definition ReactionData.hpp:141
std::vector< double > surface_export
Definition ReactionData.hpp:143
std::vector< double > surface_carry
Definition ReactionData.hpp:143
std::vector< std::vector< double > > node_outlet
Definition ReactionData.hpp:138
std::vector< double > mass
Definition ReactionData.hpp:141
std::vector< int > group_offsets
Definition ReactionData.hpp:140
std::vector< double > old_water
Definition ReactionData.hpp:141
std::vector< uint8_t > subcatchments
Definition ReactionData.hpp:144
Definition ReactionData.hpp:315
std::vector< double > clamped
Definition ReactionData.hpp:317
std::vector< double > reacted
Definition ReactionData.hpp:317
std::vector< double > final_dry
Definition ReactionData.hpp:317
bool armed
Definition ReactionData.hpp:316
std::vector< double > flooding
Definition ReactionData.hpp:317
std::vector< double > seepage
Definition ReactionData.hpp:317
std::vector< double > inflow
Definition ReactionData.hpp:317
std::vector< double > outflow
Definition ReactionData.hpp:317
void arm(std::size_t ns)
Zero and activate the legacy MSX routing ledger.
Definition ReactionData.hpp:326
std::vector< double > init
Definition ReactionData.hpp:317
Definition ReactionData.hpp:117
int coefficient
Definition ReactionData.hpp:119
double value
Definition ReactionData.hpp:120
bool link
Definition ReactionData.hpp:118
int element
Definition ReactionData.hpp:119
Definition ReactionData.hpp:186
int booster
Definition ReactionData.hpp:190
int species
Definition ReactionData.hpp:188
int pattern
Definition ReactionData.hpp:188
double value
Definition ReactionData.hpp:189
bool mass
Definition ReactionData.hpp:187
int node
Definition ReactionData.hpp:188
Definition ReactionData.hpp:182
std::string name
Definition ReactionData.hpp:183
std::vector< double > factors
Definition ReactionData.hpp:184
Definition ReactionData.hpp:206
std::string tag
Definition ReactionData.hpp:209
ReactionExprForm form
Definition ReactionData.hpp:210
int species
Definition ReactionData.hpp:208
int layer
Definition ReactionData.hpp:207
RxExprSpan compiled
Definition ReactionData.hpp:211
int cell
Definition ReactionData.hpp:207
int zone
Definition ReactionData.hpp:207
int scope
Definition ReactionData.hpp:207
std::string expression
Definition ReactionData.hpp:209
Definition ReactionData.hpp:221
RxExprSpan compiled
Definition ReactionData.hpp:225
int landuse
Definition ReactionData.hpp:222
int species
Definition ReactionData.hpp:222
ReactionExprForm form
Definition ReactionData.hpp:223
std::string expression
Definition ReactionData.hpp:224
int subcatchment
Definition ReactionData.hpp:222
Definition ReactionData.hpp:123
double area
Definition ReactionData.hpp:126
bool link
Definition ReactionData.hpp:124
int element
Definition ReactionData.hpp:125
Definition ReactionData.hpp:58
int find_species(std::string_view n) const
Find the first exact-case species name.
Definition ReactionData.hpp:355
std::vector< uint8_t > coef_is_param
1 = PARAMETER (overridable), 0 = CONSTANT
Definition ReactionData.hpp:111
std::vector< ReactionExprForm > pipe_form
size n_species
Definition ReactionData.hpp:216
void clear()
Reset reaction configuration/runtime state while preserving authored surface rows.
Definition ReactionData.hpp:394
double pattern_timestep
seconds, independent of RATE_UNITS
Definition ReactionData.hpp:193
const double * coefficients(bool link, int element, std::vector< double > &scratch) const
Borrow global coefficients or gather element-specific parameter overrides.
Definition ReactionData.hpp:172
std::vector< RxExprSpan > tank_expr
per species
Definition ReactionData.hpp:279
std::vector< double > msx_coupling_queue
Definition ReactionData.hpp:307
bool compiled
R2 compile pass succeeded.
Definition ReactionData.hpp:280
double default_temp_c
Definition ReactionData.hpp:98
double rtol
Definition ReactionData.hpp:94
bool wet_enabled(int sc) const noexcept
Test whether wet surface reactions can apply to one subcatchment.
Definition ReactionData.hpp:236
std::vector< WallArea > wall_areas
Definition ReactionData.hpp:128
std::vector< SourcePattern > source_patterns
Definition ReactionData.hpp:194
std::vector< SurfaceLaw > wet_laws
Definition ReactionData.hpp:227
std::vector< std::string > pipe_expr_src
size n_species (cold)
Definition ReactionData.hpp:217
std::vector< RxExprSpan > pipe_expr
per species (len 0 ⇒ none)
Definition ReactionData.hpp:278
std::vector< int > init_elem_species
0..n_species()-1
Definition ReactionData.hpp:272
std::vector< LidLaw > lid_laws
Definition ReactionData.hpp:136
bool warned_react_failure
Definition ReactionData.hpp:281
MsxSurfaceData surface
Definition ReactionData.hpp:340
double atol
Definition ReactionData.hpp:93
std::vector< double > species_rtol
hot (0 ⇒ global)
Definition ReactionData.hpp:107
bool lid_enabled(int control) const
Test whether a LID control key occurs in the configured reaction list.
Definition ReactionData.hpp:152
std::vector< std::string > species_name
cold
Definition ReactionData.hpp:103
std::vector< ReactionExprForm > subcatch_form
Definition ReactionData.hpp:246
std::vector< double > msx_ext_mass_in
Definition ReactionData.hpp:300
ReactionAreaUnits area_units
Definition ReactionData.hpp:90
bool warned_negative_clamp
review A2: once-per-run note
Definition ReactionData.hpp:282
int registry_base
first MSX index in the registry
Definition ReactionData.hpp:102
std::vector< SubsurfaceLaw > subsurface_laws
Definition ReactionData.hpp:213
std::vector< std::string > subcatch_expr_src
Definition ReactionData.hpp:247
std::vector< double > msx_node_conc
Definition ReactionData.hpp:289
MsxRoutingLedger msx_ledger
Definition ReactionData.hpp:333
int find_term(std::string_view n) const
Find the first exact-case term name.
Definition ReactionData.hpp:379
bool wall_geometry
WALL densities use a fixed reference contact area.
Definition ReactionData.hpp:91
std::vector< uint8_t > init_elem_is_link
0 = NODE row, 1 = LINK row
Definition ReactionData.hpp:270
std::vector< RxToken > token_pool
hot: one contiguous pool
Definition ReactionData.hpp:276
std::vector< int > init_elem_idx
resolved node/link index
Definition ReactionData.hpp:271
std::vector< ReactionExprForm > tank_form
Definition ReactionData.hpp:218
int find_coef(std::string_view n) const
Find the first exact-case coefficient name.
Definition ReactionData.hpp:367
double timestep
0 ⇒ follow QUALITY_STEP
Definition ReactionData.hpp:92
int n_species() const noexcept
Count authored reaction species.
Definition ReactionData.hpp:348
std::vector< uint8_t > report_enabled
Definition ReactionData.hpp:199
std::vector< Source > sources
Definition ReactionData.hpp:195
std::vector< std::string > species_units
cold
Definition ReactionData.hpp:105
std::vector< std::string > coef_name
cold
Definition ReactionData.hpp:110
std::vector< double > coef_value
Definition ReactionData.hpp:112
std::vector< RxExprSpan > subcatch_expr
Definition ReactionData.hpp:248
std::vector< std::string > term_name
cold
Definition ReactionData.hpp:203
std::vector< double > msx_link_conc
Definition ReactionData.hpp:290
ReactionSolverKind solver
Default integrator.
Definition ReactionData.hpp:87
std::vector< double > species_atol
hot (0 ⇒ global)
Definition ReactionData.hpp:106
std::vector< SurfaceLaw > buildup_laws
Definition ReactionData.hpp:227
std::vector< std::string > term_expr_src
cold (compiled in R2)
Definition ReactionData.hpp:204
std::vector< ParameterOverride > parameter_overrides
Definition ReactionData.hpp:122
std::vector< double > rain_conc
Definition ReactionData.hpp:265
bool configured
a reactions component applied
Definition ReactionData.hpp:342
ReactionRateUnits rate_units
Definition ReactionData.hpp:89
bool has_subcatch_reactions() const noexcept
Test whether any global or sparse wet subcatchment reaction is configured.
Definition ReactionData.hpp:254
std::vector< double > init_elem_value
Definition ReactionData.hpp:273
std::vector< double > booster_mass
Definition ReactionData.hpp:192
std::vector< RxExprSpan > term_expr
per term, in-order evaluation
Definition ReactionData.hpp:277
std::vector< int > reported_species
Definition ReactionData.hpp:200
std::vector< int > lid_controls
Definition ReactionData.hpp:135
std::vector< std::string > tank_expr_src
Definition ReactionData.hpp:219
ReactionCoupling coupling
Definition ReactionData.hpp:88
std::vector< uint8_t > species_is_wall
0 = BULK, 1 = WALL
Definition ReactionData.hpp:104
std::vector< double > init_global
Definition ReactionData.hpp:262
Compiled expression = span into the shared pool. len 0 ⇒ no expression.
Definition ReactionTokens.hpp:95