OpenSWMM Engine  6.0.0-alpha.4
Data-oriented, plugin-extensible SWMM Engine (6.0.0-alpha.4)
Loading...
Searching...
No Matches
Runoff.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
37
46
47#ifndef OPENSWMM_RUNOFF_HPP
48#define OPENSWMM_RUNOFF_HPP
49
51#include "surface/InfilBank.hpp"
52#include <vector>
53#include <array>
54#include <functional>
55#include <utility>
56
57namespace openswmm::detail {
59}
60
61namespace openswmm {
62
64
65namespace runoff {
66
72 int subcatch = -1;
73 double rain = 0.0, pet = 0.0;
74 std::array<double, 3> surface_return{}; // ft/s by IMPERV0/IMPERV1/PERV; never rain
75 double raw_precipitation = -1; // before subcatchment scales and phase partition
76 double pet_imperv = -1, pet_perv = -1; // optional exposed atmospheric footprints
77};
78
81 double area = 0, opening = 0, rain = 0, runon = 0, evaporation = 0;
82 double infiltration = 0, spatial_infiltration = 0, outflow = 0, outlet = 0, closing = 0;
83};
84
85// ============================================================================
86// Constants
87// ============================================================================
88
89constexpr double MEXP =
90 1.6666667;
91constexpr double ODETOL = 0.0001;
92constexpr double PHI = 1.486;
93
94// ============================================================================
95// Per-subcatchment subarea state (SoA for vectorization)
96// ============================================================================
97
98struct RunoffSoA {
99 int n_subcatch = 0;
100
101 // Per-subcatchment properties (set at init)
102 std::vector<double> area;
103 std::vector<double> width;
104 std::vector<double> slope;
105 std::vector<double> imperv_pct;
116 std::vector<double> frac_imperv0;
117 std::vector<double> frac_imperv1;
118
119 // Per-subarea SoA: alpha = runoff coefficient
120 std::vector<double> alpha_imperv;
121 std::vector<double> alpha_perv;
122
123 // Per-subarea SoA: depression storage (ft)
124 std::vector<double> ds_imperv;
125 std::vector<double> ds_perv;
126
127 // Per-subarea SoA: Manning's n
128 std::vector<double> n_imperv;
129 std::vector<double> n_perv;
130
131 // Per-subarea SoA: ponded depth (state, updated each step)
132 std::vector<double> depth_imperv0;
133 std::vector<double> depth_imperv1;
134 std::vector<double> depth_perv;
135
136 // Per-subarea SoA: previous-step runoff rates (ft/sec, area-averaged)
137 // Used for inter-subarea routing (legacy subcatch_getRunon)
138 std::vector<double> old_runoff_imperv0;
139 std::vector<double> old_runoff_imperv1;
140 std::vector<double> old_runoff_perv;
141
142 // Per-subcatchment: computed runoff (output)
143 std::vector<double> runoff;
144 std::vector<double> evap_loss;
145 std::vector<double>
147 std::vector<double>
149 std::vector<double>
153 std::vector<double> infil_vol;
158 std::vector<double> subarea_runoff_rate;
159
160 // Per-subcatchment: per-subarea runoff CFS from non-LID area (Gap #23)
161 // Used by SWMMEngine to compute LID unit inflow from impervious/pervious fractions.
162 std::vector<double> imperv_runoff_cfs;
163 std::vector<double> perv_runoff_cfs;
168 std::vector<double> outflow_vol;
169 std::vector<std::array<CompletedSubareaWater, 3>> completed;
170
176 void resize(int n);
183 void computeAlpha();
184};
185
186// ============================================================================
187// Runoff solver
188// ============================================================================
189
196public:
204 using InfiltrationBoundary = std::function<bool(int, double, double, double&)>;
216 void init(SimulationContext& ctx,
217 const std::vector<std::pair<int, double>>& spatial_areas = {});
225 std::vector<std::pair<int, double>> reviewedAreas() const;
265 void execute(SimulationContext& ctx, double dt, double evap_rate = 0.0,
266 double infil_factor = 1.0, double recovery_factor = 1.0, int month = -1,
267 const InfiltrationBoundary* boundary = nullptr,
268 const std::vector<RunoffSourceForcing>* source_forcing = nullptr,
269 const std::vector<double>* spatial_fractions = nullptr,
270 const std::vector<int>* source_owners = nullptr);
271
281 double nativeInfilFullLid(SimulationContext& ctx, int i, double dt, double recovery_factor);
282
287 double infilFactorUsed(int i) const { return infil_factor_used_[static_cast<std::size_t>(i)]; }
288
293 const RunoffSoA& soa() const { return soa_; }
299 RunoffSoA& soa() { return soa_; }
311 void checkpoint(detail::CompletedSourceArchive& archive, bool model);
320 void validateCheckpoint(const RunoffSolver& model) const;
328 double pendingRoutingVolume(const SimulationContext& ctx, int source) const;
329
330 // -----------------------------------------------------------------------
331 // Hot start helpers — Gap #54
332 // -----------------------------------------------------------------------
333
341 void infil_get_state(int i, int& model, double state[6]) const noexcept;
342
350 void infil_set_state(int i, int model, const double state[6]) noexcept;
351
352private:
353 RunoffSoA soa_;
354 std::vector<double>
355 spatial_full_area_ft2_;
356
357 // Infiltration state (one per subcatchment)
358 surface::InfilBank infil_bank_;
359 std::vector<double>
360 infil_factor_used_;
361 std::vector<double> completed_step_seconds_;
362
374 double infilGetInfil(SimulationContext& ctx, int i, double precip, double runon, double depth,
375 double dt, double local_infil, double recovery_factor);
376
377 // Working buffers (reused each step, sized to n_subcatch)
378 std::vector<double> precip_;
379 std::vector<double> evap_rate_;
380 std::vector<double> infil_rate_;
381
394 static void updatePondedDepth(double& depth, double inflow, double alpha, double dStore,
395 double dt, double& t_runoff);
396};
397
398} // namespace runoff
399} // namespace openswmm
400
401#endif // OPENSWMM_RUNOFF_HPP
Infiltration state and operations for surface water owners.
Structure-of-Arrays (SoA) storage for subcatchments.
Definition CompletedSourceArchive.hpp:25
Owned three-pool non-LID reservoir, native soil state and completed routing history....
Definition Runoff.hpp:195
void infil_set_state(int i, int model, const double state[6]) noexcept
Restore matching native soil history from six legacy hot-start scalars.
Definition Runoff.cpp:949
double infilFactorUsed(int i) const
Read the last recorded native infiltration multiplier for one source.
Definition Runoff.hpp:287
void validateCheckpoint(const RunoffSolver &model) const
Validate selected decoded numeric fields against an initialized runoff model.
Definition RunoffCheckpoint.cpp:48
void init(SimulationContext &ctx, const std::vector< std::pair< int, double > > &spatial_areas={})
Rebuild owned runoff/native infiltration state for one initialized model.
Definition Runoff.cpp:205
double pendingRoutingVolume(const SimulationContext &ctx, int source) const
Read completed inter-subarea outflow waiting for its next routing interval.
Definition Runoff.cpp:191
const RunoffSoA & soa() const
Borrow the current owned reservoir geometry, water and diagnostics.
Definition Runoff.hpp:293
double nativeInfilFullLid(SimulationContext &ctx, int i, double dt, double recovery_factor)
Advance native soil for a full-LID/fully impervious runoff source.
Definition Runoff.cpp:282
void infil_get_state(int i, int &model, double state[6]) const noexcept
Copy one native soil history into the legacy six-double hot-start layout.
Definition Runoff.cpp:946
RunoffSoA & soa()
Borrow mutable reservoir rows for compatible internal hot-start integration.
Definition Runoff.hpp:299
std::vector< std::pair< int, double > > reviewedAreas() const
Reconstruct only explicitly reviewed non-LID area overrides.
Definition Runoff.cpp:291
void execute(SimulationContext &ctx, double dt, double evap_rate=0.0, double infil_factor=1.0, double recovery_factor=1.0, int month=-1, const InfiltrationBoundary *boundary=nullptr, const std::vector< RunoffSourceForcing > *source_forcing=nullptr, const std::vector< double > *spatial_fractions=nullptr, const std::vector< int > *source_owners=nullptr)
Mutate selected or ordinary three-pool reservoirs over one completed interval.
Definition Runoff.cpp:309
std::function< bool(int, double, double, double &)> InfiltrationBoundary
Definition Runoff.hpp:204
void checkpoint(detail::CompletedSourceArchive &archive, bool model)
Stream either model identity rows or accepted runoff/soil state.
Definition RunoffCheckpoint.cpp:16
Definition InfilBank.hpp:31
Definition OutfallExchange.hpp:17
Definition Inflow.cpp:41
Definition ExplicitInertialSolver.hpp:68
constexpr double PHI
Manning's US customary constant.
Definition Runoff.hpp:92
constexpr double ODETOL
ODE solver tolerance (matching legacy)
Definition Runoff.hpp:91
constexpr double MEXP
Manning's exponent (legacy subcatch.c:55 literal — match bit-for-bit, NOT 5.0/3.0)
Definition Runoff.hpp:89
Definition ExchangeLaw.hpp:60
Central, reentrant simulation context.
Definition SimulationContext.hpp:390
double infiltration
Definition Runoff.hpp:82
double rain
Definition Runoff.hpp:81
double evaporation
Definition Runoff.hpp:81
double closing
Definition Runoff.hpp:82
double outlet
Definition Runoff.hpp:82
double runon
Definition Runoff.hpp:81
double area
Definition Runoff.hpp:81
double outflow
Definition Runoff.hpp:82
double opening
Definition Runoff.hpp:81
double spatial_infiltration
Definition Runoff.hpp:82
Definition Runoff.hpp:98
std::vector< double > depth_imperv0
Ponded depth, IMPERV0 (ft) — dStore=0.
Definition Runoff.hpp:132
std::vector< double > native_infil_rate
Definition Runoff.hpp:152
std::vector< double > depth_perv
Ponded depth, PERV (ft)
Definition Runoff.hpp:134
int n_subcatch
Definition Runoff.hpp:99
std::vector< double > alpha_perv
Alpha for pervious subarea.
Definition Runoff.hpp:121
std::vector< double > outflow_vol
Definition Runoff.hpp:168
std::vector< double > imperv_runoff_cfs
Impervious subarea runoff (CFS, non-LID area)
Definition Runoff.hpp:162
void resize(int n)
Reset all three-pool geometry, native water histories and output rows.
Definition Runoff.cpp:67
std::vector< double > perv_evap_vol
Pervious-subarea evaporation this step (ft3) — legacy Vpevap.
Definition Runoff.hpp:148
std::vector< double > frac_imperv0
IMPERV0 (no depression storage)
Definition Runoff.hpp:116
std::vector< double > ds_perv
Depression storage for PERV.
Definition Runoff.hpp:125
std::vector< double > ds_imperv
Depression storage for IMPERV1.
Definition Runoff.hpp:124
std::vector< double > old_runoff_imperv1
Previous IMPERV1 runoff (ft/sec)
Definition Runoff.hpp:139
std::vector< double > area
Subcatchment area (ft²)
Definition Runoff.hpp:102
std::vector< double > imperv_pct
Definition Runoff.hpp:105
std::vector< double > frac_imperv1
IMPERV1 (with depression storage)
Definition Runoff.hpp:117
std::vector< double > slope
Average slope (ft/ft)
Definition Runoff.hpp:104
std::vector< double > actual_perv_evap_vol
Definition Runoff.hpp:150
std::vector< double > old_runoff_imperv0
Previous IMPERV0 runoff (ft/sec)
Definition Runoff.hpp:138
std::vector< double > spatial_infil_vol
Completed partition diagnostics: ft3 spatial intake and ft/s outside native capacity.
Definition Runoff.hpp:152
std::vector< double > runoff
Total runoff rate (cfs)
Definition Runoff.hpp:143
std::vector< double > perv_runoff_cfs
Definition Runoff.hpp:163
std::vector< double > width
Subcatchment width (ft)
Definition Runoff.hpp:103
std::vector< double > subarea_runoff_rate
Definition Runoff.hpp:158
std::vector< double > depth_imperv1
Ponded depth, IMPERV1 (ft) — dStore>0.
Definition Runoff.hpp:133
std::vector< double > infil_loss
Reserved serialized row; execute writes context ft/s losses.
Definition Runoff.hpp:146
void computeAlpha()
Recompute native Manning reservoir coefficients from current geometry. Uses feet/ft2,...
Definition Runoff.cpp:108
std::vector< std::array< CompletedSubareaWater, 3 > > completed
Definition Runoff.hpp:169
std::vector< double > evap_loss
Reserved serialized row; execute writes context ft/s losses.
Definition Runoff.hpp:144
std::vector< double > old_runoff_perv
Previous PERV runoff (ft/sec)
Definition Runoff.hpp:140
std::vector< double > n_imperv
Manning's n, impervious.
Definition Runoff.hpp:128
std::vector< double > infil_vol
Definition Runoff.hpp:153
std::vector< double > n_perv
Manning's n, pervious.
Definition Runoff.hpp:129
std::vector< double > alpha_imperv
Alpha for impervious subareas.
Definition Runoff.hpp:120
double pet
Definition Runoff.hpp:73
double pet_perv
Definition Runoff.hpp:76
int subcatch
Definition Runoff.hpp:72
std::array< double, 3 > surface_return
Definition Runoff.hpp:74
double rain
Definition Runoff.hpp:73
double pet_imperv
Definition Runoff.hpp:76
double raw_precipitation
Definition Runoff.hpp:75