OpenSWMM Engine  6.0.0-alpha.4
Data-oriented, plugin-extensible SWMM Engine (6.0.0-alpha.4)
Loading...
Searching...
No Matches
SurfaceTransportState.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
58
59#ifndef OPENSWMM_ENGINE_2D_SURFACE_TRANSPORT_STATE_HPP
60#define OPENSWMM_ENGINE_2D_SURFACE_TRANSPORT_STATE_HPP
61
62#include <cstddef>
63#include <string>
64#include <string_view>
65#include <vector>
66#include <map>
67
68namespace openswmm::twoD {
69
71 int n_species = 0;
72 int n_cells = 0;
73
74 // ---- S4 row layout — the 1D engines' convention, verbatim -------------
75 // rows [0, n_pollut) pollutants; [n_pollut, n_pollut + n_msx) MSX species
76 // in ReactionData order; then the reserved __WATER_AGE__ row; then the
77 // reserved __TEMPERATURE__ row LAST (H1 fixed the reported column order
78 // so adding heat to an age model never moves the age column). Set by the
79 // router after resize(); -1 ⇒ the row is not carried.
80 int n_pollut = 0;
81 int n_msx = 0;
82 int age_row = -1;
83 int temp_row = -1;
87 std::vector<std::string> row_names;
98 bool signedRow(int s) const noexcept { return s == temp_row; }
105 int rowIndex(std::string_view name) const noexcept {
106 for (std::size_t i = 0; i < row_names.size(); ++i)
107 if (row_names[i] == name)
108 return static_cast<int>(i);
109 return -1;
110 }
111
115 std::vector<double> cell_mass;
116
117 // ---- Ledgers (per species), m³·conc, cumulative over the run. ----------
118 // These are what S3's coupling tuple and the continuity table will read;
119 // in S1 they are the record that mass left the surface and where.
120 std::vector<double> lost_infiltration;
121 std::vector<double> lost_boundary;
122 std::vector<double> gained_external, lost_external;
123 std::vector<double>
125 std::vector<double> lost_coupling;
129 std::vector<double> exch_mass;
139 std::vector<double> exch_spill;
140
141 // ---- S2 source concentrations (species units) -------------------------
144 std::vector<double> rain_conc;
149 std::vector<double> bc_conc;
150 std::map<int, std::vector<double>> runtime_bc_conc;
154 int slot = -1;
155 int species = -1;
156 double conc = 0.0;
157 };
158 std::vector<BoundaryQualityRow> bc_quality_rows;
159
160 // ---- S2 dispersion limiter telemetry ----------------------------------
167
170 std::vector<double> gained_rainfall;
171 std::vector<double> gained_boundary;
174 std::vector<double> gained_coupling;
177 std::vector<double> gained_exfiltration;
178 std::vector<double>
183 std::vector<double> gained_washoff;
194 std::vector<double> cell_runoff_vol;
195
196 // ---- S3 outfall-discharge species source ------------------------------
204 std::vector<double> coupling_src;
205
211 bool active() const noexcept { return n_species > 0 && n_cells > 0; }
212
225 void resize(int n_spec, int n_tri, int n_coupling_points) {
226 n_species = (n_spec > 0) ? n_spec : 0;
227 n_cells = (n_tri > 0) ? n_tri : 0;
229 n_msx = 0;
230 age_row = -1;
231 temp_row = -1; // S4: router refines
232
233 row_names.clear();
234 const auto ns = static_cast<std::size_t>(n_species);
235 cell_mass.assign(ns * static_cast<std::size_t>(n_cells), 0.0);
236 lost_infiltration.assign(ns, 0.0);
237 lost_boundary.assign(ns, 0.0);
238 gained_external.assign(ns, 0.0);
239 lost_external.assign(ns, 0.0);
240 gained_bed.clear();
241 lost_coupling.assign(ns, 0.0);
242 exch_mass.assign(
243 ns * static_cast<std::size_t>(n_coupling_points > 0 ? n_coupling_points : 0), 0.0);
244 exch_spill.assign(static_cast<std::size_t>(n_coupling_points > 0 ? n_coupling_points : 0),
245 0.0);
246 rain_conc.clear(); // S2: router fills when pollutants carry one
247 runtime_bc_conc.clear();
248 bc_conc.clear(); // S2: solver sizes at initialize
249 bc_quality_rows.clear();
251 gained_rainfall.assign(ns, 0.0);
252 gained_boundary.assign(ns, 0.0);
253 gained_coupling.assign(ns, 0.0);
254 gained_exfiltration.assign(ns, 0.0); // T7.1
255 generated_age.clear();
256 coupling_src.clear(); // S3: router sizes when outfalls exist
257 }
258
265 void clear() { *this = SurfaceTransportState{}; }
266
274 std::size_t idx(int s, int c) const noexcept {
275 return static_cast<std::size_t>(s) * static_cast<std::size_t>(n_cells) +
276 static_cast<std::size_t>(c);
277 }
278
293 double concentration(int s, int c, double volume_m3, double dry_volume_m3) const noexcept {
294 if (!(volume_m3 > dry_volume_m3))
295 return 0.0;
296 return cell_mass[idx(s, c)] / volume_m3;
297 }
298
313 double totalIncludingLedgers(int s) const noexcept {
314 double m = 0.0;
315 const auto base = static_cast<std::size_t>(s) * static_cast<std::size_t>(n_cells);
316 for (int c = 0; c < n_cells; ++c)
317 m += cell_mass[base + static_cast<std::size_t>(c)];
318 const auto us = static_cast<std::size_t>(s);
319 // Sources are SUBTRACTED so the quantity is "what was there at t=0":
320 // surface + everything that left − everything that arrived.
321 return m + lost_infiltration[us] + lost_boundary[us] + lost_coupling[us] +
323 (us < gained_rainfall.size() ? gained_rainfall[us] : 0.0) -
324 (us < gained_boundary.size() ? gained_boundary[us] : 0.0) -
325 (us < gained_coupling.size() ? gained_coupling[us] : 0.0) -
326 (us < gained_washoff.size() ? gained_washoff[us] : 0.0) -
327 (us < gained_exfiltration.size() ? gained_exfiltration[us] : 0.0) -
328 (us < generated_age.size() ? generated_age[us] : 0.0);
329 }
330};
331
332} // namespace openswmm::twoD
333
334#endif // OPENSWMM_ENGINE_2D_SURFACE_TRANSPORT_STATE_HPP
Definition ExchangeLaw.hpp:60
Definition SurfaceTransportState.hpp:153
double conc
Definition SurfaceTransportState.hpp:156
int slot
Definition SurfaceTransportState.hpp:154
int species
Definition SurfaceTransportState.hpp:155
Definition SurfaceTransportState.hpp:70
std::vector< double > cell_mass
Definition SurfaceTransportState.hpp:115
std::vector< double > gained_washoff
Definition SurfaceTransportState.hpp:183
std::vector< double > gained_exfiltration
Definition SurfaceTransportState.hpp:177
std::vector< double > lost_boundary
left through an open edge
Definition SurfaceTransportState.hpp:121
std::vector< double > exch_mass
Definition SurfaceTransportState.hpp:129
std::vector< double > rain_conc
Definition SurfaceTransportState.hpp:144
int rowIndex(std::string_view name) const noexcept
Resolve an exact species name in the current transport layout.
Definition SurfaceTransportState.hpp:105
std::vector< double > generated_age
Definition SurfaceTransportState.hpp:179
bool active() const noexcept
Test whether cell transport arrays have a nonempty layout.
Definition SurfaceTransportState.hpp:211
std::vector< double > cell_runoff_vol
Definition SurfaceTransportState.hpp:194
std::vector< double > lost_infiltration
left through the bed
Definition SurfaceTransportState.hpp:120
std::map< int, std::vector< double > > runtime_bc_conc
Definition SurfaceTransportState.hpp:150
void clear()
Replace the complete surface transport state with empty defaults.
Definition SurfaceTransportState.hpp:265
bool signedRow(int s) const noexcept
The temperature row is SIGNED (°C below zero is a state, not an error): every "mass≥ 0" guard in the ...
Definition SurfaceTransportState.hpp:98
int age_row
Definition SurfaceTransportState.hpp:82
std::vector< double > gained_rainfall
Definition SurfaceTransportState.hpp:170
long dispersion_limiter_binds
Definition SurfaceTransportState.hpp:166
std::size_t idx(int s, int c) const noexcept
Map a species/cell pair into species-major storage.
Definition SurfaceTransportState.hpp:274
double totalIncludingLedgers(int s) const noexcept
Total mass of one species over the surface + every ledger — the quantity the S1 conservation gate ass...
Definition SurfaceTransportState.hpp:313
std::vector< double > gained_external
Definition SurfaceTransportState.hpp:122
std::vector< double > coupling_src
Definition SurfaceTransportState.hpp:204
int n_cells
Definition SurfaceTransportState.hpp:72
std::vector< double > gained_coupling
Definition SurfaceTransportState.hpp:174
int n_msx
Definition SurfaceTransportState.hpp:81
std::vector< double > bc_conc
Definition SurfaceTransportState.hpp:149
std::vector< double > gained_boundary
Definition SurfaceTransportState.hpp:171
void resize(int n_spec, int n_tri, int n_coupling_points)
Reset core transport inventory and ledgers to a new tuple/cell layout.
Definition SurfaceTransportState.hpp:225
std::vector< double > lost_coupling
Definition SurfaceTransportState.hpp:125
std::vector< std::string > row_names
Definition SurfaceTransportState.hpp:87
int n_pollut
Definition SurfaceTransportState.hpp:80
double concentration(int s, int c, double volume_m3, double dry_volume_m3) const noexcept
Reported concentration — derived, never stored. dry_volume_m3 is the hydraulics' own dry threshold ex...
Definition SurfaceTransportState.hpp:293
std::vector< double > exch_spill
Definition SurfaceTransportState.hpp:139
std::vector< double > gained_bed
signed finite-bed -> surface exchange; empty in compatibility mode
Definition SurfaceTransportState.hpp:124
int temp_row
Definition SurfaceTransportState.hpp:83
int n_species
rows carried; 0 ⇒ transport is off everywhere
Definition SurfaceTransportState.hpp:71
std::vector< BoundaryQualityRow > bc_quality_rows
Definition SurfaceTransportState.hpp:158
std::vector< double > lost_external
Definition SurfaceTransportState.hpp:122