OpenSWMM Engine  6.0.0-alpha.4
Data-oriented, plugin-extensible SWMM Engine (6.0.0-alpha.4)
Loading...
Searching...
No Matches
HeatData.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
55
56#ifndef OPENSWMM_ENGINE_DATA_HEAT_DATA_HPP
57#define OPENSWMM_ENGINE_DATA_HEAT_DATA_HPP
58
59#include <limits>
60#include <vector>
61
62#include "BedZoneData.hpp" // SedimentConfig — H6b's bed zone configuration
63#include "HeatOverrideData.hpp" // HeatElement / HeatAttr / HeatScope — PE
64
65namespace openswmm {
66
70enum class HeatSource : int {
74 DWF = 1,
75 GW = 2,
76 RDII = 3,
78 IFACE = 5,
81};
82
88enum class HeatSubArea : int {
91 PERV = 2,
93};
94
103enum class DryTempPolicy : int {
106 HOLD = 0,
109 AIR = 1,
113};
114
115
136 double water_conductivity = 0.606;
137 double sed_conductivity = 2.6;
138 double sed_density = 1970.0;
139 double sed_specific_heat = 2758.0;
140};
141
152enum class ShortwaveMode : int {
156};
157
175 double latitude_deg = 0.0;
176 double longitude_deg = 0.0;
177 double timezone_hours = 0.0;
178 bool has_latitude = false;
179 bool has_longitude = false;
183 bool has_timezone = false;
184
193 double elevation_m = 0.0;
194 bool has_elevation = false;
195
196 // ---- Bird & Hulstrom (1981) atmosphere. Defaults are the paper's
197 // standard atmosphere.
198 double aod380 = 0.30;
199 double aod500 = 0.20;
200 double precip_water_cm = 1.42;
201 double ozone_cm = 0.34;
202 double ground_albedo = 0.20;
208};
209
224 bool configured = false;
225 bool use_timeseries = false;
226 int ts_index = -1;
227 double fraction = 0.0;
228
229 double sw_atten_k = 0.75;
230 double sw_atten_n = 3.4;
231 double lw_cloud_k = 0.17;
232};
233
244 double shortwave_wm2 = 0.0;
245 double albedo = 0.0;
246 double shade_factor = 0.0;
247 double sky_view = 1.0;
248 double emiss_water = 0.97;
249 double emiss_landcover = 0.97;
250 double atm_emiss_coeff = 0.5;
251 double lw_reflection = 0.03;
252
270 double landcover_temp = std::numeric_limits<double>::quiet_NaN();
271
276 int sw_ts_index = -1;
277};
278
294 std::vector<HeatOverrideRow> rows;
295
296 std::vector<RadiativeConfig> rad_link;
297 std::vector<RadiativeConfig> rad_node;
298 std::vector<SedimentConfig> sed_link;
299
300 bool resolved = false;
301
302 bool empty() const noexcept { return rows.empty(); }
303 void clear() { *this = HeatOverrideData{}; }
304};
305
319 bool configured = false;
320
323 bool radiative_exchange = false;
324
327
338 bool surface_exchange = false;
339
342
346 bool layer_conduction = false;
347
350
358 bool sediment_exchange = false;
359
366
370
374
378
380 static constexpr double kDefaultTemp = 20.0;
381
386
388 bool configured_source[static_cast<int>(HeatSource::COUNT_)] = {};
389
390 // NODE-scope overrides (DWF / EXTERNAL_INFLOW), parallel arrays.
391 std::vector<int> node_over_source;
392 std::vector<int> node_over_node;
393 std::vector<double> node_over_temp;
394
396 double source_temp(HeatSource s, int node) const noexcept {
397 for (std::size_t i = 0; i < node_over_source.size(); ++i)
398 if (node_over_source[i] == static_cast<int>(s) &&
399 node_over_node[i] == node)
400 return node_over_temp[i];
401 return global_temp[static_cast<int>(s)];
402 }
403};
404
413struct HeatState {
414 std::vector<double> node_temp_vol_in;
422 std::vector<double> node_lid_drain_temp_vol_in;
423 std::vector<double> node_temp;
424 std::vector<double> link_temp;
425
427 bool legacy_seeded = false;
428
429 // ---- H6a per-step solar forcing (plan §2.5). RESOLVED ONCE PER STEP by
430 // `updateSolarForcing`, then read const by every flux call.
431 //
432 // This is state, not config, which is why it lives here: `Jin`
433 // under TIMESERIES or COMPUTED changes every step, while
434 // `RadiativeConfig::shortwave_wm2` is what the deck wrote and must
435 // not be overwritten (a hot-started or re-opened model would
436 // otherwise resume from a stale interpolation rather than from its
437 // own configuration).
438 //
439 // It is also what keeps the SPA cost argument honest: shortwave is
440 // GLOBAL scope, so the position is computed once per step and every
441 // element reads the same cached number. A per-element solve is
442 // plan §7 work and would not use this field.
443
457 double shortwave_now = -1.0;
459 double cloud_now = 0.0;
460
461 // ---- H5a watershed rows. Sized by `resizeWatershed`, NOT by `resize`.
462 // Kept a separate call deliberately: A3 widened `WaterAgeState::
463 // resize` with a defaulted third parameter, four existing two-
464 // argument call sites then silently emptied the new arrays at
465 // runtime, and the validator had to remove the default to move the
466 // failure back to the compiler. A second function cannot be called
467 // short, so the hazard is unrepresentable rather than observed.
468
470 std::vector<double> subarea_temp;
474 std::vector<double> subarea_vol_prev;
476 std::vector<double> subcatch_runoff_temp;
480 std::vector<double> subcatch_runon_temp_vol_in;
481
502 std::vector<double> subcatch_runon_temp_rate;
503
509 std::vector<double> subcatch_outfall_temp_vol;
510
511 static constexpr int kNSubArea = static_cast<int>(HeatSubArea::COUNT_);
512
513 void resize(int n_nodes, int n_links, double initial_temp) {
514 node_temp_vol_in.assign(static_cast<std::size_t>(n_nodes), 0.0);
515 node_lid_drain_temp_vol_in.assign(static_cast<std::size_t>(n_nodes), 0.0);
516 node_temp.assign(static_cast<std::size_t>(n_nodes), initial_temp);
517 link_temp.assign(static_cast<std::size_t>(n_links), initial_temp);
518 legacy_seeded = false;
519 // H6a. `clear()` resets these via whole-struct assignment, but
520 // `resize()` is what runs at INITIALIZE — so a re-initialize on an
521 // already-run context would otherwise leave the previous run's
522 // forcing readable, and `swmm_heat_get_current_shortwave` documents
523 // itself as unresolved before the first step.
524 shortwave_now = -1.0;
525 cloud_now = 0.0;
526 }
527
528 void resizeWatershed(int n_subcatch, double initial_temp) {
529 const auto n = static_cast<std::size_t>(n_subcatch);
530 subarea_temp.assign(n * static_cast<std::size_t>(kNSubArea),
531 initial_temp);
532 subarea_vol_prev.assign(n * static_cast<std::size_t>(kNSubArea), 0.0);
533 subcatch_runoff_temp.assign(n, initial_temp);
534 subcatch_runon_temp_vol_in.assign(n, 0.0);
535 subcatch_runon_temp_rate.assign(n, 0.0);
536 subcatch_outfall_temp_vol.assign(n, 0.0);
537 }
538
539 bool watershedSized(int n_subcatch) const noexcept {
540 return subarea_temp.size() == static_cast<std::size_t>(n_subcatch) *
541 static_cast<std::size_t>(kNSubArea);
542 }
543
544 void clear() { *this = HeatState{}; }
545};
546
547} // namespace openswmm
548
549#endif // OPENSWMM_ENGINE_DATA_HEAT_DATA_HPP
Plan H6b — the bed / hyporheic transient-storage zone.
Plan PE — per-element radiative and bed attributes.
Definition Node.cpp:38
Definition NodeCoupling.cpp:16
DryTempPolicy
What a dry or absent element reports (plan D-H5c, user 2026-08-19).
Definition HeatData.hpp:103
@ HOLD
Definition HeatData.hpp:106
@ AIR
Definition HeatData.hpp:109
@ DEFAULT
Definition HeatData.hpp:112
HeatSubArea
Definition HeatData.hpp:88
@ IMPERV0
Definition HeatData.hpp:89
@ COUNT_
Definition HeatData.hpp:92
@ IMPERV1
Definition HeatData.hpp:90
@ PERV
Definition HeatData.hpp:91
@ TIMESERIES
Data from an in-file [TIMESERIES].
Definition GageData.hpp:58
HeatSource
Definition HeatData.hpp:70
@ RAINFALL
Definition HeatData.hpp:71
@ RDII
Definition HeatData.hpp:76
@ COUNT_
Definition HeatData.hpp:80
@ DWF
Definition HeatData.hpp:74
@ EXTERNAL_INFLOW
Definition HeatData.hpp:77
@ INITIAL_STATE
water in the network at t = 0
Definition HeatData.hpp:79
@ GW
Definition HeatData.hpp:75
@ IFACE
Definition HeatData.hpp:78
ShortwaveMode
Where incoming shortwave Jin comes from (plan §2.5, phase H6a).
Definition HeatData.hpp:152
@ COMPUTED
SHORTWAVE GLOBAL COMPUTED — position + clear-sky.
Definition HeatData.hpp:155
@ CONSTANT
SHORTWAVE GLOBAL <W/m²> — the H3 spelling.
Definition HeatData.hpp:153
[CLOUD_COVER] — one fraction driving two modules (H6a, D-H6a-2).
Definition HeatData.hpp:223
double sw_atten_n
Kasten–Czeplak n.
Definition HeatData.hpp:230
double fraction
C ∈ [0,1], constant spelling.
Definition HeatData.hpp:227
int ts_index
Index into ctx.tables, -1 = none.
Definition HeatData.hpp:226
double sw_atten_k
Kasten–Czeplak k.
Definition HeatData.hpp:229
bool use_timeseries
Definition HeatData.hpp:225
double lw_cloud_k
Bolz k_lw.
Definition HeatData.hpp:231
bool configured
No [CLOUD_COVER] section → clear sky.
Definition HeatData.hpp:224
Vertical conduction between LID layers (plan §6.1 D-H5b, H5b).
Definition HeatData.hpp:135
double sed_specific_heat
J/kg/K (gwmodel.cpp:52)
Definition HeatData.hpp:139
double water_conductivity
W/m/K (gwmodel.h:885)
Definition HeatData.hpp:136
double sed_density
kg/m³ (gwmodel.cpp:51)
Definition HeatData.hpp:138
double sed_conductivity
W/m/K (gwmodel.h:886)
Definition HeatData.hpp:137
Parsed model.heat state (heat component, phase H1).
Definition HeatData.hpp:318
bool configured_source[static_cast< int >(HeatSource::COUNT_)]
Whether the user set this source explicitly (vs. taking the default).
Definition HeatData.hpp:388
SolarConfig solar
Definition HeatData.hpp:373
ConductionConfig conduction
Parameters for the module above.
Definition HeatData.hpp:349
bool radiative_exchange
Definition HeatData.hpp:323
double global_temp[static_cast< int >(HeatSource::COUNT_)]
GLOBAL inlet temperature per source, °C.
Definition HeatData.hpp:383
bool sediment_exchange
Definition HeatData.hpp:358
RadiativeConfig radiative
Parameters for the module above.
Definition HeatData.hpp:326
HeatOverrideData overrides
Definition HeatData.hpp:369
static constexpr double kDefaultTemp
Default inlet temperature when a source has no row (°C).
Definition HeatData.hpp:380
DryTempPolicy dry_temp_policy
[HEAT_FLUXES] DRY_ELEMENT_TEMPERATURE HOLD|AIR|DEFAULT (D-H5c).
Definition HeatData.hpp:341
std::vector< int > node_over_source
HeatSource as int.
Definition HeatData.hpp:391
bool surface_exchange
[HEAT_FLUXES] SURFACE_EXCHANGE ON — latent + sensible exchange at the free surface (plan §2....
Definition HeatData.hpp:338
std::vector< double > node_over_temp
°C
Definition HeatData.hpp:393
bool configured
Definition HeatData.hpp:319
bool layer_conduction
Definition HeatData.hpp:346
double source_temp(HeatSource s, int node) const noexcept
Temperature of source water entering node (°C).
Definition HeatData.hpp:396
CloudConfig cloud
Definition HeatData.hpp:377
SedimentConfig sediment
Definition HeatData.hpp:365
std::vector< int > node_over_node
node index
Definition HeatData.hpp:392
Dense per-element attribute storage (PE2, D-PE2).
Definition HeatData.hpp:293
std::vector< SedimentConfig > sed_link
[link], empty ⇒ use global
Definition HeatData.hpp:298
bool empty() const noexcept
Definition HeatData.hpp:302
std::vector< HeatOverrideRow > rows
as parsed; the serializer's input
Definition HeatData.hpp:294
std::vector< RadiativeConfig > rad_node
[node], empty ⇒ use global
Definition HeatData.hpp:297
std::vector< RadiativeConfig > rad_link
[link], empty ⇒ use global
Definition HeatData.hpp:296
bool resolved
Definition HeatData.hpp:300
void clear()
Definition HeatData.hpp:303
Runtime heat state shared by the engines (phase H1).
Definition HeatData.hpp:413
std::vector< double > subarea_temp
[subcatch * kNSubArea + subarea], °C — ponded surface temperature.
Definition HeatData.hpp:470
static constexpr int kNSubArea
Definition HeatData.hpp:511
std::vector< double > link_temp
[link], °C
Definition HeatData.hpp:424
bool legacy_seeded
The LEGACY mirror seeds INITIAL_STATE on its first step.
Definition HeatData.hpp:427
std::vector< double > subcatch_runoff_temp
[subcatch], °C — temperature the subcatchment's runoff leaves at.
Definition HeatData.hpp:476
bool watershedSized(int n_subcatch) const noexcept
Definition HeatData.hpp:539
std::vector< double > node_temp_vol_in
Definition HeatData.hpp:414
std::vector< double > node_lid_drain_temp_vol_in
Definition HeatData.hpp:422
double cloud_now
Cloud fraction at the current step, C ∈ [0,1]. 0 = clear.
Definition HeatData.hpp:459
std::vector< double > node_temp
[node], °C
Definition HeatData.hpp:423
std::vector< double > subcatch_outfall_temp_vol
Definition HeatData.hpp:509
void resize(int n_nodes, int n_links, double initial_temp)
Definition HeatData.hpp:513
std::vector< double > subcatch_runon_temp_rate
Definition HeatData.hpp:502
std::vector< double > subarea_vol_prev
Definition HeatData.hpp:474
void clear()
Definition HeatData.hpp:544
void resizeWatershed(int n_subcatch, double initial_temp)
Definition HeatData.hpp:528
double shortwave_now
Definition HeatData.hpp:457
std::vector< double > subcatch_runon_temp_vol_in
Definition HeatData.hpp:480
[RADIATIVE_FLUXES] parameters (heat plan §2.2, phase H3).
Definition HeatData.hpp:243
double sky_view
fsky, 1 = open sky
Definition HeatData.hpp:247
double atm_emiss_coeff
Brunt Aa.
Definition HeatData.hpp:250
double shade_factor
fs, 0 = unshaded
Definition HeatData.hpp:246
double albedo
Rs, reference default.
Definition HeatData.hpp:245
int sw_ts_index
Index into ctx.tables under TIMESERIES; -1 otherwise.
Definition HeatData.hpp:276
double lw_reflection
RL.
Definition HeatData.hpp:251
double shortwave_wm2
Incoming solar Jin, W/m² (0 = night)
Definition HeatData.hpp:244
double emiss_landcover
εlc
Definition HeatData.hpp:249
ShortwaveMode sw_mode
Definition HeatData.hpp:274
double landcover_temp
Land-cover radiating temperature, °C. NaN ⇒ use air temperature.
Definition HeatData.hpp:270
double emiss_water
εw
Definition HeatData.hpp:248
[SEDIMENT_EXCHANGE] — the bed zone's material and geometry.
Definition BedZoneData.hpp:88
[SOLAR_RADIATION] — site geometry and Bird atmosphere (H6a).
Definition HeatData.hpp:174
double ozone_cm
Ozone column, cm (NTP)
Definition HeatData.hpp:201
double timezone_hours
Offset from UTC, +E (e.g. MST = -7).
Definition HeatData.hpp:177
bool has_timezone
Definition HeatData.hpp:183
double longitude_deg
+E. REQUIRED under COMPUTED.
Definition HeatData.hpp:176
bool has_elevation
Definition HeatData.hpp:194
double elevation_m
Definition HeatData.hpp:193
double aod380
Aerosol optical depth at 380 nm.
Definition HeatData.hpp:198
bool has_longitude
Definition HeatData.hpp:179
double precip_water_cm
Precipitable water vapour, cm.
Definition HeatData.hpp:200
double ground_albedo
Definition HeatData.hpp:202
bool has_latitude
Set by the parser, checked at close.
Definition HeatData.hpp:178
double latitude_deg
+N. REQUIRED under COMPUTED.
Definition HeatData.hpp:175
double aod500
Aerosol optical depth at 500 nm.
Definition HeatData.hpp:199