OpenSWMM Engine  6.0.0-alpha.4
Data-oriented, plugin-extensible SWMM Engine (6.0.0-alpha.4)
Loading...
Searching...
No Matches
SimulationContext.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
75
76#ifndef OPENSWMM_ENGINE_SIMULATION_CONTEXT_HPP
77#define OPENSWMM_ENGINE_SIMULATION_CONTEXT_HPP
78
79#include <cmath>
80#include <ctime>
81#include <functional>
82#include "FilePathPair.hpp"
85#include "../data/GageData.hpp"
86#include "../data/HeatData.hpp"
89#include "../data/LinkData.hpp"
90#include "../data/NameIndex.hpp"
91#include "../data/NodeData.hpp"
98#include "../data/TableData.hpp"
99#include "SimulationOptions.hpp"
100#include "SpatialFrame.hpp"
101#include "UserFlags.hpp"
104#include "../data/InflowData.hpp"
105#include "../data/InfraData.hpp"
110
111#include <algorithm>
112#include <cstdint>
113#include <string>
114#include <utility>
115#include <vector>
116
117namespace openswmm {
118
119// ============================================================================
120// Plugin specification (from [PLUGINS] section)
121// ============================================================================
122
133 std::string path;
134 std::vector<std::string> init_args;
135};
136
137// ============================================================================
138// [PROCESS_COMPONENTS] section spec — process-component registrations
139// ============================================================================
140
155 std::string id;
156 std::string config_path;
157 std::vector<std::pair<std::string, std::string>> args;
158
164};
165
166// ============================================================================
167// [FILES] section spec — secondary file references
168// ============================================================================
169
179enum class FileMode {
183};
184
211
248
249// ============================================================================
250// Engine state enumeration
251// ============================================================================
252
261enum class EngineState : int32_t {
263 OPENED = 1,
266 PAUSED = 4,
267 ENDED = 5,
269 CLOSED = 7,
272};
273
274// ============================================================================
275// StateAccessors
276// ============================================================================
277
297 std::function<bool(int subcatch_index, int& out_model, double* out_infil)> get_infil_state;
298
301 std::function<bool(int subcatch_index, int model, const double* infil)> set_infil_state;
302
304 std::function<bool(int subcatch_index, double& out_theta, double& out_lower_depth)> get_gw_state;
305
307 std::function<bool(int subcatch_index, double theta, double lower_depth)> set_gw_state;
308
310 bool can_read() const noexcept {
311 return static_cast<bool>(get_infil_state) || static_cast<bool>(get_gw_state);
312 }
313
315 bool can_write() const noexcept {
316 return static_cast<bool>(set_infil_state) || static_cast<bool>(set_gw_state);
317 }
318};
319
320// ============================================================================
321// 2D model-IO bridge (forward declarations)
322// ============================================================================
323
324// Plain 2D data structs (all header-only and define-free; see
325// src/engine/2d/data/). Forward-declared so SimulationContext can carry
326// non-owning pointers without pulling the 2D module into every TU.
327namespace twoD {
328struct MeshData;
329struct SolverOptions2D;
330struct BoundaryData;
331class Infil2D;
332struct PendingBoundaryRow;
333struct PendingEdgeConveyanceRow;
334struct PendingInitialQualityRow;
335struct PendingBoundaryQualityRow;
336struct GwTransportData; // U4 (2026-09-07)
337struct SubsurfaceConfig; // G1: the [2D_AQUIFER*] rows
338struct SubsurfaceState; // G1: the running two-zone kernel state
339} // namespace twoD
340
341// ============================================================================
342// SimulationContext
343// ============================================================================
344
354
355 // =========================================================================
356 // Engine state
357 // =========================================================================
358
361
373 std::time_t wall_start = 0;
374
375 // =========================================================================
376 // Project title / notes
377 // =========================================================================
378
388 std::vector<std::string> title_notes;
389
390 // =========================================================================
391 // Options & configuration
392 // =========================================================================
393
399
412
413 // =========================================================================
414 // Simulation clock
415 // =========================================================================
416
435 double current_time = 0.0;
436
444 double current_date = 0.0;
445
458 double elapsed_ms = 0.0;
459
466 double old_elapsed_ms = 0.0;
467
478 double next_report_ms = 0.0;
479
487
488 // =========================================================================
489 // Object data stores (Structure-of-Arrays)
490 // =========================================================================
491
497
508
514
522
528
534
540
550
558
566
574
581
590
602
618 std::vector<std::string> reported_species_names;
619
621 int n_reported_species() const noexcept {
622 return static_cast<int>(reported_species_names.size());
623 }
624
630
631 // =========================================================================
632 // Name-to-index lookup (O(1))
633 // =========================================================================
634
640
646
652
658
664
665 // NOTE: there is deliberately NO shared name registry for tables.
666 // Legacy keeps TSERIES and CURVE in separate hash tables, so a curve and
667 // a timeseries may legally share one name; ctx.tables is the authority
668 // (each row stores id + type) and lookups are kind-aware via
669 // find_timeseries() / find_curve() below.
670
671 // =========================================================================
672 // Quality data (landuse, buildup, washoff, treatment)
673 // =========================================================================
674
680
689
690 // =========================================================================
691 // Inflow data (external, DWF, RDII, patterns)
692 // =========================================================================
693
700
701 // =========================================================================
702 // Infrastructure data (transects, streets, inlets, controls)
703 // =========================================================================
704
707 std::vector<transect::TransectData> transect_tables;
712 std::uint64_t xsect_generation = 0;
713
722
727
728 // =========================================================================
729 // Events (from [EVENTS] section)
730 // =========================================================================
731
737 struct Event {
738 double start = 0.0;
739 double end = 0.0;
740 };
741 std::vector<Event> events;
742
743 // =========================================================================
744 // Subcatchment adjustment patterns (from [ADJUSTMENTS] section)
745 // =========================================================================
746
753 double adjust_temp[12] = {0,0,0,0,0,0,0,0,0,0,0,0};
754 double adjust_evap[12] = {1,1,1,1,1,1,1,1,1,1,1,1};
755 double adjust_rain[12] = {1,1,1,1,1,1,1,1,1,1,1,1};
756 double adjust_hydcon[12] = {1,1,1,1,1,1,1,1,1,1,1,1};
757
763 std::vector<int> subcatch_n_perv_pattern;
764 std::vector<int> subcatch_d_store_pattern;
765 std::vector<int> subcatch_infil_pattern;
766
768 std::vector<double> base_n_perv;
769 std::vector<double> base_ds_perv;
771
772 // =========================================================================
773 // Hydrology data (snowpacks, aquifers, LID)
774 // =========================================================================
775
783
784 // =========================================================================
785 // Transient deferred-resolution capture lists (input loading only)
786 // =========================================================================
787 // Sections whose referenced objects may be defined later in the .inp store
788 // the raw name here so PostParseResolver can re-resolve after every section
789 // has been parsed. Cleared by the resolver; empty outside input loading, so
790 // they can never desync with the editing APIs.
791
794 std::vector<std::pair<int, std::string>> pending_gw_nodes;
795
799 std::vector<std::pair<int, std::pair<std::string, std::string>>>
801
802 // =========================================================================
803 // Spatial data
804 // =========================================================================
805
811
812 // =========================================================================
813 // User-defined flags
814 // =========================================================================
815
822
823 // =========================================================================
824 // Object tags (from [TAGS] section)
825 // =========================================================================
826
827 // Tags from the [TAGS] section now live per-index on
828 // NodeData::tags / LinkData::tags / SubcatchData::tags. Storing
829 // them name-keyed here was a latent rename bug — a tagged node
830 // would lose its tag the moment `swmm_node_rename` was called.
831
832 // =========================================================================
833 // Runtime forcing data
834 // =========================================================================
835
845
846 // =========================================================================
847 // Plugin specifications (from [PLUGINS] section)
848 // =========================================================================
849
855 std::vector<PluginSpec> plugin_specs;
856
864 std::vector<ProcessComponentSpec> process_component_specs;
865
873 std::vector<std::pair<std::string, std::vector<std::string>>>
875
885
895
916 struct TwoDModelIO {
920 std::vector<twoD::PendingBoundaryRow>* pending_bc = nullptr;
921 std::vector<twoD::PendingEdgeConveyanceRow>* pending_ec = nullptr;
924 std::vector<twoD::PendingInitialQualityRow>* pending_iq = nullptr;
925 std::vector<twoD::PendingBoundaryQualityRow>* pending_bq = nullptr;
944 std::vector<std::string>* aquifer_nodes = nullptr;
952
968 std::vector<std::pair<std::string, std::string>> deferred_section_rows;
969
970 // =========================================================================
971 // Error / warning tracking
972 // =========================================================================
973
978 int error_code = 0;
979
985
989 std::string error_message;
990
998 std::vector<std::string> warnings;
999
1007 std::vector<std::string> errors;
1008
1020 std::vector<std::uint8_t> coupled_node;
1021
1036
1037 // =========================================================================
1038 // Mass balance accumulators (SoA — vectorisable batch updates)
1039 // =========================================================================
1040
1051 // Runoff totals
1052 double runoff_rainfall = 0.0;
1053 double runoff_runon = 0.0;
1054 double runoff_evap = 0.0;
1055 double runoff_infil = 0.0;
1056 double runoff_runoff = 0.0;
1057 double runoff_lid_drain = 0.0;
1058 double runoff_snowremov = 0.0;
1059 double runoff_init_store = 0.0;
1064 double runoff_init_snow = 0.0;
1074 double runoff_final_snow = 0.0;
1075
1076 // Routing totals
1079 double routing_gw_inflow = 0.0;
1080 double routing_rdii = 0.0;
1081 double routing_external = 0.0;
1082 double routing_flooding = 0.0;
1099 double routing_outflow = 0.0;
1100 double routing_evap_loss = 0.0;
1101 double routing_seep_loss = 0.0;
1104
1105 // User-forced volumes (diagnostic — subset of routing_external)
1107
1108 // User-forced quality mass (diagnostic — cumulative mass injected via user_conc_mass_flux)
1109 std::vector<double> routing_forcing_qual_inflow;
1110
1111 // Groundwater mass balance totals (all in feet — depth per unit area)
1112 // Matches legacy TGwaterTotals
1113 double gw_infil = 0.0;
1114 double gw_upper_evap = 0.0;
1115 double gw_lower_evap = 0.0;
1116 double gw_lower_perc = 0.0;
1117 double gw_lateral_flow = 0.0;
1118 double gw_init_storage = 0.0;
1119 double gw_final_storage = 0.0;
1128
1129 // Per-step accumulators (reset each step for reporting)
1130 double step_flooding = 0.0;
1131 double step_outflow = 0.0;
1132 double step_dw_inflow = 0.0;
1133 double step_gw_inflow = 0.0;
1134 double step_rdii_inflow = 0.0;
1135 double step_ext_inflow = 0.0;
1136
1137 // Quality mass balance (per-pollutant, in mass units)
1138 std::vector<double> qual_init_buildup;
1139 std::vector<double> qual_final_buildup;
1140 std::vector<double> qual_surface_buildup;
1141 std::vector<double> qual_wet_deposition;
1142 std::vector<double> qual_sweeping;
1143 std::vector<double> qual_bmp_removal;
1144 std::vector<double> qual_infil_loss;
1145 std::vector<double> qual_runoff_load;
1146 std::vector<double> qual_routing_wet;
1147 std::vector<double> qual_routing_outflow;
1148 std::vector<double> qual_routing_flood;
1149 std::vector<double> qual_routing_init;
1150 std::vector<double> qual_routing_final;
1151 std::vector<double> qual_routing_reacted;
1152 std::vector<double> qual_routing_ii_in;
1153 std::vector<double> qual_routing_dw_in;
1154 std::vector<double> qual_routing_gw_in;
1155 std::vector<double> qual_routing_ex_in;
1156 std::vector<double> qual_routing_seep;
1157 std::vector<double> qual_routing_evap;
1158
1160 auto np = static_cast<std::size_t>(n_pollutants);
1161 qual_init_buildup.assign(np, 0.0);
1162 qual_final_buildup.assign(np, 0.0);
1163 qual_surface_buildup.assign(np, 0.0);
1164 qual_wet_deposition.assign(np, 0.0);
1165 qual_sweeping.assign(np, 0.0);
1166 qual_bmp_removal.assign(np, 0.0);
1167 qual_infil_loss.assign(np, 0.0);
1168 qual_runoff_load.assign(np, 0.0);
1169 qual_routing_wet.assign(np, 0.0);
1170 qual_routing_outflow.assign(np, 0.0);
1171 qual_routing_flood.assign(np, 0.0);
1172 qual_routing_init.assign(np, 0.0);
1173 qual_routing_final.assign(np, 0.0);
1174 qual_routing_reacted.assign(np, 0.0);
1175 qual_routing_ii_in.assign(np, 0.0);
1176 qual_routing_dw_in.assign(np, 0.0);
1177 qual_routing_gw_in.assign(np, 0.0);
1178 qual_routing_ex_in.assign(np, 0.0);
1179 qual_routing_seep.assign(np, 0.0);
1180 qual_routing_evap.assign(np, 0.0);
1181 routing_forcing_qual_inflow.assign(np, 0.0);
1182 }
1183
1184 void reset() {
1185 // Save quality vectors, reset scalars, restore vectors
1186 auto qi = std::move(qual_init_buildup);
1187 auto qf = std::move(qual_final_buildup);
1188 auto qsb = std::move(qual_surface_buildup);
1189 auto qwd = std::move(qual_wet_deposition);
1190 auto qsw = std::move(qual_sweeping);
1191 auto qbmp = std::move(qual_bmp_removal);
1192 auto qil = std::move(qual_infil_loss);
1193 auto qrl = std::move(qual_runoff_load);
1194 auto qrw = std::move(qual_routing_wet);
1195 auto qro = std::move(qual_routing_outflow);
1196 auto qrf = std::move(qual_routing_flood);
1197 auto qri = std::move(qual_routing_init);
1198 auto qrfi = std::move(qual_routing_final);
1199 auto qrr = std::move(qual_routing_reacted);
1200 auto qrii = std::move(qual_routing_ii_in);
1201 auto qrdw = std::move(qual_routing_dw_in);
1202 auto qrgw = std::move(qual_routing_gw_in);
1203 auto qrex = std::move(qual_routing_ex_in);
1204 auto qrseep = std::move(qual_routing_seep);
1205 auto qrevap = std::move(qual_routing_evap);
1206 auto qrfqi = std::move(routing_forcing_qual_inflow);
1207 *this = MassBalance{};
1208 qual_init_buildup = std::move(qi);
1209 qual_final_buildup = std::move(qf);
1210 qual_surface_buildup = std::move(qsb);
1211 qual_wet_deposition = std::move(qwd);
1212 qual_sweeping = std::move(qsw);
1213 qual_bmp_removal = std::move(qbmp);
1214 qual_infil_loss = std::move(qil);
1215 qual_runoff_load = std::move(qrl);
1216 qual_routing_wet = std::move(qrw);
1217 qual_routing_outflow = std::move(qro);
1218 qual_routing_flood = std::move(qrf);
1219 qual_routing_init = std::move(qri);
1220 qual_routing_final = std::move(qrfi);
1221 qual_routing_reacted = std::move(qrr);
1222 qual_routing_ii_in = std::move(qrii);
1223 qual_routing_dw_in = std::move(qrdw);
1224 qual_routing_gw_in = std::move(qrgw);
1225 qual_routing_ex_in = std::move(qrex);
1226 qual_routing_seep = std::move(qrseep);
1227 qual_routing_evap = std::move(qrevap);
1228 routing_forcing_qual_inflow = std::move(qrfqi);
1229 // Zero out the quality vectors (except init_buildup which is
1230 // computed once during initQuality and must survive reset)
1231 for (auto* v : {&qual_final_buildup,
1245 std::fill(v->begin(), v->end(), 0.0);
1246 }
1247 }
1248
1250 double runoff_error() const {
1251 // Snow is a STORE on both sides, and snow ploughed out of the
1252 // system is a loss — matching legacy massbal.c:685-692. A pack
1253 // present at the start is water the model was given; a pack still
1254 // standing at the end is water it still holds.
1255 double total_in = runoff_rainfall + runoff_runon + runoff_init_store +
1257 double total_out = runoff_evap + runoff_infil + runoff_runoff +
1261 return (total_in > 0.0) ? (total_in - total_out) / total_in : 0.0;
1262 }
1263
1265 double routing_error() const {
1266 double total_in = routing_dry_weather + routing_wet_weather +
1269 double total_out = routing_flooding + routing_coupling_out +
1273 return (total_in > 0.0) ? (total_in - total_out) / total_in : 0.0;
1274 }
1275
1277 double gw_error() const {
1278 double total_in = gw_infil + gw_init_storage;
1279 double total_out = gw_upper_evap + gw_lower_evap + gw_lower_perc +
1281 return (total_in > 0.0) ? (total_in - total_out) / total_in : 0.0;
1282 }
1284
1309
1321 double init_storage = 0.0;
1322 double final_storage = 0.0;
1323 double rainfall_in = 0.0;
1326 double outfall_in = 0.0;
1327 double outfall_out = 0.0;
1328 double boundary_in = 0.0;
1329 double boundary_out = 0.0;
1330 double evap_out = 0.0;
1335 double infil_out = 0.0;
1342 double infil_to_aquifer = 0.0;
1350 double aquifer_in = 0.0;
1351 bool active = false;
1352
1353 // Cumulative marcher statistics (published by SurfaceRouter2D at
1354 // finalize from ISurfaceSolver::run_stats). Printed as the "2D Solver
1355 // Statistics" report block. -1 = not populated.
1356 long solver_nsteps = -1;
1357 long solver_nrhs = 0;
1358 double solver_avg_h = 0.0;
1359 double solver_last_h = 0.0;
1360
1361 // Marcher telemetry (guarded by n_tiers > 0 / non-negative fractions).
1362 double solver_active_min = -1.0;
1363 double solver_active_mean = -1.0;
1364 double solver_active_max = -1.0;
1365 long solver_tier_cells[8] = {0};
1367
1369 double error() const {
1370 double total_in = rainfall_in + coupling_1d_to_2d_in + outfall_in
1372 double total_out = coupling_2d_to_1d_out + outfall_out + boundary_out
1374 return (total_in > 0.0) ? (total_in - total_out) / total_in : 0.0;
1375 }
1377
1378 // =========================================================================
1379 // Routing time-step statistics
1380 // =========================================================================
1381
1383 struct MaxStats {
1384 int obj_type = -1;
1385 int index = -1;
1386 double value = 0.0;
1387 };
1388
1389 static constexpr int MAX_STATS = 5;
1390
1399
1401 double min_step = 1.0e30;
1402 double max_step = 0.0;
1403 double sum_step = 0.0;
1404 long n_steps = 0;
1405 double steady_pct = 0.0;
1406
1408 static constexpr int N_TIME_BINS = 5;
1409 long step_counts[N_TIME_BINS + 1] = {};
1410 double step_intervals[N_TIME_BINS + 1] = {};
1411
1414 double sum_iterations = 0.0;
1415 double max_courant = 0.0;
1416
1417 void update(double dt) {
1418 min_step = std::min(min_step, dt);
1419 max_step = std::max(max_step, dt);
1420 sum_step += dt;
1421 ++n_steps;
1422 }
1423
1425 void update_iterations(int iters, bool converged) {
1426 sum_iterations += iters;
1427 if (!converged) ++n_non_converged;
1428 }
1429
1433 void init_histogram(double route_step, double min_route_step) {
1434 if (route_step <= 0.0) return;
1435 if (min_route_step <= 0.0) min_route_step = route_step;
1436 double log_hi = std::log10(route_step);
1437 double log_lo = std::log10(min_route_step);
1438 double delta = (log_hi - log_lo) / static_cast<double>(N_TIME_BINS);
1439 step_intervals[0] = route_step;
1440 for (int i = 1; i <= N_TIME_BINS; ++i)
1441 step_intervals[i] = std::pow(10.0, log_hi - i * delta);
1442 step_intervals[N_TIME_BINS] = min_route_step;
1443 }
1444
1448 if (n_steps == 0 || max_step <= 0.0) return;
1449 double hi = max_step;
1450 double lo = (min_step < 1.0e30) ? min_step : 0.0;
1451 if (lo <= 0.0) lo = hi;
1452 init_histogram(hi, lo);
1453 }
1454
1456 void record_step_bin(double dt) {
1457 for (int i = 0; i < N_TIME_BINS; ++i) {
1458 if (dt >= step_intervals[i+1]) {
1459 step_counts[i]++;
1460 return;
1461 }
1462 }
1463 step_counts[N_TIME_BINS - 1]++;
1464 }
1465
1466 double avg_step() const {
1467 return (n_steps > 0) ? sum_step / static_cast<double>(n_steps) : 0.0;
1468 }
1469
1470 double pct_non_converged() const {
1471 return (n_steps > 0) ? 100.0 * static_cast<double>(n_non_converged) / static_cast<double>(n_steps) : 0.0;
1472 }
1473
1475 return (n_steps > 0) ? sum_iterations / static_cast<double>(n_steps) : 0.0;
1476 }
1477
1478 // ---------------------------------------------------------------
1479 // FV 1D solver statistics (published by SWMMEngine::end() from
1480 // INetworkSolver::run_stats, printed as the "FV Solver Statistics"
1481 // report block). The 1D counterpart of mass_balance_2d.solver_*.
1482 //
1483 // -1 = not populated: the run was not FLOW_ROUTING FV, or a backend
1484 // that carries no counters was selected. The report block is skipped
1485 // on the sentinel rather than printing a row of zeros, which would
1486 // read as "the solver did nothing" instead of "nobody counted".
1487 // ---------------------------------------------------------------
1488 // Slot-storage share (FV slot program R0). Peak instantaneous
1489 // system share slot/stored and the time that share exceeded 1 %;
1490 // the run-level integrated share is Σ links.stat_slot_vol_dt /
1491 // Σ links.stat_vol_dt, summed at report time. 0 under DW.
1492 double slot_peak_share = 0.0;
1493 double slot_time_above_s = 0.0;
1494
1495 long fv_nsteps = -1;
1496 long fv_nflux = 0;
1497 double fv_avg_h = 0.0;
1498 double fv_last_h = 0.0;
1499 double fv_min_h = 0.0;
1500 double fv_active_min = -1.0;
1501 double fv_active_mean = -1.0;
1502 double fv_active_max = -1.0;
1503 long fv_tier_cells[8] = {0};
1504 int fv_n_tiers = 0;
1505
1506 // dt-argmin attribution (slot program R0): who owned the binding
1507 // CFL element, counted per census / re-tier.
1513
1514 // =========================================================================
1515 // Virtual-junction diagnostics (refactored engine only)
1516 // =========================================================================
1517
1526 struct VJDiag {
1527 std::vector<int> node_idx;
1528 std::vector<int> up_link;
1529 std::vector<int> dn_link;
1530 std::vector<double> resid_max;
1531 std::vector<double> resid_sum;
1532 std::vector<long long> resid_n;
1533 void clear() {
1534 node_idx.clear(); up_link.clear(); dn_link.clear();
1535 resid_max.clear(); resid_sum.clear(); resid_n.clear();
1536 }
1538
1539 // =========================================================================
1540 // Street inlet performance diagnostics
1541 // =========================================================================
1542
1553 struct InletDiag {
1554 std::vector<int> host_node;
1555 std::vector<int> up_link;
1556 std::vector<uint8_t> is_sag;
1557 std::vector<int> num_inlets;
1558 std::vector<int> flow_periods;
1559 std::vector<int> capture_periods;
1560 std::vector<int> backflow_periods;
1561 std::vector<double> peak_flow;
1562 std::vector<double> peak_flow_capture;
1563 std::vector<double> avg_flow_capture;
1564 std::vector<double> bypass_freq;
1565
1566 int count() const { return static_cast<int>(host_node.size()); }
1567
1568 void resize(int n) {
1569 auto un = static_cast<std::size_t>(n);
1570 host_node.assign(un, -1);
1571 up_link.assign(un, -1);
1572 is_sag.assign(un, static_cast<uint8_t>(0));
1573 num_inlets.assign(un, 1);
1574 flow_periods.assign(un, 0);
1575 capture_periods.assign(un, 0);
1576 backflow_periods.assign(un, 0);
1577 peak_flow.assign(un, 0.0);
1578 peak_flow_capture.assign(un, 0.0);
1579 avg_flow_capture.assign(un, 0.0);
1580 bypass_freq.assign(un, 0.0);
1581 }
1582
1583 void clear() {
1584 host_node.clear(); up_link.clear(); is_sag.clear(); num_inlets.clear();
1585 flow_periods.clear(); capture_periods.clear(); backflow_periods.clear();
1586 peak_flow.clear(); peak_flow_capture.clear(); avg_flow_capture.clear();
1587 bypass_freq.clear();
1588 }
1590
1591 // =========================================================================
1592 // Control action log — Gap #67
1593 // Populated by ControlEngine::applyPendingActions() when rpt_controls is on.
1594 // =========================================================================
1595
1599 std::string rule_name;
1601 double date;
1602 };
1603
1605 std::vector<ControlLogEntry> control_log;
1606
1607 // =========================================================================
1608 // Input file path (for model write / hot start)
1609 // =========================================================================
1610
1615 std::string inp_file_path;
1616
1617 // =========================================================================
1618 // Context-level operations
1619 // =========================================================================
1620
1625 static void updateMaxStats(MaxStats arr[], int obj_type, int idx, double value) {
1626 MaxStats candidate;
1627 candidate.obj_type = obj_type;
1628 candidate.index = idx;
1629 candidate.value = value;
1630 for (int k = 0; k < MAX_STATS; ++k) {
1631 if (std::fabs(candidate.value) > std::fabs(arr[k].value)) {
1632 MaxStats tmp = arr[k];
1633 arr[k] = candidate;
1634 candidate = tmp;
1635 }
1636 }
1637 }
1638
1645 long step_count = routing_stats.n_steps;
1646 if (step_count <= 0) return;
1647 double inv_steps = 1.0 / static_cast<double>(step_count);
1648
1649 // CFL-critical elements: percentage of steps each element was critical
1650 for (int j = 0; j < n_nodes(); ++j) {
1651 double x = nodes.stat_time_courant_critical[static_cast<std::size_t>(j)] * inv_steps;
1652 updateMaxStats(max_courant_crit, 0, j, 100.0 * x);
1653 }
1654 for (int j = 0; j < n_links(); ++j) {
1655 double x = links.stat_time_courant_critical[static_cast<std::size_t>(j)] * inv_steps;
1656 updateMaxStats(max_courant_crit, 1, j, 100.0 * x);
1657 }
1658
1659 // Flow instability index (matching legacy normalization)
1660 long rpt_steps = routing_stats.n_steps;
1661 if (rpt_steps > 2) {
1662 double z = 100.0 / (2.0 / 3.0 * static_cast<double>(rpt_steps - 2));
1663 for (int j = 0; j < n_links(); ++j) {
1664 double x = static_cast<double>(links.stat_flow_turns[static_cast<std::size_t>(j)]) * z;
1666 }
1667 }
1668
1669 // Non-convergence: fraction of total steps each node failed to converge
1670 for (int j = 0; j < n_nodes(); ++j) {
1671 double x = static_cast<double>(nodes.stat_non_converged_count[static_cast<std::size_t>(j)]) * inv_steps;
1673 }
1674 }
1675
1683 void reset() {
1685 control_log.clear();
1686 current_time = 0.0;
1687 current_date = 0.0;
1689 elapsed_ms = 0.0;
1690 old_elapsed_ms = 0.0;
1691 next_report_ms = 0.0;
1692 error_code = 0;
1693 warning_code = 0;
1694 error_message.clear();
1695 warnings.clear();
1696 errors.clear();
1697 title_notes.clear();
1698 deferred_section_rows.clear();
1699 pending_gw_nodes.clear();
1700 pending_link_nodes.clear();
1701
1702 // Clear SoA stores
1703 nodes = NodeData{};
1704 links = LinkData{};
1706 gages = GageData{};
1708 tables = TableData{};
1709
1710 // Clear name indices
1711 node_names.clear();
1712 link_names.clear();
1713 subcatch_names.clear();
1714 gage_names.clear();
1715 pollutant_names.clear();
1716
1717 // Clear inflow-related stores that aren't reset by their owning solvers
1719
1720 // E3: transport.ard component config — its apply hook resets it, but
1721 // a reopen WITHOUT the component would otherwise inherit the previous
1722 // model's dispersion.
1724
1725 // A1a: same stale-on-reopen hygiene for water age.
1727 water_age_state.clear();
1728
1729 // H1: and for heat.
1731 heat_state.clear();
1732 lid_layer_state.clear();
1733 bed_state.clear(); // H6b
1734
1735 // Virtual-junction diagnostics
1736 vj_diag.clear();
1737 inlet_diag.clear();
1738
1739 // Clear daily climate state (re-initialized by SWMMEngine on next run)
1741
1742 // Clear spatial, flags, events, and forcing. Per-object tags
1743 // are owned by NodeData/LinkData/SubcatchData and cleared when
1744 // those SoAs are resized/cleared by the wider reset path.
1746 user_flags.clear();
1747 events.clear();
1748 std::fill(std::begin(adjust_temp), std::end(adjust_temp), 0.0);
1749 std::fill(std::begin(adjust_evap), std::end(adjust_evap), 1.0);
1750 std::fill(std::begin(adjust_rain), std::end(adjust_rain), 1.0);
1751 std::fill(std::begin(adjust_hydcon), std::end(adjust_hydcon), 1.0);
1754 subcatch_infil_pattern.clear();
1755 base_n_perv.clear();
1756 base_ds_perv.clear();
1758 forcing = ForcingData{};
1759 }
1760
1767 void save_state() noexcept {
1768 nodes.save_state();
1769 links.save_state();
1770 // NOTE: subcatches.save_state() is intentionally NOT called here.
1771 // Subcatchment old-state (old_runoff/old_runon/conc_old) is the
1772 // runoff-step snapshot used to linearly interpolate lateral inflow
1773 // between runoff evaluations (legacy subcatch_setOldState, called
1774 // ONLY inside runoff_execute — i.e. per WET/DRY step, not per routing
1775 // step). Saving it here, every routing step, clobbered old_runoff with
1776 // the current value so old==new and the lateral inflow jumped to the
1777 // full new runoff instantly instead of ramping. It is now saved in the
1778 // runoff-advance loop in SWMMEngine::stepRunoff().
1779 }
1780
1787 void reset_state() noexcept {
1788 nodes.reset_state();
1789 links.reset_state();
1790 subcatches.reset_state();
1791 gages.reset_state();
1792 tables.reset_cursors();
1793 current_time = 0.0;
1794 current_date = options.start_date;
1796 elapsed_ms = 0.0;
1797 old_elapsed_ms = 0.0;
1798 // Legacy swmm5.c:721 — ReportTime = 1000 * ReportStep (ms from SIM start)
1799 next_report_ms = 1000.0 * options.report_step;
1800 }
1801
1813 nodes.resize(node_names.size());
1814 links.resize(link_names.size());
1815 subcatches.resize(subcatch_names.size());
1816 gages.resize(gage_names.size());
1817 pollutants.resize_pollutants(pollutant_names.size());
1818 int np = static_cast<int>(pollutant_names.size());
1819 nodes.resize_quality(np);
1820 links.resize_quality(np);
1821 subcatches.resize_quality(np);
1822
1823 // Resize spatial coordinate arrays
1824 spatial.node_x.assign(static_cast<std::size_t>(node_names.size()), 0.0);
1825 spatial.node_y.assign(static_cast<std::size_t>(node_names.size()), 0.0);
1826 spatial.link_x.assign(static_cast<std::size_t>(link_names.size()), 0.0);
1827 spatial.link_y.assign(static_cast<std::size_t>(link_names.size()), 0.0);
1828 spatial.subcatch_x.assign(static_cast<std::size_t>(subcatch_names.size()), 0.0);
1829 spatial.subcatch_y.assign(static_cast<std::size_t>(subcatch_names.size()), 0.0);
1830
1831 // Resize link vertex and subcatchment polygon arrays
1832 spatial.link_vertices_x.resize(static_cast<std::size_t>(link_names.size()));
1833 spatial.link_vertices_y.resize(static_cast<std::size_t>(link_names.size()));
1834 spatial.subcatch_polygon_x.resize(static_cast<std::size_t>(subcatch_names.size()));
1835 spatial.subcatch_polygon_y.resize(static_cast<std::size_t>(subcatch_names.size()));
1836
1837 // Resize gage coordinates
1838 spatial.gage_x.assign(static_cast<std::size_t>(gage_names.size()), 0.0);
1839 spatial.gage_y.assign(static_cast<std::size_t>(gage_names.size()), 0.0);
1840 }
1841
1851 nodes.shrink_to_fit();
1852 links.shrink_to_fit();
1853 subcatches.shrink_to_fit();
1854 gages.shrink_to_fit();
1855 pollutants.shrink_to_fit();
1856 landuses.shrink_to_fit();
1857 buildup.shrink_to_fit();
1858 washoff.shrink_to_fit();
1859 treatment.shrink_to_fit();
1860 spatial.shrink_to_fit();
1861 }
1862
1863 // =========================================================================
1864 // Convenience accessors
1865 // =========================================================================
1866
1868 int n_nodes() const noexcept { return node_names.size(); }
1869
1871 int n_links() const noexcept { return link_names.size(); }
1872
1874 int n_subcatches() const noexcept { return subcatch_names.size(); }
1875
1877 int n_gages() const noexcept { return gage_names.size(); }
1878
1880 int n_pollutants() const noexcept { return pollutant_names.size(); }
1881 int n_landuses() const noexcept { return landuse_names.size(); }
1882
1884 int n_tables() const noexcept { return static_cast<int>(tables.count()); }
1885
1886 // =========================================================================
1887 // Kind-aware table lookups (case-insensitive, legacy hash.c parity).
1888 // Legacy keeps TSERIES and CURVE in separate hash tables, so the same
1889 // name may denote both a curve and a timeseries; every consumer knows
1890 // which kind it wants.
1891 // =========================================================================
1892
1898 int find_timeseries(std::string_view name) const noexcept {
1899 return tables.find_by_kind(name, /*want_timeseries=*/true);
1900 }
1901
1903 int find_curve(std::string_view name) const noexcept {
1904 return tables.find_by_kind(name, /*want_timeseries=*/false);
1905 }
1906
1913 int find_table_any(std::string_view name) const noexcept {
1914 const int ts = find_timeseries(name);
1915 if (ts >= 0) return ts;
1916 return find_curve(name);
1917 }
1918};
1919
1920} /* namespace openswmm */
1921
1922#endif /* OPENSWMM_ENGINE_SIMULATION_CONTEXT_HPP */
Parsed configuration of the Eulerian ARD transport component (org.hydrocouple.openswmm....
Plan H6b — the bed / hyporheic transient-storage zone.
Climate processing — evaporation, temperature, wind.
Carrier for an external file reference in a SWMM model.
Per-element runtime forcing state — SoA layout.
Structure-of-Arrays (SoA) storage for rain gages.
Heat-transport data (heat plan §1, §3; phase H1).
SoA stores for snowpacks, aquifers, LID controls, and LID usage.
SoA stores for external inflows, DWF, RDII, and time patterns.
SoA stores for transects, streets, inlets, and control rules.
SoA store for [INITIAL_QUALITY] per-element initial concentrations.
Phase A4 — per-(LID unit, layer, species) transported state.
O(1) name-to-index lookup for SWMM objects.
Structure-of-Arrays (SoA) storage for all node types.
Relational (normalized) Structure-of-Arrays side-tables for node subtypes.
Structure-of-Arrays (SoA) storage for pollutants and water quality.
SoA stores for land uses, buildup, washoff, and treatment.
Multispecies reaction system data (EPANET-MSX conventions) — SoA, hot/cold split per LARD plan §16 D-...
Simulation options parsed from the [OPTIONS] section.
Spatial frame — CRS specification and coordinate data for nodes/links.
Single source of truth for all transported constituents (Unified Transport master plan §4....
Structure-of-Arrays (SoA) storage for subcatchments.
Time series and rating curve data with bidirectional cursor.
Irregular transect cross-section geometry (HEC-2 style).
User-defined model flags (InfoWorks ICM-style, two-section design).
Water-age tracking data (water age plan §1–§2, phase A1a).
Bidirectional name↔index registry for SWMM objects.
Definition NameIndex.hpp:71
Definition SpeciesRegistry.hpp:61
Stores the full user-flags data: schema definitions + per-object values.
Definition UserFlags.hpp:145
Owns per-cell infiltration parameters, kernel state and held rates.
Definition Infil2D.hpp:181
FileMode
Mode keyword for one [FILES] row — SAVE or USE.
Definition SimulationContext.hpp:179
EngineState
High-level engine lifecycle state.
Definition SimulationContext.hpp:261
@ USE
Definition SimulationContext.hpp:182
@ NONE
Definition SimulationContext.hpp:180
@ SAVE
Definition SimulationContext.hpp:181
@ CLOSED
Resources released.
Definition SimulationContext.hpp:269
@ ENDED
Simulation loop completed.
Definition SimulationContext.hpp:267
@ ERROR_STATE
Fatal error; call swmm_engine_last_error()
Definition SimulationContext.hpp:270
@ RUNNING
Simulation loop in progress.
Definition SimulationContext.hpp:265
@ REPORTED
Summary report written.
Definition SimulationContext.hpp:268
@ BUILDING
Programmatic model construction in progress (no .inp)
Definition SimulationContext.hpp:271
@ CREATED
Context allocated, no input loaded.
Definition SimulationContext.hpp:262
@ PAUSED
Simulation paused (future hot-swap support)
Definition SimulationContext.hpp:266
@ INITIALIZED
Initial conditions applied.
Definition SimulationContext.hpp:264
@ OPENED
Input file parsed, objects allocated.
Definition SimulationContext.hpp:263
Definition Infiltration.cpp:34
Definition NodeCoupling.cpp:16
SoA storage for aquifer parameter sets.
Definition HydrologyData.hpp:84
Parsed model.ard state consumed by ArdEngine::init (phase E3).
Definition ArdConfigData.hpp:97
Runtime bed state, one entry per LINK.
Definition BedZoneData.hpp:164
Definition QualityData.hpp:79
Definition InfraData.hpp:249
Definition InflowData.hpp:90
Definition InflowData.hpp:46
Two-string carrier for any external file path that appears in a SWMM .inp file.
Definition FilePathPair.hpp:63
Definition SimulationContext.hpp:212
FileMode runoff_mode
Definition SimulationContext.hpp:216
FilePathPair hotstart_use_path
Legacy semantics: USE — single hot-start input file.
Definition SimulationContext.hpp:229
FilePathPair rainfall_path
Definition SimulationContext.hpp:214
FileMode rainfall_mode
Definition SimulationContext.hpp:213
FilePathPair outflows_path
Legacy semantics: SAVE only.
Definition SimulationContext.hpp:226
FilePathPair runoff_path
Definition SimulationContext.hpp:217
std::vector< HotstartSaveEntry > hotstart_saves
Definition SimulationContext.hpp:234
bool has_any() const noexcept
Definition SimulationContext.hpp:238
FilePathPair rdii_path
Definition SimulationContext.hpp:220
FilePathPair inflows_path
Legacy semantics: USE only.
Definition SimulationContext.hpp:223
FileMode rdii_mode
Definition SimulationContext.hpp:219
Definition ForcingData.hpp:70
Structure-of-Arrays storage for all rain gages.
Definition GageData.hpp:95
Parsed model.heat state (heat component, phase H1).
Definition HeatData.hpp:318
Runtime heat state shared by the engines (phase H1).
Definition HeatData.hpp:413
Configuration parsed from the [FILES] section.
Definition SimulationContext.hpp:205
double datetime
Definition SimulationContext.hpp:209
FilePathPair path
Definition SimulationContext.hpp:206
Definition InitialQualityData.hpp:47
Definition InfraData.hpp:103
Definition InfraData.hpp:168
Definition QualityData.hpp:45
SoA storage for LID control type definitions.
Definition HydrologyData.hpp:117
Per-(unit, layer, species) state for every LID unit in the model.
Definition LidLayerSpeciesData.hpp:77
SoA storage for LID usage assignments to subcatchments.
Definition HydrologyData.hpp:158
Structure-of-Arrays storage for all nodes.
Definition NodeData.hpp:130
Owns the three node subtype side-tables plus the reverse index map.
Definition NodeSubtypes.hpp:373
Definition InflowData.hpp:235
One plugin entry from the [PLUGINS] section.
Definition SimulationContext.hpp:132
std::string path
Shared library path.
Definition SimulationContext.hpp:133
std::vector< std::string > init_args
Extra tokens from the [PLUGINS] row.
Definition SimulationContext.hpp:134
Static properties for each pollutant species.
Definition PollutantData.hpp:71
One row of [PROCESS_COMPONENTS] (Unified Transport suite, D-UT8).
Definition SimulationContext.hpp:154
std::string config_path
config="…" argument (may be empty)
Definition SimulationContext.hpp:156
std::vector< std::pair< std::string, std::string > > args
other key/value args
Definition SimulationContext.hpp:157
std::string id
Component id (or library path — HC2)
Definition SimulationContext.hpp:155
std::string resolved_config_path
Definition SimulationContext.hpp:163
Definition InflowData.hpp:131
Definition InflowData.hpp:223
Definition ReactionData.hpp:56
double new_setting
The new target setting value (0-1)
Definition SimulationContext.hpp:1600
std::string rule_name
Name of the rule that triggered the change.
Definition SimulationContext.hpp:1599
double date
OADate when the change occurred.
Definition SimulationContext.hpp:1601
int link_idx
Index of the link whose setting changed.
Definition SimulationContext.hpp:1598
double end
Event end (DateTime decimal days)
Definition SimulationContext.hpp:739
double start
Event start (DateTime decimal days)
Definition SimulationContext.hpp:738
std::vector< int > num_inlets
Definition SimulationContext.hpp:1557
void resize(int n)
Definition SimulationContext.hpp:1568
std::vector< int > host_node
inlet-junction node (−1 = conduit host)
Definition SimulationContext.hpp:1554
std::vector< int > backflow_periods
Definition SimulationContext.hpp:1560
std::vector< int > up_link
approach conduit (−1 = none)
Definition SimulationContext.hpp:1555
std::vector< int > flow_periods
Definition SimulationContext.hpp:1558
std::vector< int > capture_periods
Definition SimulationContext.hpp:1559
std::vector< double > peak_flow
peak approach flow (cfs)
Definition SimulationContext.hpp:1561
std::vector< double > avg_flow_capture
Σ capture efficiency over capture periods.
Definition SimulationContext.hpp:1563
int count() const
Definition SimulationContext.hpp:1566
std::vector< uint8_t > is_sag
resolved placement: 1 = ON_SAG
Definition SimulationContext.hpp:1556
void clear()
Definition SimulationContext.hpp:1583
std::vector< double > peak_flow_capture
capture efficiency at peak flow (%)
Definition SimulationContext.hpp:1562
std::vector< double > bypass_freq
Definition SimulationContext.hpp:1564
double boundary_in
Cumulative boundary inflow (m³)
Definition SimulationContext.hpp:1328
double solver_active_max
max active-cell fraction
Definition SimulationContext.hpp:1364
double evap_out
Definition SimulationContext.hpp:1330
double outfall_in
Cumulative 1D outfall discharge into 2D (m³)
Definition SimulationContext.hpp:1326
double boundary_out
Cumulative boundary outflow (m³)
Definition SimulationContext.hpp:1329
double coupling_2d_to_1d_out
Cumulative 2D→1D drainage out (m³)
Definition SimulationContext.hpp:1325
double solver_avg_h
mean accepted internal step (s)
Definition SimulationContext.hpp:1358
long solver_tier_cells[8]
cumulative cells per LTS tier
Definition SimulationContext.hpp:1365
double solver_active_mean
mean active-cell fraction
Definition SimulationContext.hpp:1363
double final_storage
Latest surface storage (m³)
Definition SimulationContext.hpp:1322
double init_storage
Initial surface storage (m³)
Definition SimulationContext.hpp:1321
double solver_active_min
min active-cell fraction
Definition SimulationContext.hpp:1362
double solver_last_h
last accepted internal step (s)
Definition SimulationContext.hpp:1359
double infil_to_aquifer
Definition SimulationContext.hpp:1342
double error() const
2D surface continuity error (fraction).
Definition SimulationContext.hpp:1369
double outfall_out
Cumulative 2D→pipe withdrawal at submerged outfalls (m³)
Definition SimulationContext.hpp:1327
double aquifer_in
Definition SimulationContext.hpp:1350
long solver_nsteps
internal (marcher) substeps
Definition SimulationContext.hpp:1356
long solver_nrhs
face-kernel evaluations
Definition SimulationContext.hpp:1357
int solver_n_tiers
populated tier count
Definition SimulationContext.hpp:1366
double infil_out
Definition SimulationContext.hpp:1335
bool active
True if the 2D module ran.
Definition SimulationContext.hpp:1351
double rainfall_in
Cumulative rainfall volume (m³)
Definition SimulationContext.hpp:1323
double coupling_1d_to_2d_in
Cumulative 1D→2D spill into 2D (m³)
Definition SimulationContext.hpp:1324
Cumulative mass balance totals for runoff and routing.
Definition SimulationContext.hpp:1050
double routing_rdii
Definition SimulationContext.hpp:1080
std::vector< double > qual_routing_ex_in
External (interface file) quality mass inflow.
Definition SimulationContext.hpp:1155
double gw_infil
Cumulative infiltration to GW (ft)
Definition SimulationContext.hpp:1113
double routing_gw_inflow
Definition SimulationContext.hpp:1079
double runoff_runon
Outfall-routed runon volume (ft3), legacy RUNOFF_RUNON.
Definition SimulationContext.hpp:1053
double routing_init_storage
Definition SimulationContext.hpp:1102
double routing_evap_loss
Definition SimulationContext.hpp:1100
std::vector< double > qual_surface_buildup
Accumulated buildup during sim.
Definition SimulationContext.hpp:1140
double routing_dry_weather
Definition SimulationContext.hpp:1077
std::vector< double > qual_routing_final
Final stored quality mass.
Definition SimulationContext.hpp:1150
double runoff_runoff
Total surface runoff volume (ft3)
Definition SimulationContext.hpp:1056
std::vector< double > qual_init_buildup
Initial buildup mass.
Definition SimulationContext.hpp:1138
std::vector< double > qual_routing_init
Initial stored quality mass.
Definition SimulationContext.hpp:1149
std::vector< double > qual_runoff_load
Mass load in surface runoff.
Definition SimulationContext.hpp:1145
std::vector< double > qual_final_buildup
Final buildup mass.
Definition SimulationContext.hpp:1139
double routing_final_storage
Definition SimulationContext.hpp:1103
double runoff_init_store
Initial surface storage (ft3)
Definition SimulationContext.hpp:1059
double gw_lower_perc
Cumulative deep percolation (ft)
Definition SimulationContext.hpp:1116
double gw_infil_2d_recharge
Definition SimulationContext.hpp:1127
double routing_seep_loss
Definition SimulationContext.hpp:1101
std::vector< double > qual_routing_flood
Quality mass lost to flooding.
Definition SimulationContext.hpp:1148
double runoff_snowremov
Total snow removal volume (ft3)
Definition SimulationContext.hpp:1058
std::vector< double > qual_routing_dw_in
Dry weather quality mass inflow.
Definition SimulationContext.hpp:1153
double gw_upper_evap
Cumulative upper zone evaporation (ft)
Definition SimulationContext.hpp:1114
double routing_external
Definition SimulationContext.hpp:1081
std::vector< double > qual_infil_loss
Mass lost to infiltration.
Definition SimulationContext.hpp:1144
double runoff_final_store
Definition SimulationContext.hpp:1060
std::vector< double > qual_routing_reacted
Quality mass lost to decay.
Definition SimulationContext.hpp:1151
double routing_wet_weather
Definition SimulationContext.hpp:1078
std::vector< double > qual_wet_deposition
Wet deposition mass.
Definition SimulationContext.hpp:1141
double gw_final_storage
Definition SimulationContext.hpp:1119
std::vector< double > qual_routing_seep
Quality mass lost to seepage.
Definition SimulationContext.hpp:1156
double step_gw_inflow
Definition SimulationContext.hpp:1133
double runoff_rainfall
Total rainfall volume (ft3)
Definition SimulationContext.hpp:1052
void reset()
Definition SimulationContext.hpp:1184
double gw_lateral_flow
Cumulative lateral GW flow (ft)
Definition SimulationContext.hpp:1117
std::vector< double > qual_routing_ii_in
RDII quality mass inflow.
Definition SimulationContext.hpp:1152
double routing_flooding
Definition SimulationContext.hpp:1082
void resize_quality(int n_pollutants)
Definition SimulationContext.hpp:1159
double gw_error() const
Groundwater continuity error (fraction). Gap #72.
Definition SimulationContext.hpp:1277
double runoff_evap
Total evaporation volume (ft3)
Definition SimulationContext.hpp:1054
double gw_init_storage
Initial GW storage (ft)
Definition SimulationContext.hpp:1118
std::vector< double > qual_routing_gw_in
Groundwater quality mass inflow.
Definition SimulationContext.hpp:1154
double step_flooding
Definition SimulationContext.hpp:1130
std::vector< double > qual_sweeping
Mass removed by sweeping.
Definition SimulationContext.hpp:1142
std::vector< double > routing_forcing_qual_inflow
Per-pollutant cumulative user-forced quality mass.
Definition SimulationContext.hpp:1109
double routing_error() const
Routing continuity error (fraction).
Definition SimulationContext.hpp:1265
double gw_lower_evap
Cumulative lower zone evaporation (ft)
Definition SimulationContext.hpp:1115
std::vector< double > qual_routing_outflow
Quality mass leaving at outfalls.
Definition SimulationContext.hpp:1147
double runoff_final_snow
Definition SimulationContext.hpp:1074
double routing_forcing_inflow
Cumulative user-forced lateral inflow (ft3)
Definition SimulationContext.hpp:1106
double routing_coupling_out
Definition SimulationContext.hpp:1098
double step_rdii_inflow
Definition SimulationContext.hpp:1134
double runoff_infil
Total infiltration volume (ft3)
Definition SimulationContext.hpp:1055
double step_outflow
Definition SimulationContext.hpp:1131
std::vector< double > qual_bmp_removal
BMP treatment removal.
Definition SimulationContext.hpp:1143
double routing_outflow
Definition SimulationContext.hpp:1099
double runoff_lid_drain
LID drain-to-node outflow (ft3), legacy RUNOFF_DRAINS / VlidDrain.
Definition SimulationContext.hpp:1057
double runoff_error() const
Runoff continuity error (fraction).
Definition SimulationContext.hpp:1250
std::vector< double > qual_routing_wet
Wet weather quality inflow to routing.
Definition SimulationContext.hpp:1146
std::vector< double > qual_routing_evap
Quality mass lost to evaporation.
Definition SimulationContext.hpp:1157
double step_dw_inflow
Definition SimulationContext.hpp:1132
double step_ext_inflow
Definition SimulationContext.hpp:1135
double runoff_init_snow
Definition SimulationContext.hpp:1064
Top-N element statistic entry (matching legacy TMaxStats).
Definition SimulationContext.hpp:1383
int index
element index (-1 = unused slot)
Definition SimulationContext.hpp:1385
int obj_type
0 = NODE, 1 = LINK
Definition SimulationContext.hpp:1384
double value
statistic value (percentage or index)
Definition SimulationContext.hpp:1386
D-NS1 negative-source clamp bookkeeping (subplan §3.1, X6).
Definition SimulationContext.hpp:1295
bool api_warned
first negative API mass flux
Definition SimulationContext.hpp:1306
int first_node
Definition SimulationContext.hpp:1299
void reset()
Definition SimulationContext.hpp:1307
double shortfall_mass
unmet extraction, internal units
Definition SimulationContext.hpp:1297
long clamp_events
pollutant clamps, all engines
Definition SimulationContext.hpp:1296
bool first_clamp_recorded
Definition SimulationContext.hpp:1305
long age_clamp_events
age-row clamps
Definition SimulationContext.hpp:1298
void update_iterations(int iters, bool converged)
Record iteration count for a routing step.
Definition SimulationContext.hpp:1425
double sum_step
Sum of all routing time steps (sec)
Definition SimulationContext.hpp:1403
double sum_iterations
Sum of iterations for averaging.
Definition SimulationContext.hpp:1414
static constexpr int N_TIME_BINS
Number of time step histogram bins (matching legacy TIMELEVELS=5).
Definition SimulationContext.hpp:1408
long n_steps
Total number of routing steps.
Definition SimulationContext.hpp:1404
double fv_active_min
min active-face fraction
Definition SimulationContext.hpp:1500
double avg_step() const
Definition SimulationContext.hpp:1466
void init_histogram(double route_step, double min_route_step)
Definition SimulationContext.hpp:1433
double max_step
Maximum routing time step used (sec)
Definition SimulationContext.hpp:1402
double min_step
Minimum routing time step used (sec)
Definition SimulationContext.hpp:1401
void update(double dt)
Definition SimulationContext.hpp:1417
double steady_pct
Percent of time in steady state.
Definition SimulationContext.hpp:1405
double fv_last_h
last substep (s)
Definition SimulationContext.hpp:1498
double step_intervals[N_TIME_BINS+1]
Histogram bin edges.
Definition SimulationContext.hpp:1410
void record_step_bin(double dt)
Add a step to the histogram (call during simulation or post-process)
Definition SimulationContext.hpp:1456
long step_counts[N_TIME_BINS+1]
Histogram bin counts.
Definition SimulationContext.hpp:1409
long fv_nsteps
explicit substeps over the run
Definition SimulationContext.hpp:1495
long fv_tier_cells[8]
rebuild-sampled cells per LTS tier
Definition SimulationContext.hpp:1503
long fv_dt_argmin_band
Definition SimulationContext.hpp:1509
double fv_active_max
max active-face fraction
Definition SimulationContext.hpp:1502
double fv_avg_h
mean substep (s)
Definition SimulationContext.hpp:1497
double fv_min_h
smallest substep taken (s)
Definition SimulationContext.hpp:1499
double max_courant
Maximum Courant number observed.
Definition SimulationContext.hpp:1415
int fv_n_tiers
populated tier count
Definition SimulationContext.hpp:1504
double fv_active_mean
mean active-face fraction
Definition SimulationContext.hpp:1501
double pct_non_converged() const
Definition SimulationContext.hpp:1470
double slot_peak_share
Definition SimulationContext.hpp:1492
double slot_time_above_s
Definition SimulationContext.hpp:1493
void build_histogram()
Definition SimulationContext.hpp:1447
long fv_nflux
face flux evaluations
Definition SimulationContext.hpp:1496
long n_non_converged
Non-convergence and iteration tracking.
Definition SimulationContext.hpp:1413
long fv_dt_argmin_pressurized
Definition SimulationContext.hpp:1508
long fv_dt_argmin_node
Definition SimulationContext.hpp:1511
double computed_avg_iterations() const
Definition SimulationContext.hpp:1474
long fv_dt_argmin_free
Definition SimulationContext.hpp:1510
std::vector< twoD::PendingBoundaryRow > * pending_bc
Definition SimulationContext.hpp:920
twoD::SubsurfaceState * aquifer_state
Definition SimulationContext.hpp:950
twoD::MeshData * mesh
Definition SimulationContext.hpp:917
twoD::GwTransportData * gw
Definition SimulationContext.hpp:935
twoD::SubsurfaceConfig * aquifer
Definition SimulationContext.hpp:940
std::vector< twoD::PendingBoundaryQualityRow > * pending_bq
Definition SimulationContext.hpp:925
std::vector< twoD::PendingEdgeConveyanceRow > * pending_ec
Definition SimulationContext.hpp:921
std::vector< twoD::PendingInitialQualityRow > * pending_iq
Definition SimulationContext.hpp:924
std::vector< std::string > * aquifer_nodes
Definition SimulationContext.hpp:944
twoD::BoundaryData * boundary
Definition SimulationContext.hpp:919
twoD::Infil2D * infil
Definition SimulationContext.hpp:930
twoD::SolverOptions2D * options
Definition SimulationContext.hpp:918
std::vector< int > up_link
upstream conduit (through orientation, -1 sag/peak)
Definition SimulationContext.hpp:1528
std::vector< int > dn_link
downstream conduit (-1 sag/peak)
Definition SimulationContext.hpp:1529
void clear()
Definition SimulationContext.hpp:1533
std::vector< long long > resid_n
number of accumulated steps
Definition SimulationContext.hpp:1532
std::vector< int > node_idx
virtual junction node index
Definition SimulationContext.hpp:1527
std::vector< double > resid_max
max |R_j| over the run (cfs·ft/s)
Definition SimulationContext.hpp:1530
std::vector< double > resid_sum
Σ|R_j| for mean reporting.
Definition SimulationContext.hpp:1531
std::vector< std::pair< std::string, std::string > > deferred_section_rows
Section rows whose target object had not been parsed yet.
Definition SimulationContext.hpp:968
struct openswmm::SimulationContext::MassBalance mass_balance
NameIndex aquifer_names
Definition SimulationContext.hpp:779
TransectStore transects
Definition SimulationContext.hpp:705
struct openswmm::SimulationContext::VJDiag vj_diag
UserFlags user_flags
User-defined flags from [USER_FLAGS] section.
Definition SimulationContext.hpp:821
LinkSubtypes link_subtypes
Relational per-subtype link side-tables (Phase 6) — the link analogue of node_subtypes....
Definition SimulationContext.hpp:521
void save_state() noexcept
Snapshot current state into old-step arrays before solving.
Definition SimulationContext.hpp:1767
double old_elapsed_ms
Elapsed routing time (ms) at the START of the current step.
Definition SimulationContext.hpp:466
NameIndex subcatch_names
Subcatchment name → subcatchment index.
Definition SimulationContext.hpp:651
NameIndex node_names
Node name → node index.
Definition SimulationContext.hpp:639
SpeciesRegistry species_registry
Species registry — the single source of truth for transported constituents (master plan §4....
Definition SimulationContext.hpp:549
ReactionData reactions
Multispecies reaction system (EPANET-MSX conventions), parsed from the reactions component's config f...
Definition SimulationContext.hpp:557
InletUsageStore inlet_usages
Definition SimulationContext.hpp:725
MaxStats max_courant_crit[MAX_STATS]
Top-5 CFL time-step critical elements.
Definition SimulationContext.hpp:1392
int n_nodes() const noexcept
Number of nodes.
Definition SimulationContext.hpp:1868
ExtInflowData ext_inflows
Definition SimulationContext.hpp:694
static void updateMaxStats(MaxStats arr[], int obj_type, int idx, double value)
Insertion sort into a descending-by-absolute-value top-N array.
Definition SimulationContext.hpp:1625
NodeData nodes
All node state and properties.
Definition SimulationContext.hpp:496
std::uint64_t xsect_generation
Definition SimulationContext.hpp:712
double adjust_rain[12]
Definition SimulationContext.hpp:755
MaxStats max_non_converged[MAX_STATS]
Top-5 nodes with highest non-convergence frequency.
Definition SimulationContext.hpp:1396
TableData tables
All time series and rating curves.
Definition SimulationContext.hpp:629
struct openswmm::SimulationContext::NegativeSourceStats negsrc
double adjust_temp[12]
Monthly climate adjustment factors from [ADJUSTMENTS] section.
Definition SimulationContext.hpp:753
MaxStats max_mass_bal_errs[MAX_STATS]
Top-5 nodes with highest continuity errors.
Definition SimulationContext.hpp:1398
int error_code
Most recent error code (0 = no error).
Definition SimulationContext.hpp:978
RDIIAssignData rdii_assigns
Definition SimulationContext.hpp:696
AquiferStore aquifers
Definition SimulationContext.hpp:778
BedZoneState bed_state
The bed / hyporheic transient-storage zone (phase H6b).
Definition SimulationContext.hpp:601
NameIndex snowpack_names
Definition SimulationContext.hpp:777
std::vector< int > subcatch_d_store_pattern
Definition SimulationContext.hpp:764
InletStore inlets
Definition SimulationContext.hpp:724
GageData gages
All rain gage state and properties.
Definition SimulationContext.hpp:533
FilesSpec files
Secondary file references parsed from [FILES].
Definition SimulationContext.hpp:884
std::vector< ControlLogEntry > control_log
Chronological log of all control actions taken during the simulation.
Definition SimulationContext.hpp:1605
DwfData dwf_inflows
Definition SimulationContext.hpp:695
struct openswmm::SimulationContext::InletDiag inlet_diag
NameIndex gage_names
Rain gage name → gage index.
Definition SimulationContext.hpp:657
BuildupData buildup
Definition SimulationContext.hpp:677
std::vector< std::pair< int, std::string > > pending_gw_nodes
Definition SimulationContext.hpp:794
int n_gages() const noexcept
Number of rain gages.
Definition SimulationContext.hpp:1877
std::string inp_file_path
Path to the input .inp file (empty if not opened from a file).
Definition SimulationContext.hpp:1615
std::vector< std::uint8_t > coupled_node
Per-node flag: 1 if the node is a 2D-coupled junction (a non-outfall coupling point),...
Definition SimulationContext.hpp:1020
NodeSubtypes node_subtypes
Relational side-tables for node subtypes (storage/outfall/divider).
Definition SimulationContext.hpp:507
bool gpkg_units_internal
Definition SimulationContext.hpp:721
std::vector< std::string > errors
Accumulated error messages written to report file.
Definition SimulationContext.hpp:1007
WaterAgeState water_age_state
Definition SimulationContext.hpp:573
RDIIDecayData rdii_decay
Parsed [RDII_DECAY] data (exponential IA model)
Definition SimulationContext.hpp:698
EngineState state
Current lifecycle state of the engine.
Definition SimulationContext.hpp:360
WashoffData washoff
Definition SimulationContext.hpp:678
int warning_code
Most recent warning code (0 = no warning).
Definition SimulationContext.hpp:984
NameIndex landuse_names
Definition SimulationContext.hpp:675
int n_tables() const noexcept
Number of tables (time series + curves).
Definition SimulationContext.hpp:1884
struct openswmm::SimulationContext::RoutingStepStats routing_stats
LidControlStore lid_controls
Definition SimulationContext.hpp:780
std::vector< int > subcatch_infil_pattern
Definition SimulationContext.hpp:765
double adjust_hydcon[12]
Definition SimulationContext.hpp:756
std::vector< std::string > title_notes
Project title and notes (from [TITLE] section).
Definition SimulationContext.hpp:388
std::vector< std::string > warnings
Accumulated warning messages written to report file.
Definition SimulationContext.hpp:998
ControlRuleStore control_rules
Definition SimulationContext.hpp:726
struct openswmm::SimulationContext::MassBalance2D mass_balance_2d
int find_curve(std::string_view name) const noexcept
Find a curve table (any CURVE_* type) by name; -1 if none.
Definition SimulationContext.hpp:1903
std::time_t wall_start
Wall-clock time stamped at the start of SWMMEngine::open().
Definition SimulationContext.hpp:373
TreatmentData treatment
Definition SimulationContext.hpp:679
bool has_subcatch_adj_patterns
True if any pattern index >= 0.
Definition SimulationContext.hpp:770
WaterAgeConfigData water_age_config
Water-age tracking (phase A1a): per-source initial ages parsed from the waterage component (model....
Definition SimulationContext.hpp:572
ArdConfigData ard_config
Eulerian ARD transport component configuration, parsed from the model.ard config file registered via ...
Definition SimulationContext.hpp:565
void finalize_max_stats()
Compute top-5 arrays for CFL-critical, flow turns, and non-convergence.
Definition SimulationContext.hpp:1644
LinkData links
All link state and properties.
Definition SimulationContext.hpp:513
UnitHydData unit_hyds
Parsed [HYDROGRAPHS] data.
Definition SimulationContext.hpp:697
std::vector< std::pair< int, std::pair< std::string, std::string > > > pending_link_nodes
Definition SimulationContext.hpp:800
double dt_controls_remaining
Time remaining until the next control rule event (seconds).
Definition SimulationContext.hpp:486
void reset()
Fully reset the context to a CREATED state.
Definition SimulationContext.hpp:1683
int n_pollutants() const noexcept
Number of pollutants.
Definition SimulationContext.hpp:1880
std::vector< ProcessComponentSpec > process_component_specs
Process-component registrations parsed from [PROCESS_COMPONENTS].
Definition SimulationContext.hpp:864
LidUsageStore lid_usage
Definition SimulationContext.hpp:782
double next_report_ms
Next report instant in MILLISECONDS from start_date.
Definition SimulationContext.hpp:478
LidLayerSpeciesState lid_layer_state
A4: per-(LID unit, layer, species) transported state.
Definition SimulationContext.hpp:580
InitialQualityData initial_quality
Per-element initial quality rows from [INITIAL_QUALITY].
Definition SimulationContext.hpp:688
climate::ClimateState climate_state
Daily climate state — temperature, evaporation, wind, humidity.
Definition SimulationContext.hpp:411
MaxStats max_flow_turns[MAX_STATS]
Top-5 links with highest flow instability index.
Definition SimulationContext.hpp:1394
std::vector< std::pair< std::string, std::vector< std::string > > > embedded_component_sections
Embedded component sections found in the legacy .inp ([REACTION_*] today; other component families as...
Definition SimulationContext.hpp:874
void allocate_objects()
Allocate all object arrays after input parsing is complete.
Definition SimulationContext.hpp:1812
StateAccessors state_accessors
Solver-neutral accessors for reading and writing solver-internal state at hot-start save/load time.
Definition SimulationContext.hpp:894
std::vector< std::string > reported_species_names
Species names as REPORTED (phase A2b): the pollutant names, then __WATER_AGE__ when [OPTIONS] WATER_A...
Definition SimulationContext.hpp:618
int n_subcatches() const noexcept
Number of subcatchments.
Definition SimulationContext.hpp:1874
int n_links() const noexcept
Number of links.
Definition SimulationContext.hpp:1871
std::vector< double > base_ds_perv
Definition SimulationContext.hpp:769
NameIndex link_names
Link name → link index.
Definition SimulationContext.hpp:645
std::vector< PluginSpec > plugin_specs
Plugin library specs parsed from [PLUGINS].
Definition SimulationContext.hpp:855
StreetStore streets
Definition SimulationContext.hpp:723
double coupling_delivery_remaining
Remaining seconds of the current 1D↔2D coupling delivery window.
Definition SimulationContext.hpp:1035
double current_time
Current simulation time in SECONDS from start_date.
Definition SimulationContext.hpp:435
struct openswmm::SimulationContext::TwoDModelIO twod_io
double elapsed_ms
Elapsed routing time in MILLISECONDS from start_date.
Definition SimulationContext.hpp:458
int find_table_any(std::string_view name) const noexcept
Find a table of either kind by name; -1 if none.
Definition SimulationContext.hpp:1913
ForcingData forcing
Per-element runtime forcing state (lateral inflows, head boundaries, rainfall, evap,...
Definition SimulationContext.hpp:844
int n_landuses() const noexcept
Definition SimulationContext.hpp:1881
std::vector< double > base_n_perv
Base values for pattern-adjusted parameters (populated at init).
Definition SimulationContext.hpp:768
double adjust_evap[12]
Definition SimulationContext.hpp:754
HeatState heat_state
Definition SimulationContext.hpp:589
int n_reported_species() const noexcept
Length of reported_species_names (pollutants + age when enabled).
Definition SimulationContext.hpp:621
std::string error_message
Human-readable message for the last error/warning.
Definition SimulationContext.hpp:989
SpatialFrame spatial
Coordinate reference system and georeferenced coordinates.
Definition SimulationContext.hpp:810
std::vector< transect::TransectData > transect_tables
Built transect geometry tables (indexed same as transects).
Definition SimulationContext.hpp:707
SnowpackStore snowpacks
Definition SimulationContext.hpp:776
int find_timeseries(std::string_view name) const noexcept
Find a timeseries table by name; -1 if none.
Definition SimulationContext.hpp:1898
std::vector< int > subcatch_n_perv_pattern
Per-subcatchment pattern indices for N-PERV, DSTORE, INFIL adjustments.
Definition SimulationContext.hpp:763
PatternData patterns
Definition SimulationContext.hpp:699
static constexpr int MAX_STATS
Definition SimulationContext.hpp:1389
NameIndex lid_names
Definition SimulationContext.hpp:781
HeatConfigData heat_config
Heat transport (phase H1): per-source inlet temperatures parsed from the heat component (model....
Definition SimulationContext.hpp:588
NameIndex pollutant_names
Pollutant name → pollutant index.
Definition SimulationContext.hpp:663
void shrink_all_to_fit()
Release excess vector capacity on all owned SoA data stores.
Definition SimulationContext.hpp:1850
void reset_state() noexcept
Reset all state variables to initial conditions (cold start).
Definition SimulationContext.hpp:1787
std::vector< Event > events
Definition SimulationContext.hpp:741
SubcatchData subcatches
All subcatchment state and properties.
Definition SimulationContext.hpp:527
LanduseData landuses
Definition SimulationContext.hpp:676
SimulationOptions options
Parsed simulation options (from [OPTIONS] section).
Definition SimulationContext.hpp:398
PollutantData pollutants
Pollutant definitions and per-object quality state.
Definition SimulationContext.hpp:539
double current_date
Absolute current date/time (decimal days, OADate (days since 12/30/1899)).
Definition SimulationContext.hpp:444
All SWMM simulation options parsed from [OPTIONS] section.
Definition SimulationOptions.hpp:166
SoA storage for snowpack parameter sets.
Definition HydrologyData.hpp:54
Spatial frame containing CRS and georeferenced coordinates.
Definition SpatialFrame.hpp:98
Solver-neutral hooks for reading and writing solver-internal state (infiltration, groundwater) at hot...
Definition SimulationContext.hpp:294
std::function< bool(int subcatch_index, int model, const double *infil)> set_infil_state
Definition SimulationContext.hpp:301
std::function< bool(int subcatch_index, int &out_model, double *out_infil)> get_infil_state
Definition SimulationContext.hpp:297
bool can_write() const noexcept
True iff the write-side accessors are wired.
Definition SimulationContext.hpp:315
std::function< bool(int subcatch_index, double theta, double lower_depth)> set_gw_state
Apply groundwater zone state to a subcatchment.
Definition SimulationContext.hpp:307
std::function< bool(int subcatch_index, double &out_theta, double &out_lower_depth)> get_gw_state
Read groundwater zone state (upper-zone moisture and lower-zone depth).
Definition SimulationContext.hpp:304
bool can_read() const noexcept
True iff the read-side accessors are wired.
Definition SimulationContext.hpp:310
Definition InfraData.hpp:70
Structure-of-Arrays storage for all subcatchments.
Definition SubcatchData.hpp:57
SoA collection of all time series and curves in the model.
Definition TableData.hpp:690
Definition InfraData.hpp:42
Definition QualityData.hpp:149
Definition InflowData.hpp:173
Definition QualityData.hpp:114
Parsed model.age state (waterage component, phase A1a).
Definition WaterAgeData.hpp:72
Definition WaterAgeData.hpp:111
Definition Climate.hpp:87
One entry per control rule action that changed a link setting.
Definition SimulationContext.hpp:1597
Event time periods for event-based analysis/reporting.
Definition SimulationContext.hpp:737
Per-inlet-usage performance block for the .rpt street tables.
Definition SimulationContext.hpp:1553
System mass-balance totals for the optional 2D surface domain.
Definition SimulationContext.hpp:1320
Cumulative mass balance totals for runoff and routing.
Definition SimulationContext.hpp:1050
Top-N element statistic entry (matching legacy TMaxStats).
Definition SimulationContext.hpp:1383
D-NS1 negative-source clamp bookkeeping (subplan §3.1, X6).
Definition SimulationContext.hpp:1295
Definition SimulationContext.hpp:1400
Non-owning pointers to the engine's 2D surface-routing model storage (mesh, solver options,...
Definition SimulationContext.hpp:916
Per-virtual-junction momentum-residual accumulators.
Definition SimulationContext.hpp:1526
Central, reentrant simulation context.
Definition SimulationContext.hpp:353
SoA storage for per-edge boundary conditions.
Definition BoundaryData.hpp:71
Every [GW_*] authoring row of one model.
Definition GwTransportData.hpp:180
SoA storage for 2D mixed triangle/quad mesh geometry and topology.
Definition MeshData.hpp:67
Configuration for the 2D surface routing solver.
Definition SolverOptions2D.hpp:208
Everything the parser fills, before resolution onto cells.
Definition SubsurfaceData.hpp:234
Per-cell resolved parameters and state (SoA).
Definition SubsurfaceData.hpp:146