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

Central, reentrant simulation context. More...

#include <SimulationContext.hpp>

Classes

struct  ControlLogEntry
 
struct  Event
 Event time periods for event-based analysis/reporting. More...
 
struct  InletDiag
 Per-inlet-usage performance block for the .rpt street tables. More...
 
struct  MassBalance
 
struct  MassBalance2D
 
struct  MaxStats
 Top-N element statistic entry (matching legacy TMaxStats). More...
 
struct  NegativeSourceStats
 D-NS1 negative-source clamp bookkeeping (subplan §3.1, X6). More...
 
struct  OutfallExports
 Cumulative mass balance totals for runoff and routing. More...
 
struct  QualityOnlyInflow
 
struct  RoutingStepStats
 
struct  TwoDModelIO
 Non-owning pointers to the engine's 2D surface-routing model storage (mesh, solver options, boundary conditions, parse-time pending rows). More...
 
struct  VJDiag
 Per-virtual-junction momentum-residual accumulators. More...
 

Public Member Functions

void refreshReportedSpecies ()
 Rebuild derived output columns after pre-initialization reaction edits.
 
int n_reported_species () const noexcept
 Length of reported_species_names (pollutants + age when enabled).
 
void logControlAction (const ControlLogEntry &e)
 Append a control action or count it as dropped at the log cap.
 
void finalize_max_stats ()
 Compute top-5 arrays for CFL-critical, flow turns, and non-convergence.
 
void reset ()
 Fully reset the context to a CREATED state.
 
void save_state () noexcept
 Snapshot current state into old-step arrays before solving.
 
void save_lat_qual_state () noexcept
 Roll node lateral inflows and node/link quality to their old-step arrays.
 
void save_hyd_state () noexcept
 Roll node and link hydraulic values to old-step arrays.
 
void reset_state () noexcept
 Reset all state variables to initial conditions (cold start).
 
void allocate_objects ()
 Allocate all object arrays after input parsing is complete.
 
void shrink_all_to_fit ()
 Release excess vector capacity on all owned SoA data stores.
 
int n_nodes () const noexcept
 Number of nodes.
 
int n_links () const noexcept
 Number of links.
 
int n_subcatches () const noexcept
 Number of subcatchments.
 
int n_gages () const noexcept
 Number of rain gages.
 
int n_pollutants () const noexcept
 Number of pollutants.
 
int n_landuses () const noexcept
 Count registered land-use names.
 
int n_tables () const noexcept
 Number of tables (time series + curves).
 
int find_timeseries (std::string_view name) const noexcept
 Find the lowest-index matching time-series table.
 
int find_curve (std::string_view name) const noexcept
 Find the lowest-index matching curve table.
 
int find_table_any (std::string_view name) const noexcept
 Find a named table with time-series precedence.
 

Static Public Member Functions

static void updateMaxStats (MaxStats arr[], int obj_type, int idx, double value)
 Insert a candidate into a fixed top-five array by absolute magnitude.
 

Public Attributes

EngineState state = EngineState::CREATED
 Current lifecycle state of the engine.
 
std::time_t wall_start = 0
 Wall-clock time stamped at the start of SWMMEngine::open().
 
std::vector< std::string > title_notes
 Project title and notes (from [TITLE] section).
 
std::map< std::string, std::vector< std::string > > passthrough_sections
 Sections the solver never reads, kept verbatim so a save does not delete them: [LABELS], [BACKDROP], [PROFILE].
 
SimulationOptions options
 Parsed simulation options (from [OPTIONS] section).
 
climate::ClimateState climate_state
 Daily climate state — temperature, evaporation, wind, humidity.
 
double current_time = 0.0
 Current simulation time in SECONDS from start_date.
 
double current_date = 0.0
 Absolute current date/time (decimal days, OADate (days since 12/30/1899)).
 
double elapsed_ms = 0.0
 Elapsed routing time in MILLISECONDS from start_date.
 
double old_elapsed_ms = 0.0
 Elapsed routing time (ms) at the START of the current step.
 
double next_report_ms = 0.0
 Next report instant in MILLISECONDS from start_date.
 
double runoff_interp_f = 1.0
 Where this routing instant falls between the two runoff times.
 
double dt_controls_remaining = 0.0
 Time remaining until the next control rule event (seconds).
 
NodeData nodes
 All node state and properties.
 
NodeSubtypes node_subtypes
 Relational side-tables for node subtypes (storage/outfall/divider).
 
LinkData links
 All link state and properties.
 
LinkSubtypes link_subtypes
 Relational per-subtype link side-tables (Phase 6) — the link analogue of node_subtypes. Authoritative store for conduit/pump/ orifice/weir/outlet config; shared fields (xsect_*, has_flap_gate, pump_curve_name) stay on links.
 
SubcatchData subcatches
 All subcatchment state and properties.
 
GageData gages
 All rain gage state and properties.
 
PollutantData pollutants
 Pollutant definitions and per-object quality state.
 
SpeciesRegistry species_registry
 Species registry — the single source of truth for transported constituents (master plan §4.1, phase T0a). Pollutants occupy the first slots (index-aligned with the legacy pollutant index); MSX species append via the reactions component (R1); reserved age/temperature species append with phases A1/H1. Rebuilt at each open().
 
ReactionData reactions
 Multispecies reaction system (EPANET-MSX conventions), parsed from the reactions component's config file or embedded [REACTION_*] sections (phase R1). Compiled bytecode arrives with phase R2.
 
ArdConfigData ard_config
 Eulerian ARD transport component configuration, parsed from the model.ard config file registered via [PROCESS_COMPONENTS] (phase E3: the dispersion subset — global mode + per-conduit overrides).
 
WaterAgeConfigData water_age_config
 Water-age tracking (phase A1a): per-source initial ages parsed from the waterage component (model.age) + the runtime age state the engines and loaders share.
 
WaterAgeState water_age_state
 
