![]() |
OpenSWMM Engine
6.0.0-alpha.3
Data-oriented, plugin-extensible SWMM Engine (6.0.0-alpha.3)
|
Structure-of-Arrays storage for all nodes. More...
#include <NodeData.hpp>
Public Member Functions | |
| int | count () const noexcept |
| Number of nodes. | |
| void | resize (int n) |
Resize all arrays to hold exactly n nodes. | |
| void | grow_to (int n) |
Grow all arrays to hold at least n nodes, preserving existing data. | |
| void | erase_at (int idx) |
Erase the node at index idx from every parallel array. | |
| void | resize_loads (int n_pollutants) |
| Resize pollutant load arrays after pollutant count is known. | |
| void | resize_quality (int n_pollutants) |
| Resize per-node quality arrays after pollutant count is known. | |
| void | shrink_to_fit () |
| Release excess vector capacity accumulated during parsing. | |
| void | save_state () noexcept |
| Snapshot current state into old-step arrays before solving. | |
| void | reset_state () noexcept |
| Reset state variables, applying init_depth from input. | |
| void | clearInflowSources () noexcept |
| Zero routing-phase inflow source arrays. | |
Public Attributes | |
| std::vector< NodeType > | type |
| Node type for each node. | |
| std::vector< double > | invert_elev |
| Invert elevation (project length units). | |
| std::vector< double > | full_depth |
| Full depth of the node (project length units). | |
| std::vector< double > | init_depth |
| Initial water depth (project length units). | |
| std::vector< double > | sur_depth |
| Maximum depth allowed at the node (ponding or surcharge limit). | |
| std::vector< double > | ponded_area |
| Ponding area at the surface (sq project length units). | |
| std::vector< double > | depth |
| Current water depth above invert (project length units). | |
| std::vector< double > | head |
| Current water surface head (project length units = invert + depth). | |
| std::vector< double > | volume |
| Current water volume (project volume units). | |
| std::vector< double > | lat_flow |
| Current lateral inflow (project flow units). | |
| std::vector< double > | user_lat_flow |
| User-forced lateral inflow set via the API (project flow units). | |
| std::vector< double > | runoff_inflow |
| Interpolated surface runoff from subcatchments (project flow units). | |
| std::vector< double > | gw_inflow |
| Interpolated groundwater flow from subcatchments (project flow units). | |
| std::vector< double > | ext_inflow |
| External (timeseries/baseline) inflows (project flow units). | |
| std::vector< double > | dwf_inflow |
| Dry weather flow inflows (project flow units). | |
| std::vector< double > | rdii_inflow |
| RDII unit hydrograph inflows (project flow units). | |
| std::vector< double > | iface_inflow |
| Interface file (upstream model coupling) inflows (project flow units). | |
| std::vector< double > | coupling_inflow |
| 2D ↔ 1D coupling exchange flow at the node (project flow units). | |
| std::vector< double > | coupling_volume |
| Pending 1D↔2D exchange VOLUME for the next routing step (1D units, ft³). | |
| std::vector< double > | qual_mass_in |
| Accumulated quality mass inflow rate per (node, pollutant). | |
| std::vector< double > | qual_vol_in |
| Accumulated volume inflow rate per node (ft3/sec). | |
| std::vector< double > | iface_qual_mass |
| Routing interface file quality mass rate per (node, pollutant) (mass/sec). | |
| std::vector< double > | lid_drain_qual_load |
| LID drain quality mass rate per (node, pollutant) (mass/sec). | |
| std::vector< double > | lid_drain_qual_vol |
| LID drain volume inflow rate per node (ft3/sec). | |
| std::vector< double > | conc |
| Current quality concentration at each node. | |
| std::vector< double > | conc_old |
| Previous-step quality at each node. | |
| std::vector< double > | hrt |
| Hydraulic residence time for storage nodes (seconds). | |
| std::vector< double > | user_conc_mass_flux |
| User-forced quality mass flux at each node (mass/sec). | |
| int | conc_n_pollutants = 0 |
| Number of pollutants in the quality arrays. | |
| std::vector< double > | inflow |
| Current total inflow to the node (project flow units). | |
| std::vector< double > | outflow |
| Current total outflow from the node (project flow units). | |
| std::vector< double > | overflow |
| Current overflow / ponded flow (project flow units). | |
| std::vector< double > | losses |
| Node losses (evaporation + seepage) (project flow units). | |
| std::vector< double > | crown_elev |
| Crown elevation — top of highest connecting conduit (project length units). | |
| std::vector< int > | degree |
| Node degree — number of connecting links (+ve downstream, -ve upstream terminal). | |
| std::vector< double > | old_net_inflow |
| Net inflow from previous timestep (inflow - outflow) for averaging. | |
| std::vector< double > | full_volume |
| Full volume at node (project volume units). | |
| std::vector< double > | old_depth |
| Depth at the previous timestep. | |
| std::vector< double > | old_volume |
| Volume at the previous timestep. | |
| std::vector< double > | old_lat_flow |
| Lateral flow at the previous timestep. | |
| std::vector< double > | old_inflow |
| Total inflow at the previous timestep (for output interpolation). | |
| std::vector< std::string > | comments |
| Object comment from the INP file (lines with a single ';' prefix immediately above this object's data row). | |
| std::vector< std::string > | tags |
Per-object tag from the INP [TAGS] section. | |
| std::vector< char > | rpt_flag |
| Whether this node is included in report/output (0=no, 1=yes). | |
| std::vector< double > | stat_vol_flooded |
| Total volume of water lost as overflow (project volume units). | |
| std::vector< double > | stat_time_flooded |
| Total duration the node was flooded (seconds). | |
| std::vector< double > | stat_max_depth |
| Maximum reported depth (project length units). | |
| std::vector< double > | stat_max_overflow |
| Maximum reported overflow rate (project flow units). | |
| std::vector< double > | stat_max_overflow_date |
| Date/time when maximum overflow occurred (OADate (days since 12/30/1899)). | |
| std::vector< double > | stat_sum_depth |
| std::vector< double > | stat_sum_volume |
| std::vector< double > | stat_max_depth_date |
| std::vector< double > | stat_max_rpt_depth |
| std::vector< double > | stat_max_inflow_date |
| std::vector< double > | stat_time_surcharged |
| std::vector< double > | stat_max_surcharge_height |
| std::vector< double > | stat_outfall_avg_flow |
| Outfall cumulative average flow (flow units × reporting periods). | |
| std::vector< double > | stat_max_lat_inflow |
| std::vector< double > | stat_max_total_inflow |
| std::vector< double > | stat_lat_inflow_vol |
| std::vector< double > | stat_total_inflow_vol |
| Cumulative total inflow volume at each node (ft3). | |
| std::vector< double > | stat_total_outflow_vol |
| std::vector< double > | stat_outfall_max_flow |
| Outfall maximum flow (project flow units). | |
| std::vector< long > | stat_outfall_periods |
| Outfall number of non-zero flow periods. | |
| std::vector< int > | stat_non_converged_count |
| Count of non-converging steps per node. | |
| std::vector< double > | stat_time_courant_critical |
| CFL time-step critical count per node. | |
| std::vector< double > | stat_total_load |
| Cumulative pollutant loads at each node. | |
| int | stat_n_pollutants = 0 |
Structure-of-Arrays storage for all nodes.
All parallel arrays are indexed by node index [0, count). Use SimulationContext::node_names to translate name → index.
Fields are divided into:
|
inlinenoexcept |
Zero routing-phase inflow source arrays.
Called at the start of each routing step before processes write to their respective source arrays.
NOTE: runoff_inflow and gw_inflow are zeroed in stepRunoff() Phase 2 before subcatchment accumulation (matching legacy initSystemInflows which zeros newLatFlow each routing step).
|
inlinenoexcept |
Number of nodes.
|
inline |
Erase the node at index idx from every parallel array.
Removes the element at idx from every SoA vector. For flat-2D quality arrays indexed as [node * n_pollutants + p], the full stride for idx is removed. Spatial arrays are NOT touched here; ObjectDeleter erases spatial data separately after calling this. Only call in BUILDING or OPENED state.
|
inline |
Grow all arrays to hold at least n nodes, preserving existing data.
Called by ensure_node_capacity() during incremental INP parsing. Uses vector::resize() (not assign) so existing elements are preserved. New elements get the same defaults as resize().
|
inlinenoexcept |
Reset state variables, applying init_depth from input.
Matches legacy node_initState() which sets oldDepth = initDepth and computes initial volume from depth. Flows and inflows are zeroed for a cold start.
|
inline |
Resize all arrays to hold exactly n nodes.
Called once during input parsing after the total node count is known. All numeric arrays are zero-initialized; type arrays use JUNCTION as the default.
|
inline |
Resize pollutant load arrays after pollutant count is known.
|
inline |
Resize per-node quality arrays after pollutant count is known.
|
inlinenoexcept |
Snapshot current state into old-step arrays before solving.
|
inline |
Release excess vector capacity accumulated during parsing.
Called once after final sizing is complete. Each vector's capacity is reduced to match its size, freeing memory that was over-allocated by geometric growth during incremental parsing.
| std::vector<std::string> openswmm::NodeData::comments |
Object comment from the INP file (lines with a single ';' prefix immediately above this object's data row).
Multiple comment lines are joined by the literal two-character token "\\n" (backslash + n). Empty string means no comment. Written back to INP by InpWriter as one ';'-prefixed row per part. Also stored verbatim in the GeoPackage 'comment' column.
| std::vector<double> openswmm::NodeData::conc |
Current quality concentration at each node.
Size = n_nodes * n_pollutants.
| int openswmm::NodeData::conc_n_pollutants = 0 |
Number of pollutants in the quality arrays.
| std::vector<double> openswmm::NodeData::conc_old |
Previous-step quality at each node.
| std::vector<double> openswmm::NodeData::coupling_inflow |
2D ↔ 1D coupling exchange flow at the node (project flow units).
Signed: positive = 2D → 1D (surface drainage into the node), negative = 1D → 2D (surcharge spill onto the surface). Written by SurfaceRouter2D::advancePostRouting at the end of step N; read by assembleLateralInflows at the start of step N+1 (so the value persists across the step boundary and is consumed exactly once by the DW solver).
For mass-balance accounting the signed value is split:
This replaces the earlier scheme of routing coupling Q through forcing.node_lat_inflow_value, which conflated user forcing with 2D coupling and dropped the negative (1D→2D) volume from the mass balance entirely.
| std::vector<double> openswmm::NodeData::coupling_volume |
Pending 1D↔2D exchange VOLUME for the next routing step (1D units, ft³).
The exchange is carried across the staggered-coupling step boundary as a volume (not a rate) so it stays mass-conservative under VARIABLE_STEP: the producer (computeCouplingExchange / the live-RHS booking) writes Q·dt here at the end of step N; the consumer (assembleLateralInflows) re-derives the rate coupling_inflow = coupling_volume/dt at the start of step N+1 and clears this, so the 1D node receives exactly the volume 2D exchanged regardless of how the timestep changes. Signed: + = 2D→1D drain, − = 1D→2D spill. In-memory only (not serialized to hotstart). See plan / review §11.
| std::vector<double> openswmm::NodeData::crown_elev |
Crown elevation — top of highest connecting conduit (project length units).
| std::vector<int> openswmm::NodeData::degree |
| std::vector<double> openswmm::NodeData::depth |
Current water depth above invert (project length units).
| std::vector<double> openswmm::NodeData::dwf_inflow |
Dry weather flow inflows (project flow units).
| std::vector<double> openswmm::NodeData::ext_inflow |
External (timeseries/baseline) inflows (project flow units).
| std::vector<double> openswmm::NodeData::full_depth |
Full depth of the node (project length units).
| std::vector<double> openswmm::NodeData::full_volume |
Full volume at node (project volume units).
| std::vector<double> openswmm::NodeData::gw_inflow |
Interpolated groundwater flow from subcatchments (project flow units).
| std::vector<double> openswmm::NodeData::head |
Current water surface head (project length units = invert + depth).
| std::vector<double> openswmm::NodeData::hrt |
Hydraulic residence time for storage nodes (seconds).
| std::vector<double> openswmm::NodeData::iface_inflow |
Interface file (upstream model coupling) inflows (project flow units).
| std::vector<double> openswmm::NodeData::iface_qual_mass |
Routing interface file quality mass rate per (node, pollutant) (mass/sec).
Written by iface::InterfaceManager::readInflows() each routing step (cleared in clearInflowSources()); read by QualitySolver::addIfaceLoads() → added to qual_mass_in. Flat 2D: [node * n_pollutants + pollutant].
| std::vector<double> openswmm::NodeData::inflow |
| std::vector<double> openswmm::NodeData::init_depth |
Initial water depth (project length units).
| std::vector<double> openswmm::NodeData::invert_elev |
Invert elevation (project length units).
| std::vector<double> openswmm::NodeData::lat_flow |
Current lateral inflow (project flow units).
| std::vector<double> openswmm::NodeData::lid_drain_qual_load |
LID drain quality mass rate per (node, pollutant) (mass/sec).
Set once per runoff step (cleared at runoff step start); read each routing step by addWetWeatherLoads() → added to qual_mass_in. Flat 2D: [node * n_pollutants + pollutant]. Covers drain-to-node and drain-to-subcatch (routed to outlet node). Matches legacy lid_addDrainInflow() / lid_addDrainRunon() quality.
| std::vector<double> openswmm::NodeData::lid_drain_qual_vol |
LID drain volume inflow rate per node (ft3/sec).
Set once per runoff step; read each routing step by addWetWeatherLoads() → added to qual_vol_in (denominator for mixing).
| std::vector<double> openswmm::NodeData::losses |
| std::vector<double> openswmm::NodeData::old_depth |
Depth at the previous timestep.
| std::vector<double> openswmm::NodeData::old_inflow |
Total inflow at the previous timestep (for output interpolation).
| std::vector<double> openswmm::NodeData::old_lat_flow |
Lateral flow at the previous timestep.
| std::vector<double> openswmm::NodeData::old_net_inflow |
Net inflow from previous timestep (inflow - outflow) for averaging.
| std::vector<double> openswmm::NodeData::old_volume |
Volume at the previous timestep.
| std::vector<double> openswmm::NodeData::outflow |
| std::vector<double> openswmm::NodeData::overflow |
| std::vector<double> openswmm::NodeData::ponded_area |
Ponding area at the surface (sq project length units).
| std::vector<double> openswmm::NodeData::qual_mass_in |
Accumulated quality mass inflow rate per (node, pollutant).
Flat 2D: [node * n_pollutants + pollutant]. Units: mass/sec.
| std::vector<double> openswmm::NodeData::qual_vol_in |
Accumulated volume inflow rate per node (ft3/sec).
| std::vector<double> openswmm::NodeData::rdii_inflow |
RDII unit hydrograph inflows (project flow units).
| std::vector<char> openswmm::NodeData::rpt_flag |
Whether this node is included in report/output (0=no, 1=yes).
| std::vector<double> openswmm::NodeData::runoff_inflow |
Interpolated surface runoff from subcatchments (project flow units).
| std::vector<double> openswmm::NodeData::stat_lat_inflow_vol |
Cumulative lateral inflow volume at each node (ft3).
| std::vector<double> openswmm::NodeData::stat_max_depth |
Maximum reported depth (project length units).
| std::vector<double> openswmm::NodeData::stat_max_depth_date |
Date/time when maximum depth occurred (OADate (days since 12/30/1899)).
| std::vector<double> openswmm::NodeData::stat_max_inflow_date |
Date/time when maximum total inflow occurred (OADate (days since 12/30/1899)).
| std::vector<double> openswmm::NodeData::stat_max_lat_inflow |
Maximum lateral inflow at each node (project flow units).
| std::vector<double> openswmm::NodeData::stat_max_overflow |
Maximum reported overflow rate (project flow units).
| std::vector<double> openswmm::NodeData::stat_max_overflow_date |
Date/time when maximum overflow occurred (OADate (days since 12/30/1899)).
| std::vector<double> openswmm::NodeData::stat_max_rpt_depth |
Maximum reported depth (used for output-step max tracking).
| std::vector<double> openswmm::NodeData::stat_max_surcharge_height |
| std::vector<double> openswmm::NodeData::stat_max_total_inflow |
Maximum total inflow at each node (project flow units).
| int openswmm::NodeData::stat_n_pollutants = 0 |
| std::vector<int> openswmm::NodeData::stat_non_converged_count |
Count of non-converging steps per node.
Incremented when a routing step fails to converge and the node itself did not converge (matching legacy NodeStats[i].nonConvergedCount).
| std::vector<double> openswmm::NodeData::stat_outfall_avg_flow |
Outfall cumulative average flow (flow units × reporting periods).
| std::vector<double> openswmm::NodeData::stat_outfall_max_flow |
Outfall maximum flow (project flow units).
| std::vector<long> openswmm::NodeData::stat_outfall_periods |
Outfall number of non-zero flow periods.
| std::vector<double> openswmm::NodeData::stat_sum_depth |
Cumulative depth for computing average (project length units × seconds).
| std::vector<double> openswmm::NodeData::stat_sum_volume |
Cumulative stored volume for computing average (internal ft³), storage nodes only. Accumulated per routing step alongside stat_sum_depth so the Storage Volume Summary's average is the true time-average of the node's nonlinear volume, not volume-of-the-average-depth (which understates a convex curve).
| std::vector<double> openswmm::NodeData::stat_time_courant_critical |
CFL time-step critical count per node.
Incremented when the node's depth-change rate produces the smallest CFL-limited timestep (matching legacy NodeStats[i].timeCourantCritical).
| std::vector<double> openswmm::NodeData::stat_time_flooded |
Total duration the node was flooded (seconds).
| std::vector<double> openswmm::NodeData::stat_time_surcharged |
Total time node was surcharged (seconds).
| std::vector<double> openswmm::NodeData::stat_total_inflow_vol |
Cumulative total inflow volume at each node (ft3).
| std::vector<double> openswmm::NodeData::stat_total_load |
Cumulative pollutant loads at each node.
Flat 2D: [node * n_pollutants + p]. Only meaningful for outfall nodes. Resized by resize_loads() after pollutant count is known.
| std::vector<double> openswmm::NodeData::stat_total_outflow_vol |
Cumulative total outflow volume at each node (ft3).
| std::vector<double> openswmm::NodeData::stat_vol_flooded |
Total volume of water lost as overflow (project volume units).
| std::vector<double> openswmm::NodeData::sur_depth |
Maximum depth allowed at the node (ponding or surcharge limit).
| std::vector<std::string> openswmm::NodeData::tags |
Per-object tag from the INP [TAGS] section.
Free-form string label, used by GUIs for filtering and grouping (e.g. catchment-name labels, asset IDs, user-defined groups). Empty string means no tag. Written back to INP by InpWriter as a Node <name> <tag> row in [TAGS]. Index-keyed (per-NodeData field) so swmm_node_rename keeps the tag attached — the earlier name-keyed SimulationContext::node_tags map lost tags on rename.
| std::vector<NodeType> openswmm::NodeData::type |
Node type for each node.
| std::vector<double> openswmm::NodeData::user_conc_mass_flux |
User-forced quality mass flux at each node (mass/sec).
Flat 2D: [node * n_pollutants + pollutant]. Unlike the transient forcing in ForcingData, this persists until the user explicitly changes it and is applied as an additive mass source at each routing step (analogous to user_lat_flow for flow).
| std::vector<double> openswmm::NodeData::user_lat_flow |
User-forced lateral inflow set via the API (project flow units).
Unlike lat_flow, this is not cleared between routing steps. The value persists until the user explicitly changes it and is added to lat_flow at each routing step.
| std::vector<double> openswmm::NodeData::volume |
Current water volume (project volume units).