OpenSWMM Engine  6.0.0-alpha.3
Data-oriented, plugin-extensible SWMM Engine (6.0.0-alpha.3)
Loading...
Searching...
No Matches
SurfaceStateData.hpp
Go to the documentation of this file.
1
15
16#ifndef OPENSWMM_ENGINE_2D_SURFACE_STATE_DATA_HPP
17#define OPENSWMM_ENGINE_2D_SURFACE_STATE_DATA_HPP
18
19#include <vector>
20#include <cstring>
21#include <cmath>
22#include <algorithm>
23#include <vector>
24
25namespace openswmm { struct NodeData; } // 1D node data (held during a 2D advance)
26
27namespace openswmm::twoD {
28
29struct CouplingPoint; // fwd decl — 1D↔2D coupling descriptor (NodeCoupling.hpp)
30struct ActiveSetData; // fwd decl — dry-cell wet-front mask (ActiveSetData.hpp)
31
39struct BoundaryData; // fwd decl — per-edge boundary conditions (BoundaryData.hpp)
40
42
43 // -----------------------------------------------------------------------
44 // State variables — per triangle [0, n_triangles)
45 // -----------------------------------------------------------------------
46
54 const BoundaryData* boundary = nullptr;
55
63 const NodeData* nodes_1d = nullptr;
64 const std::vector<CouplingPoint>* node_coupling = nullptr;
65
72 const ActiveSetData* active_set = nullptr;
73
74 std::vector<double> depth;
75 std::vector<double> head;
76 std::vector<double> volume;
77
78 // Gradient fields (per triangle)
79 std::vector<double> grad_hx;
80 std::vector<double> grad_hy;
81 std::vector<double> grad_hx_lim;
82 std::vector<double> grad_hy_lim;
83
84 // Reconstructed head at vertices — [0, n_vertices)
85 std::vector<double> vert_head;
86
87 // Cell-centred velocity (RT0 reconstruction from edge fluxes) — per triangle
88 std::vector<double> face_vx;
89 std::vector<double> face_vy;
90
91 // Per-cell continuity residual — per triangle (m³/s, ≈0 when conservative)
92 std::vector<double> cell_continuity_err;
93
94 // Fluxes — flat 2D: [tri * 3 + edge]
95 std::vector<double> edge_flux;
96
97 // Source/sink terms — per triangle
98 std::vector<double> rainfall;
99 std::vector<double> evap_rate;
100 std::vector<double> coupling_flux;
101 std::vector<double> net_source;
102
103 // -----------------------------------------------------------------------
104 // Forcing overrides (optional external control)
105 // -----------------------------------------------------------------------
106
107 std::vector<int8_t> rainfall_forced;
108 std::vector<int8_t> rainfall_persist;
109 std::vector<double> rainfall_force_val;
110 std::vector<int8_t> evap_forced;
111 std::vector<int8_t> evap_persist;
112 std::vector<double> evap_force_val;
113 std::vector<int8_t> coupling_forced;
114 std::vector<int8_t> coupling_persist;
115 std::vector<double> coupling_force_val;
116
117 // -----------------------------------------------------------------------
118 // Previous step state
119 // -----------------------------------------------------------------------
120
121 std::vector<double> old_depth;
122 std::vector<double> old_volume;
123
124 // -----------------------------------------------------------------------
125 // Cumulative statistics
126 // -----------------------------------------------------------------------
127
128 std::vector<double> stat_max_depth;
129 std::vector<double> stat_max_velocity;
130 std::vector<double> stat_max_cont_err;
131 std::vector<double> stat_cum_volume;
132
136 double evap_loss_total = 0.0;
137
138 // -----------------------------------------------------------------------
139 // Lifecycle
140 // -----------------------------------------------------------------------
141
142 void resize(int n_triangles, int n_vertices) {
143 auto nt = static_cast<std::size_t>(n_triangles);
144 auto nv = static_cast<std::size_t>(n_vertices);
145 auto n3 = nt * 3;
146
147 depth.assign(nt, 0.0);
148 head.assign(nt, 0.0);
149 volume.assign(nt, 0.0);
150 grad_hx.assign(nt, 0.0);
151 grad_hy.assign(nt, 0.0);
152 grad_hx_lim.assign(nt, 0.0);
153 grad_hy_lim.assign(nt, 0.0);
154 vert_head.assign(nv, 0.0);
155 face_vx.assign(nt, 0.0);
156 face_vy.assign(nt, 0.0);
157 cell_continuity_err.assign(nt, 0.0);
158 edge_flux.assign(n3, 0.0);
159 rainfall.assign(nt, 0.0);
160 evap_rate.assign(nt, 0.0);
161 coupling_flux.assign(nt, 0.0);
162 net_source.assign(nt, 0.0);
163
164 rainfall_forced.assign(nt, 0);
165 rainfall_persist.assign(nt, 0);
166 rainfall_force_val.assign(nt, 0.0);
167 evap_forced.assign(nt, 0);
168 evap_persist.assign(nt, 0);
169 evap_force_val.assign(nt, 0.0);
170 coupling_forced.assign(nt, 0);
171 coupling_persist.assign(nt, 0);
172 coupling_force_val.assign(nt, 0.0);
173
174 old_depth.assign(nt, 0.0);
175 old_volume.assign(nt, 0.0);
176 stat_max_depth.assign(nt, 0.0);
177 stat_max_velocity.assign(nt, 0.0);
178 stat_max_cont_err.assign(nt, 0.0);
179 stat_cum_volume.assign(nt, 0.0);
180 evap_loss_total = 0.0;
181 }
182
183 void save_state() noexcept {
184 std::memcpy(old_depth.data(), depth.data(),
185 depth.size() * sizeof(double));
186 std::memcpy(old_volume.data(), volume.data(),
187 volume.size() * sizeof(double));
188 }
189
190 void reset_state() noexcept {
191 std::memcpy(depth.data(), old_depth.data(),
192 old_depth.size() * sizeof(double));
193 std::memcpy(volume.data(), old_volume.data(),
194 old_volume.size() * sizeof(double));
195 }
196
198 void clear_reset_forcings() noexcept {
199 for (std::size_t i = 0; i < rainfall_forced.size(); ++i) {
200 if (rainfall_persist[i] == 0) {
201 rainfall_forced[i] = 0;
202 rainfall_force_val[i] = 0.0;
203 }
204 if (evap_persist[i] == 0) {
205 evap_forced[i] = 0;
206 evap_force_val[i] = 0.0;
207 }
208 if (coupling_persist[i] == 0) {
209 coupling_forced[i] = 0;
210 coupling_force_val[i] = 0.0;
211 }
212 }
213 }
214
222 void update_statistics([[maybe_unused]] const std::vector<double>& tri_area,
223 double dt,
224 [[maybe_unused]] int nthreads = 1) noexcept {
225 // Each cell updates only its own envelope slots (max/cum into [i]);
226 // schedule(static) keeps this bit-identical to serial for any thread
227 // count. int loop index for OpenMP canonical-loop form.
228 const int n = static_cast<int>(depth.size());
229#if defined(SWMM_USE_OPENMP)
230#pragma omp parallel for schedule(static) num_threads(nthreads)
231#endif
232 for (int i = 0; i < n; ++i) {
233 if (depth[i] > stat_max_depth[i])
234 stat_max_depth[i] = depth[i];
235
236 const double speed = std::sqrt(face_vx[i] * face_vx[i]
237 + face_vy[i] * face_vy[i]);
238 if (speed > stat_max_velocity[i])
239 stat_max_velocity[i] = speed;
240
241 const double aerr = std::abs(cell_continuity_err[i]);
242 if (aerr > stat_max_cont_err[i])
243 stat_max_cont_err[i] = aerr;
244
245 // Cell water volume × dt (VFR: V is the integrated state, not h̄·A).
246 stat_cum_volume[i] += volume[i] * dt;
247 }
248 }
249};
250
251} // namespace openswmm::twoD
252
253#endif // OPENSWMM_ENGINE_2D_SURFACE_STATE_DATA_HPP
Definition NodeCoupling.cpp:15
Definition NodeCoupling.cpp:15
Structure-of-Arrays storage for all nodes.
Definition NodeData.hpp:114
Definition ActiveSetData.hpp:39
SoA storage for per-edge boundary conditions.
Definition BoundaryData.hpp:55
Descriptor for a single coupling point between 2D and 1D.
Definition NodeCoupling.hpp:41
Definition SurfaceStateData.hpp:41
std::vector< double > grad_hy_lim
Limited gradient Y.
Definition SurfaceStateData.hpp:82
std::vector< double > grad_hy
∂h/∂y (unlimited gradient)
Definition SurfaceStateData.hpp:80
void save_state() noexcept
Definition SurfaceStateData.hpp:183
std::vector< int8_t > coupling_forced
0=computed, 1=override, 2=add
Definition SurfaceStateData.hpp:113
std::vector< double > coupling_flux
Exchange with SWMM node (m/s, + = into 2D)
Definition SurfaceStateData.hpp:100
std::vector< int8_t > rainfall_forced
0=computed, 1=override, 2=add
Definition SurfaceStateData.hpp:107
double evap_loss_total
Definition SurfaceStateData.hpp:136
std::vector< double > stat_max_depth
Maximum depth ψ_o seen at each cell (m)
Definition SurfaceStateData.hpp:128
std::vector< double > cell_continuity_err
Definition SurfaceStateData.hpp:92
const ActiveSetData * active_set
Definition SurfaceStateData.hpp:72
std::vector< double > net_source
Net source/sink per cell (m/s)
Definition SurfaceStateData.hpp:101
std::vector< double > rainfall_force_val
Forced rainfall value.
Definition SurfaceStateData.hpp:109
std::vector< double > stat_max_cont_err
Max |cell_continuity_err| (m³/s)
Definition SurfaceStateData.hpp:130
std::vector< double > stat_cum_volume
Cumulative volume through cell (m³)
Definition SurfaceStateData.hpp:131
std::vector< int8_t > evap_persist
0=reset, 1=persist
Definition SurfaceStateData.hpp:111
void clear_reset_forcings() noexcept
Clear RESET forcings after each step.
Definition SurfaceStateData.hpp:198
std::vector< double > depth
Mean wetted depth h̄ = V/A_wet (m) [reconstructed].
Definition SurfaceStateData.hpp:74
std::vector< double > face_vx
Cell velocity X component (m/s)
Definition SurfaceStateData.hpp:88
std::vector< double > grad_hx
∂h/∂x (unlimited gradient)
Definition SurfaceStateData.hpp:79
const std::vector< CouplingPoint > * node_coupling
non-outfall points
Definition SurfaceStateData.hpp:64
std::vector< double > rainfall
Rainfall intensity (m/s)
Definition SurfaceStateData.hpp:98
std::vector< double > volume
Cell water volume V (m³) — the integrated state.
Definition SurfaceStateData.hpp:76
std::vector< double > coupling_force_val
Forced coupling value.
Definition SurfaceStateData.hpp:115
std::vector< double > evap_force_val
Forced evaporation value.
Definition SurfaceStateData.hpp:112
std::vector< double > vert_head
Head reconstructed at vertices.
Definition SurfaceStateData.hpp:85
std::vector< int8_t > evap_forced
0=computed, 1=override, 2=add
Definition SurfaceStateData.hpp:110
void reset_state() noexcept
Definition SurfaceStateData.hpp:190
std::vector< double > head
Free-surface elevation η (m) [reconstructed].
Definition SurfaceStateData.hpp:75
std::vector< double > grad_hx_lim
Limited gradient X.
Definition SurfaceStateData.hpp:81
const NodeData * nodes_1d
Definition SurfaceStateData.hpp:63
std::vector< int8_t > coupling_persist
0=reset, 1=persist
Definition SurfaceStateData.hpp:114
void resize(int n_triangles, int n_vertices)
Definition SurfaceStateData.hpp:142
std::vector< double > face_vy
Cell velocity Y component (m/s)
Definition SurfaceStateData.hpp:89
std::vector< double > evap_rate
Evaporation demand rate (m/s, >= 0)
Definition SurfaceStateData.hpp:99
std::vector< double > stat_max_velocity
Max cell speed |v| = √(vx²+vy²) (m/s)
Definition SurfaceStateData.hpp:129
const BoundaryData * boundary
Definition SurfaceStateData.hpp:54
std::vector< double > old_depth
Mean depth at start of coupling interval.
Definition SurfaceStateData.hpp:121
std::vector< int8_t > rainfall_persist
0=reset, 1=persist
Definition SurfaceStateData.hpp:108
std::vector< double > old_volume
Volume at start of coupling interval (m³)
Definition SurfaceStateData.hpp:122
void update_statistics(const std::vector< double > &tri_area, double dt, int nthreads=1) noexcept
Definition SurfaceStateData.hpp:222
std::vector< double > edge_flux
Normal flux through each edge.
Definition SurfaceStateData.hpp:95