LidLayerSpeciesState lid_layer_state
 A4: per-(LID unit, layer, species) transported state.
 
HeatConfigData heat_config
 Heat transport (phase H1): per-source inlet temperatures parsed from the heat component (model.heat) + the runtime temperature state the engines and loaders share.
 
HeatState heat_state
 
BedZoneState bed_state
 The bed / hyporheic transient-storage zone (phase H6b).
 
std::vector< std::string > reported_species_names
 Species names as REPORTED (phase A2b): the pollutant names, then __WATER_AGE__ when [OPTIONS] WATER_AGE is on.
 
TableData tables
 All time series and rating curves.
 
NameIndex node_names
 Node name → node index.
 
NameIndex link_names
 Link name → link index.
 
NameIndex subcatch_names
 Subcatchment name → subcatchment index.
 
NameIndex gage_names
 Rain gage name → gage index.
 
NameIndex pollutant_names
 Pollutant name → pollutant index.
 
NameIndex landuse_names
 
LanduseData landuses
 
BuildupData buildup
 
WashoffData washoff
 
TreatmentData treatment
 
InitialQualityData initial_quality
 Per-element initial quality rows from [INITIAL_QUALITY].
 
ExtInflowData ext_inflows
 
DwfData dwf_inflows
 
RDIIAssignData rdii_assigns
 
UnitHydData unit_hyds
 Parsed [HYDROGRAPHS] data.
 
RDIIDecayData rdii_decay
 Parsed [RDII_DECAY] data (exponential IA model)
 
PatternData patterns
 
TransectStore transects
 
std::vector< transect::TransectData > transect_tables
 Built transect geometry tables (indexed same as transects).
 
std::uint64_t xsect_generation = 0
 
bool gpkg_units_internal = false
 
StreetStore streets
 
InletStore inlets
 
InletUsageStore inlet_usages
 
ControlRuleStore control_rules
 
std::vector< Event > events
 
double adjust_temp [12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
 Monthly climate adjustment factors from [ADJUSTMENTS] section.
 
double adjust_evap [12]
 [ADJUSTMENTS] EVAP: ADDED to the evaporation rate (in/day or mm/day), legacy Adjust.evap
 
double adjust_rain [12] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
 
double adjust_hydcon [12] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
 
std::vector< int > subcatch_n_perv_pattern
 Per-subcatchment pattern indices for N-PERV, DSTORE, INFIL adjustments.
 
std::vector< int > subcatch_d_store_pattern
 
std::vector< int > subcatch_infil_pattern
 
std::vector< double > base_n_perv
 Base values for pattern-adjusted parameters (populated at init).
 
std::vector< double > base_ds_perv
 
bool has_subcatch_adj_patterns = false
 True if any pattern index >= 0.
 
SnowpackStore snowpacks
 
NameIndex snowpack_names
 
AquiferStore aquifers
 
NameIndex aquifer_names
 
LidControlStore lid_controls
 
std::vector< LidNodeOutlet > lid_node_outlets
 
NameIndex lid_names
 
LidUsageStore lid_usage
 
std::vector< std::pair< int, std::string > > pending_gw_nodes
 
std::vector< std::pair< int, std::string > > pending_gw_aquifers
 
std::vector< std::pair< int, std::pair< std::string, std::string > > > pending_link_nodes
 
SpatialFrame spatial
 Coordinate reference system and georeferenced coordinates.
 
UserFlags user_flags
 User-defined flags from [USER_FLAGS] section.
 
ForcingData forcing
 Per-element runtime forcing state (lateral inflows, head boundaries, rainfall, evap, link settings, quality mass fluxes).
 
std::vector< PluginSpec > plugin_specs
 Plugin library specs parsed from [PLUGINS].
 
std::vector< ProcessComponentSpec > process_component_specs
 Process-component registrations parsed from [PROCESS_COMPONENTS].
 
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 they land) — the D-UT8 embedded-fallback path. (tag, lines) pairs in file order; consumed after component resolution with a style warning, or reported ignored when the external file wins.
 
FilesSpec files
 Secondary file references parsed from [FILES].
 
StateAccessors state_accessors
 Solver-neutral accessors for reading and writing solver-internal state at hot-start save/load time.
 
struct openswmm::SimulationContext::TwoDModelIO twod_io
 
std::vector< std::pair< std::string, std::string > > deferred_section_rows
 Section rows whose target object had not been parsed yet.
 
std::vector< std::pair< std::string, long > > unknown_section_headers
 Every unknown section header read, as (token as written, 1-based line number), in file order — legacy's "Unknown section '%s' at line %ld" warning names both.
 
int error_code = 0
 Most recent error code (0 = no error).
 
int warning_code = 0
 Most recent warning code (0 = no warning).
 
std::string error_message
 Human-readable message for the last error/warning.
 
std::vector< std::string > warnings
 Accumulated warning messages written to report file.
 
std::vector< std::string > errors
 Accumulated error messages written to report file.
 
NodeCoupling2DRows node_coupling_2d
 [2D_NODE_COUPLING] rows: per-node coupling structure type and its authored parameters (model data, kept with or without a mesh).
 
std::vector< std::uint8_t > coupled_node
 Per-node flag: 1 if the node is a 2D-coupled junction (a non-outfall coupling point), else 0. Empty when the 2D module is inactive.
 
std::vector< double > coupled_pond_area
 Above-rim pond of each 2D-coupled junction under dynamic wave (2D_OPTIONS COUPLING_POND_MODE / COUPLING_RIM_BAND).
 
std::vector< double > coupled_pond_band
 
double coupling_delivery_remaining = 0.0
 Remaining seconds of the current 1D↔2D coupling delivery window.
 
struct openswmm::SimulationContext::OutfallExports outfall_exports
 
struct openswmm::SimulationContext::MassBalance mass_balance
 
struct openswmm::SimulationContext::NegativeSourceStats negsrc
 
