OpenSWMM Engine  6.0.0-alpha.4
Data-oriented, plugin-extensible SWMM Engine (6.0.0-alpha.4)
Loading...
Searching...
No Matches
QualityRouting.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
23
41
42#ifndef OPENSWMM_QUALITY_ROUTING_HPP
43#define OPENSWMM_QUALITY_ROUTING_HPP
44
46#include <vector>
47
48namespace openswmm {
49
51
52namespace quality {
53
54// ============================================================================
55// Constants
56// ============================================================================
57
58constexpr double ZERO_VOLUME = 0.0353147;
59constexpr double ZERO_DEPTH = 0.003281;
64constexpr double LEGACY_ZERO = 1.0e-10;
65
66// ============================================================================
67// Shared shape of the legacy mixing kernels
68//
69// The pollutant kernels in QualityRouting.cpp and the water-age, heat and MSX
70// mirrors in transport/components all route on the SAME rules — that identity
71// is the mirrors' design contract, and the reason WATER_AGE or HEAT_TRANSPORT
72// can be switched on without moving a pollutant trajectory. Four hand-copies
73// of those rules had already drifted apart (each mirror still carried the
74// pre-correction spelling, and their "matches the quality path" zero-volume
75// constant was 1e-10 against the quality path's one litre), so the rules live
76// here once and every kernel asks rather than re-derives.
77// ============================================================================
78
84
90double conduitMixingInflow(const SimulationContext& ctx, int link, double dt);
91
94bool linkIsDry(const SimulationContext& ctx, int link);
95
100bool nodeIsReactor(const SimulationContext& ctx, int node);
101
105bool nodeIsDry(const SimulationContext& ctx, int node, double q_in);
106
110double storageEvapFactor(const SimulationContext& ctx, int node);
111
116void updateUntreatedStorageHrt(SimulationContext& ctx, double dt);
117
142void applyNodeTreatment(SimulationContext& ctx, int node, double dt, double q_in_cfs,
143 const double* cin);
144
145// ============================================================================
146// Quality solver
147// ============================================================================
148
150public:
151 void init(int n_nodes, int n_links, int n_pollutants);
152
165 void execute(SimulationContext& ctx, double dt);
166 FvTransportWater& fvWater() noexcept {return fv_transport_.water;}
167 bool fvTransportAccepted() const noexcept {return fv_transport_.accepted();}
168 bool hasFvRetainedDryMass() const noexcept {return fv_transport_.hasRetainedDryMass();}
169 std::string fvDryRestartState(const SimulationContext& ctx) const {return fv_transport_.dryRestartState(ctx);}
170 std::string restoreFvDryRestart(SimulationContext& ctx,const std::string& blob,bool apply) {return fv_transport_.restoreDryRestart(ctx,blob,apply);}
171 std::vector<double> fvRetainedPollutantMass(const SimulationContext& ctx) const {return fv_transport_.retainedPollutantMass(ctx);}
172 std::vector<double> fvRetainedSpeciesMass(const SimulationContext& ctx) const {return fv_transport_.retainedSpeciesMass(ctx);}
173 void beginFvWindow() noexcept {fv_transport_.beginWindow();}
174
184 void assembleExternalLoads(SimulationContext& ctx, double dt);
185
196 void addExtInflowLoads(SimulationContext& ctx, double dt);
200 void addCouplingLoads(SimulationContext& ctx, double dt);
201 void addQualityOnlyInflows(SimulationContext& ctx, double dt);
202
209 void addWetWeatherLoads(SimulationContext& ctx, double dt);
210
214 void updateLinkQuality(SimulationContext& ctx, double dt);
215
222
230 void applyTreatment(SimulationContext& ctx, double dt, bool full_inflow = true);
231
232private:
233 int n_pollutants_ = 0;
234 FvQualityTransport fv_transport_;
238 std::vector<double> qual_vol_lat_;
243 std::vector<double> qual_vol_lat_neg_;
244
245 // Quality mass inflow arrays are stored on NodeData (nodes.qual_mass_in[],
246 // nodes.qual_vol_in[]) so that external quality sources (user forcing, DWF
247 // quality, etc.) can contribute at the same assembly point.
248
250 void addRdiiLoads(SimulationContext& ctx, double dt);
251
253 void addDwfLoads(SimulationContext& ctx, double dt);
254
256 void addGwLoads(SimulationContext& ctx, double dt);
257
259 void addIfaceLoads(SimulationContext& ctx, double dt);
260
262 void accumulateLinkLoads(SimulationContext& ctx, double dt);
263
265 void mixAtNodes(SimulationContext& ctx, double dt);
266
268 void applyDecay(SimulationContext& ctx, double dt);
269};
270
271} // namespace quality
272} // namespace openswmm
273
274#endif // OPENSWMM_QUALITY_ROUTING_HPP
Definition FvQualityTransport.hpp:8
Definition QualityRouting.hpp:149
void addWetWeatherLoads(SimulationContext &ctx, double dt)
Add subcatchment washoff quality loads to node inflows.
Definition QualityRouting.cpp:1006
void updateLinkQuality(SimulationContext &ctx, double dt)
Publish link pollutant concentration using shared legacy conduit mixing rules.
Definition QualityRouting.cpp:1818
std::vector< double > fvRetainedPollutantMass(const SimulationContext &ctx) const
Definition QualityRouting.hpp:171
void init(int n_nodes, int n_links, int n_pollutants)
Set the solver's pollutant row count for subsequent routing/assembly.
Definition QualityRouting.cpp:410
void addExtInflowLoads(SimulationContext &ctx, double dt)
Add direct external inflow ([INFLOWS] CONCEN/MASS) pollutant loads, and the direct inflow's water,...
Definition QualityRouting.cpp:708
void addQualityOnlyInflows(SimulationContext &ctx, double dt)
review D2 + gaining conduits
Definition QualityRouting.cpp:440
void addCouplingLoads(SimulationContext &ctx, double dt)
Add accepted 2D-to-node coupling carrier volumes, scalar numerators and pollutant rates.
Definition QualityRouting.cpp:635
bool fvTransportAccepted() const noexcept
Definition QualityRouting.hpp:167
FvTransportWater & fvWater() noexcept
Definition QualityRouting.hpp:166
bool hasFvRetainedDryMass() const noexcept
Definition QualityRouting.hpp:168
void beginFvWindow() noexcept
Definition QualityRouting.hpp:173
std::vector< double > fvRetainedSpeciesMass(const SimulationContext &ctx) const
Definition QualityRouting.hpp:172
std::string fvDryRestartState(const SimulationContext &ctx) const
Definition QualityRouting.hpp:169
void applyTreatment(SimulationContext &ctx, double dt, bool full_inflow=true)
Apply [TREATMENT] at every node that has one.
Definition QualityRouting.cpp:2003
void execute(SimulationContext &ctx, double dt)
Execute one quality routing timestep.
Definition QualityRouting.cpp:820
void assembleExternalLoads(SimulationContext &ctx, double dt)
Stage 1 of execute() only: reset the assembly arrays and run the external-load adders (runoff/LID,...
Definition QualityRouting.cpp:505
std::string restoreFvDryRestart(SimulationContext &ctx, const std::string &blob, bool apply)
Definition QualityRouting.hpp:170
Definition Node.cpp:38
Definition ConservativeMixing.cpp:8
bool linkIsDry(const SimulationContext &ctx, int link)
Test the accepted conduit water/depth effective-zero thresholds.
Definition QualityRouting.cpp:130
constexpr double ZERO_VOLUME
1 liter in ft3
Definition QualityRouting.hpp:58
constexpr double LEGACY_ZERO
Definition QualityRouting.hpp:64
double conduitMixingInflow(const SimulationContext &ctx, int link, double dt)
Calculate a conduit quality mixing inflow from accepted hydraulic balance.
Definition QualityRouting.cpp:90
bool nodeIsReactor(const SimulationContext &ctx, int node)
Select storage or retained-water node mixing.
Definition QualityRouting.cpp:145
constexpr double ZERO_DEPTH
Definition QualityRouting.hpp:59
double storageEvapFactor(const SimulationContext &ctx, int node)
Calculate storage concentration increase from non-LID evaporation.
Definition QualityRouting.cpp:165
void updateUntreatedStorageHrt(SimulationContext &ctx, double dt)
Advance residence time only for untreated storage nodes under active native reactions.
Definition QualityRouting.cpp:204
bool linkTakesUpstreamValue(const SimulationContext &ctx, int link)
Test whether a link has no mixed conduit water pool.
Definition QualityRouting.cpp:74
void applyNodeTreatment(SimulationContext &ctx, int j, double dt, double q_raw, const double *cin)
Resolve one node's compiled co-treatment laws and book accepted pollutant removal.
Definition QualityRouting.cpp:2078
bool nodeIsDry(const SimulationContext &ctx, int node, double q_in)
Test node effective dryness only when mixing inflow is negligible.
Definition QualityRouting.cpp:236
Definition ExchangeLaw.hpp:60
Central, reentrant simulation context.
Definition SimulationContext.hpp:390
Definition FvTransportWater.hpp:7
MixingWater water
Definition FvTransportWater.hpp:8