std::vector< double > surface_outfall_link_limit
 System mass-balance totals for the optional 2D surface domain.
 
QualityOnlyInflow surface_outfall_quality
 D2: booked as external inflow.
 
QualityOnlyInflow link_gain_quality
 gaining conduits: groundwater inflow
 
bool runtime_coupling_used = false
 Runtime prescriptions require a future restart format.
 
struct openswmm::SimulationContext::MassBalance2D mass_balance_2d
 
MaxStats max_courant_crit [MAX_STATS] = {}
 Top-5 CFL time-step critical elements.
 
MaxStats max_flow_turns [MAX_STATS] = {}
 Top-5 links with highest flow instability index.
 
MaxStats max_non_converged [MAX_STATS] = {}
 Top-5 nodes with highest non-convergence frequency.
 
MaxStats max_mass_bal_errs [MAX_STATS] = {}
 Top-5 nodes with highest continuity errors.
 
struct openswmm::SimulationContext::RoutingStepStats routing_stats
 
struct openswmm::SimulationContext::VJDiag vj_diag
 
struct openswmm::SimulationContext::InletDiag inlet_diag
 
std::vector< ControlLogEntry > control_log
 
std::vector< std::string > control_rule_names
 Rule names by rule index, interned by ControlEngine as actions are logged.
 
std::size_t control_log_dropped = 0
 Actions NOT logged because the cap was reached; the report says so once.
 
std::string inp_file_path
 Path to the input .inp file (empty if not opened from a file).
 

Static Public Attributes

static constexpr int MAX_STATS = 5
 
static constexpr std::size_t kMaxControlLog = 1'000'000
 

Detailed Description

Central, reentrant simulation context.

Owns all simulation data. Passed by (non-const) reference to every solver function. One context per concurrent simulation.

Member Function Documentation

◆ allocate_objects()

void openswmm::SimulationContext::allocate_objects ( )
inline

Allocate all object arrays after input parsing is complete.

Called by InputReader after all [JUNCTIONS], [CONDUITS], etc. sections have been parsed and the final object counts are known. Resizes SoA arrays and pollutant quality matrices.

Note
Name indices must already be populated (resize() uses node_names.size(), etc. to determine array length).

◆ finalize_max_stats()

void openswmm::SimulationContext::finalize_max_stats ( )
inline

Compute top-5 arrays for CFL-critical, flow turns, and non-convergence.

Called once at end of simulation before reporting (matching legacy stats_findMaxStats in stats.c).

Here is the call graph for this function:

◆ find_curve()

int openswmm::SimulationContext::find_curve ( std::string_view name) const
inlinenoexcept

Find the lowest-index matching curve table.

Uses the TableData name index; caller keeps it synchronized after edits.

Parameters
[in]nameBorrowed case-insensitive table name.
Returns
Matching curve index or -1; time-series rows do not qualify.
Here is the caller graph for this function:

◆ find_table_any()

int openswmm::SimulationContext::find_table_any ( std::string_view name) const
inlinenoexcept

Find a named table with time-series precedence.

For callers without kind context; a same-named time series wins regardless of curve row order. Caller keeps TableData indexes coherent.

Parameters
[in]nameBorrowed case-insensitive table name.
Returns
Lowest matching time-series index, otherwise lowest matching curve index, otherwise -1.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ find_timeseries()

int openswmm::SimulationContext::find_timeseries ( std::string_view name) const
inlinenoexcept

Find the lowest-index matching time-series table.

Uses the TableData name index; caller keeps that index synchronized after edits.

Parameters
[in]nameBorrowed case-insensitive table name, looked up without copying.
Returns
Matching table index or -1; only time-series rows qualify.
Here is the caller graph for this function:

◆ logControlAction()

void openswmm::SimulationContext::logControlAction ( const ControlLogEntry & e)
inline

Append a control action or count it as dropped at the log cap.

At one million stored entries, only increments control_log_dropped. Otherwise push_back may allocate and throw. Does not write reports or alter the referenced link setting.

Parameters
[in]eEntry copied into owned storage. Caller supplies valid link/rule indices, target setting and OADate; this helper does not validate them.

◆ n_gages()

int openswmm::SimulationContext::n_gages ( ) const
inlinenoexcept

Number of rain gages.

Here is the caller graph for this function:

◆ n_landuses()

int openswmm::SimulationContext::n_landuses ( ) const
inlinenoexcept

Count registered land-use names.

Returns
Land-use name-index size; does not check associated store allocation or alignment.
Here is the caller graph for this function:

◆ n_links()

int openswmm::SimulationContext::n_links ( ) const
inlinenoexcept

Number of links.

◆ n_nodes()

int openswmm::SimulationContext::n_nodes ( ) const
inlinenoexcept

Number of nodes.

◆ n_pollutants()

int openswmm::SimulationContext::n_pollutants ( ) const
inlinenoexcept

Number of pollutants.

Here is the caller graph for this function:

◆ n_reported_species()

int openswmm::SimulationContext::n_reported_species ( ) const
inlinenoexcept

Length of reported_species_names (pollutants + age when enabled).

◆ n_subcatches()

int openswmm::SimulationContext::n_subcatches ( ) const
inlinenoexcept

Number of subcatchments.

◆ n_tables()

int openswmm::SimulationContext::n_tables ( ) const
inlinenoexcept

Number of tables (time series + curves).

Here is the caller graph for this function:

◆ refreshReportedSpecies()

void openswmm::SimulationContext::refreshReportedSpecies ( )
inline

Rebuild derived output columns after pre-initialization reaction edits.

Here is the call graph for this function:

◆ reset()

void openswmm::SimulationContext::reset ( )
inline

Fully reset the context to a CREATED state.

Clears all object data and name indices. Does NOT free the option structs (they are re-parsed from the input file). Call this before re-running or re-opening a simulation.

◆ reset_state()

void openswmm::SimulationContext::reset_state ( )
inlinenoexcept

Reset all state variables to initial conditions (cold start).

Sets all current and old-step arrays to zero. Invert elevations and static properties are NOT changed.

◆ save_hyd_state()

void openswmm::SimulationContext::save_hyd_state ( )
inlinenoexcept

Roll node and link hydraulic values to old-step arrays.

Called only for an actually routed step; skip when steady routing is bypassed so old hydraulic values are preserved. Does not roll quality/lateral inflow or subcatchment runoff.

◆ save_lat_qual_state()

void openswmm::SimulationContext::save_lat_qual_state ( )
inlinenoexcept

Roll node lateral inflows and node/link quality to their old-step arrays.

Called every routing step, including skipped steady-state steps, before inflow/quality assembly. Does not snapshot hydraulic or subcatchment runoff state; owned data arrays must already be allocated/aligned.

◆ save_state()

void openswmm::SimulationContext::save_state ( )
inlinenoexcept

Snapshot current state into old-step arrays before solving.

Must be called at the start of each timestep, before the hydraulic and quality solvers update the state.

◆ shrink_all_to_fit()

void openswmm::SimulationContext::shrink_all_to_fit ( )
inline

Release excess vector capacity on all owned SoA data stores.

Called once after parsing and final sizing are complete. During incremental parsing, vectors grow via geometric capacity doubling. This method reclaims that excess by calling shrink_to_fit() on every data store.

Here is the caller graph for this function:

◆ updateMaxStats()

static void openswmm::SimulationContext::updateMaxStats ( MaxStats arr[],
int obj_type,
int idx,
double value )
inlinestatic

Insert a candidate into a fixed top-five array by absolute magnitude.

Strict greater-than comparison keeps existing ties first; drops the final displaced candidate. NaN magnitudes do not insert. No allocation or model access.

Parameters
[in,out]arrNon-null array of at least MAX_STATS entries already ordered by descending absolute value.
[in]obj_typeObject category carried unchanged into an inserted entry (normally 0 node or 1 link).
[in]idxObject index carried unchanged; no model-range validation.
[in]valueCandidate statistic in the same units as existing values.
Here is the caller graph for this function:

Member Data Documentation

◆ adjust_evap

double openswmm::SimulationContext::adjust_evap[12]
Initial value:
= {
0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0}

[ADJUSTMENTS] EVAP: ADDED to the evaporation rate (in/day or mm/day), legacy Adjust.evap

◆ adjust_hydcon

double openswmm::SimulationContext::adjust_hydcon[12] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}

◆ adjust_rain

double openswmm::SimulationContext::adjust_rain[12] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}

◆ adjust_temp

double openswmm::SimulationContext::adjust_temp[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}

Monthly climate adjustment factors from [ADJUSTMENTS] section.

Copied into ClimateState during initialize(). Stored here so that input parsing populates them without accessing SWMMEngine.

See also
Legacy: Adjust struct (temp[], evap[], rain[], hydcon[])

◆ aquifer_names

NameIndex openswmm::SimulationContext::aquifer_names

◆ aquifers

AquiferStore openswmm::SimulationContext::aquifers

◆ ard_config

ArdConfigData openswmm::SimulationContext::ard_config

Eulerian ARD transport component configuration, parsed from the model.ard config file registered via [PROCESS_COMPONENTS] (phase E3: the dispersion subset — global mode + per-conduit overrides).

See also
data/ArdConfigData.hpp.

◆ base_ds_perv

std::vector<double> openswmm::SimulationContext::base_ds_perv

◆ base_n_perv

std::vector<double> openswmm::SimulationContext::base_n_perv

Base values for pattern-adjusted parameters (populated at init).

◆ bed_state

BedZoneState openswmm::SimulationContext::bed_state

The bed / hyporheic transient-storage zone (phase H6b).

One entry per LINK, carrying a temperature and a per-species concentration. It sits beside heat_state rather than inside it because it holds solute state too — the reference's HTS zone is a transient-storage zone for tracers as much as a thermal mass. Empty and untouched unless [HEAT_FLUXES] SEDIMENT_EXCHANGE is on.

See also
data/BedZoneData.hpp.

◆ buildup

BuildupData openswmm::SimulationContext::buildup

◆ climate_state

climate::ClimateState openswmm::SimulationContext::climate_state

Daily climate state — temperature, evaporation, wind, humidity.

Scalar broadcast to all subcatchments; updated at the runoff step boundary by SWMMEngine. Lives on the context so that downstream solvers (RDII exponential IA, future models) can read it through ctx.climate_state without reaching into the engine.

See also
Legacy: Temp, Evap, Wind, Humidity in globals.h

◆ control_log

std::vector<ControlLogEntry> openswmm::SimulationContext::control_log

Chronological log of the control actions taken during the simulation, capped at kMaxControlLog entries (see logControlAction).

◆ control_log_dropped

std::size_t openswmm::SimulationContext::control_log_dropped = 0

Actions NOT logged because the cap was reached; the report says so once.

◆ control_rule_names

std::vector<std::string> openswmm::SimulationContext::control_rule_names

Rule names by rule index, interned by ControlEngine as actions are logged.

◆ control_rules

ControlRuleStore openswmm::SimulationContext::control_rules

◆ coupled_node

std::vector<std::uint8_t> openswmm::SimulationContext::coupled_node

Per-node flag: 1 if the node is a 2D-coupled junction (a non-outfall coupling point), else 0. Empty when the 2D module is inactive.

Populated by SurfaceRouter2D::initialize from the coupling map. Lets the 1D dynamic-wave solver treat a coupled junction as pond-capable so its HGL can rise above the crown over the auto-assigned ponded_area (the 2D-cell footprint), regardless of the global ALLOW_PONDING option — which only governs ordinary (uncoupled) junctions. Outfall coupling uses a tailwater head BC instead, so outfalls are NOT flagged here.

◆ coupled_pond_area

std::vector<double> openswmm::SimulationContext::coupled_pond_area

Above-rim pond of each 2D-coupled junction under dynamic wave (2D_OPTIONS COUPLING_POND_MODE / COUPLING_RIM_BAND).

Set by SurfaceRouter2D::initialize; EMPTY reproduces the legacy step onto ponded_area. coupled_pond_area (1D ft²) is the pond area A_eq — runtime state under TRACKING, which relaxes it each routing step; coupled_pond_band (ft) is the height above the rim over which the area ramps in (2d/coupling/PondModel.hpp).

◆ coupled_pond_band

std::vector<double> openswmm::SimulationContext::coupled_pond_band

◆ coupling_delivery_remaining

double openswmm::SimulationContext::coupling_delivery_remaining = 0.0

Remaining seconds of the current 1D↔2D coupling delivery window.

Set by SurfaceRouter2D::fireAdvanceWindow to the length of the 2D advance window whose junction-exchange volumes it just moved into NodeData::coupling_queue. assembleLateralInflows drains the queue at the uniform rate queue/remaining, counts this down once per routing step, and flushes the whole remainder on the step where remaining ≤ dt — so the 1D node receives exactly the exchanged volume spread over the window instead of as a single-step pulse. 0 (the cold-start default, and the steady state when the 2D advance fires every routing step) reproduces the legacy one-step delivery exactly.

◆ current_date

double openswmm::SimulationContext::current_date = 0.0

Absolute current date/time (decimal days, OADate (days since 12/30/1899)).

= options.start_date + current_time

See also
Legacy: StartDateTime + ElapsedTime in globals.h

◆ current_time

double openswmm::SimulationContext::current_time = 0.0

Current simulation time in SECONDS from start_date.

Updated by TimestepController::advance() with the routing step in seconds (TimestepController.cpp:88). The value 0.0 corresponds to options.start_date.

The companion field current_date is the OADate (decimal days since 12/30/1899) computed via datetime::addSeconds(start_date, current_time).

Callers that need elapsed time in decimal days (e.g. the control engine's SIM_TIME premise) must divide by constants::SEC_PER_DAY. Legacy ElapsedTime is in days; this field stores seconds.

See also
Legacy: ElapsedTime in globals.h (legacy is in days)

◆ deferred_section_rows

std::vector<std::pair<std::string, std::string> > openswmm::SimulationContext::deferred_section_rows

Section rows whose target object had not been parsed yet.

Sections are dispatched in the order they appear in the file, so a property section that names an object defined further down (e.g. an [XSECTIONS] row for a link declared in a later [ORIFICES]) cannot resolve its name on the first pass. Legacy SWMM avoids this with an ID pre-pass; here a handler stashes the unresolved row as (section tag, raw line) and InputReader re-dispatches it once every section has been read. Rows still unresolved after that replay name an object that does not exist and raise ERROR 209, as legacy does.

Parse-time scratch only — empty once reading finishes.

◆ dt_controls_remaining

double openswmm::SimulationContext::dt_controls_remaining = 0.0

Time remaining until the next control rule event (seconds).

0.0 means no control step scheduled; updated by the control rule processor.

◆ dwf_inflows

DwfData openswmm::SimulationContext::dwf_inflows

◆ elapsed_ms

double openswmm::SimulationContext::elapsed_ms = 0.0

Elapsed routing time in MILLISECONDS from start_date.

Legacy-parity clock: accumulated exactly as legacy NewRoutingTime = NewRoutingTime + 1000.0 * routingStep (swmm5.c / routing.c:309). Kept alongside current_time (seconds) because the two accumulations are NOT FP-identical; report scheduling and report datestamps must use this clock to match legacy bit-for-bit.

See also
Legacy: NewRoutingTime in globals.h

◆ embedded_component_sections

std::vector<std::pair<std::string, std::vector<std::string> > > openswmm::SimulationContext::embedded_component_sections

Embedded component sections found in the legacy .inp ([REACTION_*] today; other component families as they land) — the D-UT8 embedded-fallback path. (tag, lines) pairs in file order; consumed after component resolution with a style warning, or reported ignored when the external file wins.

◆ error_code

int openswmm::SimulationContext::error_code = 0

Most recent error code (0 = no error).

See also
Legacy: ErrorCode in globals.h

◆ error_message

std::string openswmm::SimulationContext::error_message

Human-readable message for the last error/warning.

◆ errors

std::vector<std::string> openswmm::SimulationContext::errors

Accumulated error messages written to report file.

Matches legacy behavior where errors are collected during parsing/validation and written to the .rpt file. Format: "ERROR NNN: description for ObjectID"

See also
Legacy: report_writeErrorMsg() in report.c

◆ events

std::vector<Event> openswmm::SimulationContext::events

◆ ext_inflows

ExtInflowData openswmm::SimulationContext::ext_inflows

◆ files

FilesSpec openswmm::SimulationContext::files

Secondary file references parsed from [FILES].

Mirrors legacy SWMM5's TFile struct array — rainfall, runoff, RDII, inflows, outflows, hotstart save/use. The simulation engine consults specific slots when the corresponding feature is requested (e.g. interfacing a routing run with a separately-saved runoff file).

◆ forcing

ForcingData openswmm::SimulationContext::forcing

Per-element runtime forcing state (lateral inflows, head boundaries, rainfall, evap, link settings, quality mass fluxes).

Set via swmm_forcing_*() API. Applied by applyForcings() in the step loop. Auto-cleared by clear_reset_entries() at end of each step (for RESET-persistence entries).

See also
ForcingData.hpp, openswmm_forcing.h

◆ gage_names

NameIndex openswmm::SimulationContext::gage_names

Rain gage name → gage index.

See also
Legacy: project_findObject(GAGE, name) in project.c

◆ gages

GageData openswmm::SimulationContext::gages

All rain gage state and properties.

See also
Legacy: Gage[] in globals.h + TGage in objects.h

◆ gpkg_units_internal

bool openswmm::SimulationContext::gpkg_units_internal = false

True when the model was loaded from a GeoPackage, whose hydraulic fields are stored in CANONICAL internal units (feet/cfs/ft³) — NOT the display units a .inp uses. resolve_cross_references then SKIPS the display→ internal conversion (convert_inputs_to_internal) so the round-trip is bit-for-bit identical (no non-invertible ×0.3048). The GeoPackage reader converts only the cross-section raw geom1-4 (the lone display-unit fields it stores) itself. Left false for the .inp path.

◆ has_subcatch_adj_patterns

bool openswmm::SimulationContext::has_subcatch_adj_patterns = false

True if any pattern index >= 0.

◆ heat_config

HeatConfigData openswmm::SimulationContext::heat_config

Heat transport (phase H1): per-source inlet temperatures parsed from the heat component (model.heat) + the runtime temperature state the engines and loaders share.

See also
data/HeatData.hpp.

◆ heat_state

HeatState openswmm::SimulationContext::heat_state

◆ initial_quality

InitialQualityData openswmm::SimulationContext::initial_quality

Per-element initial quality rows from [INITIAL_QUALITY].

Pollutant + reserved-species (WATER_AGE/__TEMPERATURE__) per-node/per-link initial values overriding the global [POLLUTANTS] Cinit / sidecar INITIAL_STATE seeds. Names are resolved and constituents classified in PostParseResolver.

◆ inlet_diag

struct openswmm::SimulationContext::InletDiag openswmm::SimulationContext::inlet_diag

◆ inlet_usages

InletUsageStore openswmm::SimulationContext::inlet_usages

◆ inlets

InletStore openswmm::SimulationContext::inlets

◆ inp_file_path

std::string openswmm::SimulationContext::inp_file_path

Path to the input .inp file (empty if not opened from a file).

See also
Legacy: InpFile in globals.h

◆ kMaxControlLog

std::size_t openswmm::SimulationContext::kMaxControlLog = 1'000'000
staticconstexpr

◆ landuse_names

NameIndex openswmm::SimulationContext::landuse_names

◆ landuses

LanduseData openswmm::SimulationContext::landuses

◆ lid_controls

LidControlStore openswmm::SimulationContext::lid_controls

◆ lid_layer_state

LidLayerSpeciesState openswmm::SimulationContext::lid_layer_state

A4: per-(LID unit, layer, species) transported state.

See also
data/LidLayerSpeciesData.hpp — generic over species so H5's temperature is a row rather than a second array.

◆ lid_names

NameIndex openswmm::SimulationContext::lid_names

◆ lid_node_outlets

std::vector<LidNodeOutlet> openswmm::SimulationContext::lid_node_outlets

◆ lid_usage

LidUsageStore openswmm::SimulationContext::lid_usage

◆ link_gain_quality

QualityOnlyInflow openswmm::SimulationContext::link_gain_quality

gaining conduits: groundwater inflow

◆ link_names

NameIndex openswmm::SimulationContext::link_names

Link name → link index.

See also
Legacy: project_findObject(LINK, name) in project.c

◆ link_subtypes

LinkSubtypes openswmm::SimulationContext::link_subtypes

Relational per-subtype link side-tables (Phase 6) — the link analogue of node_subtypes. Authoritative store for conduit/pump/ orifice/weir/outlet config; shared fields (xsect_*, has_flap_gate, pump_curve_name) stay on links.

See also
data/LinkSubtypes.hpp.

◆ links

LinkData openswmm::SimulationContext::links

All link state and properties.

See also
Legacy: Link[], LinkStats[] in globals.h + TLink in objects.h

◆ mass_balance

struct openswmm::SimulationContext::MassBalance openswmm::SimulationContext::mass_balance

◆ mass_balance_2d

struct openswmm::SimulationContext::MassBalance2D openswmm::SimulationContext::mass_balance_2d

◆ max_courant_crit

MaxStats openswmm::SimulationContext::max_courant_crit[MAX_STATS] = {}

Top-5 CFL time-step critical elements.

◆ max_flow_turns

MaxStats openswmm::SimulationContext::max_flow_turns[MAX_STATS] = {}

Top-5 links with highest flow instability index.

◆ max_mass_bal_errs

MaxStats openswmm::SimulationContext::max_mass_bal_errs[MAX_STATS] = {}

Top-5 nodes with highest continuity errors.

◆ max_non_converged

MaxStats openswmm::SimulationContext::max_non_converged[MAX_STATS] = {}

Top-5 nodes with highest non-convergence frequency.

◆ MAX_STATS

int openswmm::SimulationContext::MAX_STATS = 5
staticconstexpr

◆ negsrc

struct openswmm::SimulationContext::NegativeSourceStats openswmm::SimulationContext::negsrc

◆ next_report_ms

double openswmm::SimulationContext::next_report_ms = 0.0

Next report instant in MILLISECONDS from start_date.

Legacy ReportTime: seeded to 1000*report_step at start and advanced by 1000*report_step per period (swmm5.c:721,1044). The grid is anchored at SIM start; periods whose datestamp falls before options.report_start are skipped (not written) but the grid still advances — exactly legacy output_saveResults() (output.c:481).

◆ node_coupling_2d

NodeCoupling2DRows openswmm::SimulationContext::node_coupling_2d

[2D_NODE_COUPLING] rows: per-node coupling structure type and its authored parameters (model data, kept with or without a mesh).

Nodes without a row take their class default (core/NodeCoupling2D.hpp). Keyed by node index; delete_node drops and renumbers.

◆ node_names

NameIndex openswmm::SimulationContext::node_names

Node name → node index.

See also
Legacy: project_findObject(NODE, name) in project.c

◆ node_subtypes

NodeSubtypes openswmm::SimulationContext::node_subtypes

Relational side-tables for node subtypes (storage/outfall/divider).

Phase 1 (shadow) of the relational node refactor: built from nodes at hydraulics init and kept as an exact mirror of the wide subtype arrays. Not yet read by the solver. See docs/relational/RELATIONAL_NODE_REFACTOR_PLAN.md and src/engine/data/NodeSubtypes.hpp.

◆ nodes

NodeData openswmm::SimulationContext::nodes

All node state and properties.

See also
Legacy: Node[], NodeStats[] in globals.h + TNode in objects.h

◆ old_elapsed_ms

double openswmm::SimulationContext::old_elapsed_ms = 0.0

Elapsed routing time (ms) at the START of the current step.

Legacy OldRoutingTime; with elapsed_ms brackets the report instant for interpolated output.

◆ options

SimulationOptions openswmm::SimulationContext::options

Parsed simulation options (from [OPTIONS] section).

See also
Legacy: FlowUnits, RouteModel, RouteStep, … in globals.h

◆ outfall_exports

struct openswmm::SimulationContext::OutfallExports openswmm::SimulationContext::outfall_exports

◆ passthrough_sections

std::map<std::string, std::vector<std::string> > openswmm::SimulationContext::passthrough_sections

Sections the solver never reads, kept verbatim so a save does not delete them: [LABELS], [BACKDROP], [PROFILE].

Keyed by section tag, holding the data lines exactly as they were read (comments and blank lines already stripped by the reader). Legacy SWMM has no case for any of them in parseLine, so their content is whatever the authoring GUI chose to put there and no engine can validate it — which is precisely why replaying it byte-for-byte is both the safest and the most faithful thing to do.

These were registered as no-op handlers, so a model's map labels and backdrop image vanished on the first Open → Save.

◆ patterns

PatternData openswmm::SimulationContext::patterns

◆ pending_gw_aquifers

std::vector<std::pair<int, std::string> > openswmm::SimulationContext::pending_gw_aquifers

[GROUNDWATER] aquifer names (subcatch index -> aquifer name) not yet defined when the row was read, for [AQUIFERS] placed further down.

◆ pending_gw_nodes

std::vector<std::pair<int, std::string> > openswmm::SimulationContext::pending_gw_nodes

[GROUNDWATER] receiving-node names (subcatch index -> node name). [GROUNDWATER] normally precedes [JUNCTIONS] in EPA SWMM output.

◆ pending_link_nodes

std::vector<std::pair<int, std::pair<std::string, std::string> > > openswmm::SimulationContext::pending_link_nodes

Link end-node names (link index -> {from-node name, to-node name}). Legacy parsing is order-independent, so [CONDUITS] may precede the node sections; without this the link loads silently orphaned (node1/node2 -1).

◆ plugin_specs

std::vector<PluginSpec> openswmm::SimulationContext::plugin_specs

Plugin library specs parsed from [PLUGINS].

Consumed by PluginFactory::load_plugins() during open(). New in 6.0.0 — no legacy equivalent.

◆ pollutant_names

NameIndex openswmm::SimulationContext::pollutant_names

Pollutant name → pollutant index.

See also
Legacy: project_findObject(POLLUT, name) in project.c

◆ pollutants

PollutantData openswmm::SimulationContext::pollutants

Pollutant definitions and per-object quality state.

See also
Legacy: Pollut[], node.newQual[], link.newQual[] in globals.h

◆ process_component_specs

std::vector<ProcessComponentSpec> openswmm::SimulationContext::process_component_specs

Process-component registrations parsed from [PROCESS_COMPONENTS].

Resolved against the ProcessComponentRegistry during open() (after the input read, mirroring the external 2D mesh file); each resolved component's config file is parsed and delivered to its apply hook. Unified Transport suite D-UT8.

◆ rdii_assigns

RDIIAssignData openswmm::SimulationContext::rdii_assigns

◆ rdii_decay

RDIIDecayData openswmm::SimulationContext::rdii_decay

Parsed [RDII_DECAY] data (exponential IA model)

◆ reactions

ReactionData openswmm::SimulationContext::reactions

Multispecies reaction system (EPANET-MSX conventions), parsed from the reactions component's config file or embedded [REACTION_*] sections (phase R1). Compiled bytecode arrives with phase R2.

◆ reported_species_names

std::vector<std::string> openswmm::SimulationContext::reported_species_names

Species names as REPORTED (phase A2b): the pollutant names, then __WATER_AGE__ when [OPTIONS] WATER_AGE is on.

The .out format has exactly one per-species column block, so age reports as a trailing pseudo-pollutant column. This vector is the single naming truth the output writers and the snapshot's pollut_names pointer share — built once at open so the pointer stays valid for the run. n_reported_species() is its length and is what the writers must stride by; plain n_pollutants() remains the TRANSPORT stride for nodes.conc etc. Keeping the two counts distinct and named is deliberate: conflating them is the stride-slip family (roadmap lessons 14/15).

◆ routing_stats

struct openswmm::SimulationContext::RoutingStepStats openswmm::SimulationContext::routing_stats

◆ runoff_interp_f

double openswmm::SimulationContext::runoff_interp_f = 1.0

Where this routing instant falls between the two runoff times.

Legacy's f = (routingTime - OldRunoffTime) / (NewRunoffTime - OldRunoffTime), clamped to [0,1] (routing.c:707). It weights EVERY subcatchment quantity handed to a node this step — the runoff flow in addWetWeatherInflows, and the washoff load right beside it in surfqual_getWtdWashoff. SWMMEngine::assembleLateralInflows forms it and publishes it here so the quality loaders use the same number rather than assuming a midpoint.

◆ runtime_coupling_used

bool openswmm::SimulationContext::runtime_coupling_used = false

Runtime prescriptions require a future restart format.

◆ snowpack_names

NameIndex openswmm::SimulationContext::snowpack_names

◆ snowpacks

SnowpackStore openswmm::SimulationContext::snowpacks

◆ spatial

SpatialFrame openswmm::SimulationContext::spatial

Coordinate reference system and georeferenced coordinates.

See also
Legacy: Coord[] in globals.h

◆ species_registry

SpeciesRegistry openswmm::SimulationContext::species_registry

Species registry — the single source of truth for transported constituents (master plan §4.1, phase T0a). Pollutants occupy the first slots (index-aligned with the legacy pollutant index); MSX species append via the reactions component (R1); reserved age/temperature species append with phases A1/H1. Rebuilt at each open().

◆ state

EngineState openswmm::SimulationContext::state = EngineState::CREATED

Current lifecycle state of the engine.

◆ state_accessors

StateAccessors openswmm::SimulationContext::state_accessors

Solver-neutral accessors for reading and writing solver-internal state at hot-start save/load time.

Wired by SWMMEngine at open() time so state-IO plugins can access per-subcatchment infiltration and groundwater state without depending on solver types.

◆ streets

StreetStore openswmm::SimulationContext::streets

◆ subcatch_d_store_pattern

std::vector<int> openswmm::SimulationContext::subcatch_d_store_pattern

◆ subcatch_infil_pattern

std::vector<int> openswmm::SimulationContext::subcatch_infil_pattern

◆ subcatch_n_perv_pattern

std::vector<int> openswmm::SimulationContext::subcatch_n_perv_pattern

Per-subcatchment pattern indices for N-PERV, DSTORE, INFIL adjustments.

Index into ctx.tables / pattern tables. -1 = no pattern.

See also
Legacy: Subcatch[i].nPervPattern, dStorePattern, infilPattern

◆ subcatch_names

NameIndex openswmm::SimulationContext::subcatch_names

Subcatchment name → subcatchment index.

See also
Legacy: project_findObject(SUBCATCH, name) in project.c

◆ subcatches

SubcatchData openswmm::SimulationContext::subcatches

All subcatchment state and properties.

See also
Legacy: Subcatch[], SubcatchStats[] in globals.h + TSubcatch

◆ surface_outfall_link_limit

std::vector<double> openswmm::SimulationContext::surface_outfall_link_limit

System mass-balance totals for the optional 2D surface domain.

Accumulated each executed 2D step by SurfaceRouter2D. Unlike the 1D MassBalance (ft³ for US flow units), all volumes here are in the 2D solver's SI internal units (m³). This is a SEPARATE balance from the 1D routing balance: the coupling terms are inflows/outflows of the 2D domain, signed oppositely to the 1D routing_external/routing_flooding terms.

◆ surface_outfall_quality

QualityOnlyInflow openswmm::SimulationContext::surface_outfall_quality

D2: booked as external inflow.

◆ tables

TableData openswmm::SimulationContext::tables

All time series and rating curves.

See also
Legacy: Tseries[], Curve[] in globals.h + TTable in objects.h

◆ title_notes

std::vector<std::string> openswmm::SimulationContext::title_notes

Project title and notes (from [TITLE] section).

Each entry is one line of free-form text from the [TITLE] section of the .inp file. Lines beginning with ";;" (comments) are stripped by the input reader before reaching the handler.

See also
Legacy: Title[MAXTITLE] in globals.h (limited to 3 lines)

◆ transect_tables

std::vector<transect::TransectData> openswmm::SimulationContext::transect_tables

Built transect geometry tables (indexed same as transects).

◆ transects

TransectStore openswmm::SimulationContext::transects

◆ treatment

TreatmentData openswmm::SimulationContext::treatment

◆ twod_io

struct openswmm::SimulationContext::TwoDModelIO openswmm::SimulationContext::twod_io

◆ unit_hyds

UnitHydData openswmm::SimulationContext::unit_hyds

Parsed [HYDROGRAPHS] data.

◆ unknown_section_headers

std::vector<std::pair<std::string, long> > openswmm::SimulationContext::unknown_section_headers

Every unknown section header read, as (token as written, 1-based line number), in file order — legacy's "Unknown section '%s' at line %ld" warning names both.

◆ user_flags

UserFlags openswmm::SimulationContext::user_flags

User-defined flags from [USER_FLAGS] section.

New in 6.0.0. No legacy equivalent.

See also
UserFlags.hpp

◆ vj_diag

struct openswmm::SimulationContext::VJDiag openswmm::SimulationContext::vj_diag

◆ wall_start

std::time_t openswmm::SimulationContext::wall_start = 0

Wall-clock time stamped at the start of SWMMEngine::open().

Reported as "Analysis begun on:" and used as the origin for "Total elapsed time:" in the .rpt. Stamped before input parsing so that parse + cross-reference resolution + validation + module initialization are all included in the reported elapsed time. This matches legacy, which takes its timestamp in report_writeLogo() before project_readInput() (see legacy/engine/report.c). Zero until open() runs.

◆ warning_code

int openswmm::SimulationContext::warning_code = 0

Most recent warning code (0 = no warning).

See also
Legacy: WarningCode in globals.h

◆ warnings

std::vector<std::string> openswmm::SimulationContext::warnings

Accumulated warning messages written to report file.

Matches legacy behavior where warnings are collected during validation and written after the title section in the .rpt file. Format: "WARNING NN: description for ObjectID"

See also
Legacy: report_writeWarningMsg() in report.c

◆ washoff

WashoffData openswmm::SimulationContext::washoff

◆ water_age_config

WaterAgeConfigData openswmm::SimulationContext::water_age_config

Water-age tracking (phase A1a): per-source initial ages parsed from the waterage component (model.age) + the runtime age state the engines and loaders share.

See also
data/WaterAgeData.hpp.

◆ water_age_state

WaterAgeState openswmm::SimulationContext::water_age_state

◆ xsect_generation

std::uint64_t openswmm::SimulationContext::xsect_generation = 0

Bumped whenever a link's cross-section/flow properties are recomputed mid-run (C-API setters via recompute_conduit_flow_properties), so consumers holding per-link XSectParams caches know to rebuild (e.g. SWMMEngine's reporting-path cache).


The documentation for this struct was generated from the following file: