![]() |
OpenSWMM Engine
6.0.0-alpha.4
Data-oriented, plugin-extensible SWMM Engine (6.0.0-alpha.4)
|
Classes | |
| struct | BedCoupling |
| One element's bed coupling, fully reduced to SI conductances. More... | |
| struct | PairStep |
| Simultaneous temperature increments for the coupled pair, °C. More... | |
| struct | SolarPosition |
| Sun geometry at one instant. The SPA swap point's return type. More... | |
| struct | SolutePairStep |
| Simultaneous concentration increments for the coupled pair. More... | |
Functions | |
| PairStep | relaxPair (const BedCoupling &g, double t_w, double t_b, double j0, double j1, double h, double area_m2, double dt) noexcept |
| One exact step of the coupled (water, bed) pair. | |
| SolutePairStep | exchangePair (double c_w, double c_b, double vol_w, double vol_b, double q_exch, double dt) noexcept |
| One exact step of the two-body solute exchange. | |
| bool | bedExchangeEnabled (const SimulationContext &ctx) noexcept |
| Test current native finite-bed heat family process enable. | |
| double | groundTemperature (SimulationContext &ctx) noexcept |
| Sample the global held deep-ground temperature at native absolute model time. | |
| double | linkBedAreaM2 (const SimulationContext &ctx, int link) noexcept |
| Compute wetted conduit bed contact area from native geometry. | |
| double | linkFreeSurfaceFt2 (const SimulationContext &ctx, int link) noexcept |
| Compute native open-conduit free surface for heat/evaporation binding. | |
| double | bedExchangeQ (const SedimentConfig &cfg, double bed_m2) noexcept |
| Compute total finite-bed solute exchange rate from diffusion and hyporheic velocity. | |
| double | groundTempFor (const SimulationContext &ctx, const SedimentConfig &sc, double t_gr_global) noexcept |
| Choose one element's held deep-ground constant or globally sampled series temperature. | |
| void | fillChannelThermalGeometry (const SimulationContext &ctx, ChannelThermalRegion ®ion) noexcept |
| Publish native conduit thermal region geometry in SI. | |
| BedCoupling | bedCouplingFromContact (const SimulationContext &ctx, const SedimentConfig &sc, double bed_m2, double vol_ft3, double t_gr) noexcept |
| Construct finite water/bed conductance and capacity from one SI contact footprint. | |
| BedCoupling | bedCouplingForLink (const SimulationContext &ctx, int link, double vol_ft3, double t_gr) noexcept |
| Build a conduit finite-bed pair from current wet perimeter and resolved element material. | |
| void | seedBedTemperature (SimulationContext &ctx) |
| Size and seed native link bed temperatures at their initial owner phase. | |
| void | applyBedSoluteExchange (SimulationContext &ctx, double *link_conc, int n_arr, int offset, int n_total, double dt) |
Step every conduit's bed/channel solute exchange for one dt. | |
| double | netFluxOut (const SimulationContext &ctx, const HeatElement &elem, double t_w) noexcept |
| Sum enabled element latent/sensible and radiative flux under one outward sign convention. | |
| void | applyHeatFluxes (SimulationContext &ctx, double dt) |
| Advance each eligible native water element once against combined atmospheric and finite bed heat. | |
| std::vector< std::string > | resolveHeatOverrides (SimulationContext &ctx) |
| Materialize retained per-element/tag/mesh heat attributes in dense lookup vectors. | |
| const RadiativeConfig & | radiativeFor (const SimulationContext &ctx, const HeatElement &e) noexcept |
| Borrow resolved element radiation parameters with global fallback. | |
| const SedimentConfig & | sedimentFor (const SimulationContext &ctx, const HeatElement &e) noexcept |
| Borrow resolved conduit/mesh-cell sediment parameters with global fallback. | |
| double | netShortwave (double incoming_wm2, double albedo, double shade_factor) noexcept |
| Compute absorbed incident shortwave after albedo and shade. | |
| double | backLongwave (double t_water_c, double emiss_water) noexcept |
| Compute emitted water longwave flux from the Stefan-Boltzmann law. | |
| double | atmosphericEmissivity (double e_a_kpa, double atm_emiss_coeff, double cloud_factor) noexcept |
| Compute Brunt atmospheric emissivity with optional held cloud enhancement. | |
| double | atmosphericLongwave (double t_air_c, double humidity_pct, double atm_emiss_coeff, double lw_reflection, double sky_view, double cloud_factor) noexcept |
| Compute absorbed visible-sky atmospheric longwave into water. | |
| double | landCoverLongwave (double t_air_c, double emiss_landcover, double sky_view) noexcept |
| Compute visible land-cover longwave contribution into water. | |
| double | netRadiativeFluxOut (double t_water_c, double t_air_c, double humidity_pct, const RadiativeConfig &cfg, double jin_wm2, double cloud_factor, double incoming_longwave) noexcept |
| Combine water emission with absorbed shortwave, sky longwave and land-cover longwave. | |
| double | radiativeFluxOut (const SimulationContext &ctx, const HeatElement &elem, double t_w) noexcept |
| Evaluate element radiative flux using the configured global family enable. | |
| double | radiativeFluxOut (const SimulationContext &ctx, const HeatElement &elem, double t_w, bool enabled) noexcept |
| Evaluate held element radiation with an explicit domain enable and no global toggle mutation. | |
| double | airTempCelsius (const SimulationContext &ctx) noexcept |
| Convert held native climate air temperature from Fahrenheit to Celsius. | |
| double | relaxT (double j0, double j1, double h, double area_m2, double vol_m3, double dt, double rho, double cp) noexcept |
| One element's temperature change, integrated SEMI-IMPLICITLY [°C]. | |
| double | equilibriumT (double t0_c, double j0, double j1, double h) noexcept |
| Compute the positive-damping linearized equilibrium temperature. | |
| double | saturationVapourPressure (double t_c) noexcept |
| Compute saturation vapor pressure from the Magnus water-temperature formula. | |
| double | latentHeatOfVaporization (double t_c) noexcept |
| Compute temperature-dependent latent heat of vaporization. | |
| double | windFunction (double wind_ms, double a, double b) noexcept |
| Evaluate the mass-transfer wind function with nonnegative wind speed. | |
| double | evaporationRate (double t_water_c, double t_air_c, double humidity_pct, double wind_ms, double a, double b) noexcept |
| Compute signed vapor-deficit-driven water surface evaporation velocity. | |
| double | latentFlux (double t_water_c, double t_air_c, double humidity_pct, double wind_ms, double a, double b, double water_density) noexcept |
| Convert signed surface evaporation into outward latent heat flux. | |
| double | bowenRatio (double t_water_c, double t_air_c, double humidity_pct, double pressure_ratio) noexcept |
| Compute the dimensionless Bowen sensible-to-latent ratio at held weather. | |
| double | sensibleFlux (double latent_flux, double bowen_ratio) noexcept |
| Form signed outward sensible flux from latent flux and Bowen ratio. | |
| double | surfaceFluxOut (const SimulationContext &ctx, const HeatElement &elem, double t_w) noexcept |
| Evaluate one element's enabled latent+sensible outward atmospheric flux. | |
| SolarPosition | solarPosition (int day_of_year, double hour_local, double lat_deg, double lon_deg, double tz_hours) noexcept |
| Compute Spencer/NOAA sun geometry at a local civil-clock instant. | |
| double | airMass (double zenith_deg) noexcept |
| Compute Kasten-Young relative optical air mass. | |
| double | pressureFromElevation (double elevation_m) noexcept |
| Estimate standard-atmosphere station pressure from elevation. | |
| double | birdClearSkyGHI (const SolarPosition &pos, double pressure_mb, const SolarConfig &cfg) noexcept |
| Estimate clear-sky global horizontal irradiance with Bird-Hulstrom terms. | |
| double | cloudShortwaveFactor (double cloud_fraction, double k, double n) noexcept |
| Compute the cloud attenuation multiplier max(0,1-k*C^n). | |
| double | cloudLongwaveFactor (double cloud_fraction, double k_lw) noexcept |
| Compute the cloud atmospheric-emissivity multiplier 1+k_lw*C^2. | |
| void | updateSolarForcing (SimulationContext &ctx, double seconds=1) |
| Update shared heat shortwave/cloud forcing with mesh radiation disabled. | |
Variables | |
| constexpr double | kStefanBoltzmann = 5.67e-8 |
Stefan–Boltzmann constant, W/m²/K⁴ (rhemodel.cpp:46). | |
| constexpr double | kKelvinOffset = 273.15 |
| Celsius → Kelvin offset. | |
| constexpr double | kBowenCoeff = 0.061 |
| Bowen's coefficient, kPa/°C (CSH §4.5). | |
| constexpr double | kProbeC = 1.0e-3 |
| constexpr double | kSqFtToSqM = 0.09290304 |
ft² → m². Exported with relaxT, which is useless without it. | |
| constexpr double | kCuFtToCuM = 0.028316846592 |
| ft³ → m³. | |
| constexpr double | kMphToMs = 0.44704 |
mph → m/s. ClimateState::wind_speed is mph. | |
| constexpr double | kSolarConstant |
| Solar constant, W/m² (Bird & Hulstrom 1981; WMO 1982). | |
| constexpr double | kStdPressureMb |
| Sea-level standard pressure, millibars — Bird's pressure reference. | |
|
noexcept |
Compute Kasten-Young relative optical air mass.
| zenith_deg | Finite solar zenith in degrees, normally [0,180]. |
|
noexcept |
Convert held native climate air temperature from Fahrenheit to Celsius.
| [in] | ctx | Stable climate_state.temperature in degF. |
Air temperature in °C. ClimateState carries °F (a legacy convention); every formulation in this program is Celsius. Exported at H5a so the watershed binding cannot acquire a second, drifting copy of the conversion — there is exactly one place that knows the units.
| void openswmm::transport::heat::applyBedSoluteExchange | ( | SimulationContext & | ctx, |
| double * | link_conc, | ||
| int | n_arr, | ||
| int | offset, | ||
| int | n_total, | ||
| double | dt ) |
Step every conduit's bed/channel solute exchange for one dt.
| [in,out] | ctx | Prepared native hydraulics/material overrides and finite bed state; may seed bed temperature and resize/reset combined bed native concentration array for n_links*n_total. |
| [in,out] | link_conc | Optional writable contiguous node-major-style link array [link*n_arr+s] in native concentration units; null returns. Caller guarantees at least n_links*n_arr elements, nonaliasing with bed storage (which may reallocate), stable through call. |
| [in] | dt | Positive finite accepted solute interval s; nonpositive/NaN returns. |
| n_arr | Species carried by link_conc. |
| offset | Where link_conc's rows start inside the bed store. The bed carries ONE species set — pollutants then MSX — and LEGACY holds those in two arrays (links.conc, msx_link_conc), so it calls twice: (conc, np, 0) and (msx, nm, np). Splitting the bed store instead would give the two halves independent sizing paths and a seam where one resizes and the other does not. |
| n_total | Total species the bed store carries (np + nm). Sizing is by n_total, so the two LEGACY calls agree about the store's shape by construction. |
| void openswmm::transport::heat::applyHeatFluxes | ( | SimulationContext & | ctx, |
| double | dt ) |
Advance each eligible native water element once against combined atmospheric and finite bed heat.
Apply one step of surface heat exchange to every exchanging node and link.
| [in,out] | ctx | Prepared native node/link hydraulic geometry and temperatures, heat/material configuration, weather/providers, bed state and tables. Mutates temperature arrays, bed seeds, held ground/solar forcing and relevant series/geometry cursors; borrowed owners remain live/stable. |
| [in] | dt | Positive finite accepted heat interval s; nonpositive/NaN returns. Caller chooses interval consistent with hydraulic volume/heat-owner chronology. |
Storage nodes (node::getSurfArea) and open conduits (top width × length × barrels) — the engine's own evaporation surfaces, so heat crosses the free surface exactly where water leaves it. Junctions, outfalls, dividers and closed conduits have no free surface and no exchange.
Modifies heat_state.node_temp and link_temp in place. No-op unless HEAT_TRANSPORT is on and at least one flux module is enabled.
|
noexcept |
Compute Brunt atmospheric emissivity with optional held cloud enhancement.
| [in] | e_a_kpa | Air vapor pressure kPa, negative floored0 before sqrt and converted to Pa. |
| [in] | atm_emiss_coeff | Dimensionless clear-sky intercept. |
| [in] | cloud_factor | Dimensionless Bolz cloud multiplier, normally>=1; exactly1 bypasses multiply. |
Brunt atmospheric emissivity [-]. e_a_kpa is converted to Pa inside.
H6a: cloud_factor is Bolz's 1 + k_lw C² from SolarRadiation::cloudLongwaveFactor. It DEFAULTS TO 1.0 and the default is not decorative — every H3 gate calls the two-argument form, so the clear-sky value is unchanged by construction rather than by arithmetic that happens to round the same way.
|
noexcept |
Compute absorbed visible-sky atmospheric longwave into water.
Atmospheric longwave [W/m²], INTO the water.
| [in] | t_air_c | Qualified air degC. |
| [in] | humidity_pct | Relative humidity percent, normally[0,100]. |
| [in] | atm_emiss_coeff | Dimensionless Brunt intercept. |
| [in] | lw_reflection | Longwave reflected fraction, normally[0,1]. |
| [in] | sky_view | Visible-sky hemisphere fraction, normally[0,1]. |
| [in] | cloud_factor | Held dimensionless cloud emissivity multiplier, default1 for clear sky. |
|
noexcept |
Compute emitted water longwave flux from the Stefan-Boltzmann law.
Back longwave emitted by the water [W/m²], OUT of the water.
| [in] | t_water_c | Qualified water degC, converted to K. |
| [in] | emiss_water | Dimensionless water emissivity, normally[0,1]. |
|
noexcept |
Build a conduit finite-bed pair from current wet perimeter and resolved element material.
Bed conductances for link j from the deck configuration and the link's current hydraulics.
| [in] | ctx | Stable prepared link/native geometry/global+resolved bed overrides/water constants. |
| [in] | link | Valid zero-based link index. |
| [in] | vol_ft3 | Accepted positive native conduit water volume ft3. |
| [in] | t_gr | Already sampled global deep-ground degC, used when global series configured. |
Contact area is the WETTED PERIMETER times length times barrels — see BedZoneData.hpp divergence 1. Returns a non-viable coupling (which relaxPair treats as a no-op) for a dry link, a non-conduit, or a link whose perimeter cannot be formed. t_gr is passed in rather than resolved here because the TIMESERIES lookup is GLOBAL scope: one lookup per STEP, not one per link. That is updateSolarForcing's pattern and the reason it exists. PE2: the link's own SedimentConfig (per-element overrides included) is resolved INSIDE, so every caller of the link form gets per-element bed attributes without threading them.
|
noexcept |
Construct finite water/bed conductance and capacity from one SI contact footprint.
The material half of the coupling, geometry already folded in.
| [in] | ctx | Stable positive SI water density kg/m3 and specific heat J/(kg*K). |
| [in] | sc | Qualified SI thermal diffusivity m2/s, thickness/deep depth m, solid density kg/m3, specific heat J/(kg*K), hyporheic velocity m/s and held ground parameters. |
| [in] | bed_m2 | Nonnegative contact area m2. |
| [in] | vol_ft3 | Positive native water volume ft3, converted once to m3 for heat capacity. |
| [in] | t_gr | Held selected deep-ground temperature degC. |
Split out of bedCouplingForLink for the ARD binding: a CELL has its own contact area and volume but the same material math, and a second hand-written copy of that math is how the two engines' beds would come to disagree about the same sediment. LEGACY and LARD go through bedCouplingForLink (link geometry); ARD computes its per-cell bed_m2/vol_ft3 and calls this directly.
PE2: sc is the SedimentConfig in force for the element — sedimentFor(ctx, elem), or the global for a caller with no element. The check found the handoff's draft resolving the per-element table and never passing it to ANY bed reader: both links of the per-tag gate cooled to the identical bit.
|
noexcept |
Test current native finite-bed heat family process enable.
True when [HEAT_FLUXES] SEDIMENT_EXCHANGE is on and heat transport is.
| [in] | ctx | Stable global process/family flags. |
|
noexcept |
Compute total finite-bed solute exchange rate from diffusion and hyporheic velocity.
| [in] | cfg | Qualified SI sediment config, diffusivity m2/s, thickness m and hyporheic velocity m/s. |
| [in] | bed_m2 | Nonnegative contact area m2. |
Total solute exchange discharge across a bed interface of bed_m2, m³/s: D_sed·A/Y + v_hyp·A. One spelling, used by every engine's solute loop.
|
noexcept |
Estimate clear-sky global horizontal irradiance with Bird-Hulstrom terms.
| pos | Compatible solarPosition result with nonnegative cosine and valid zenith/eccentricity. The cosine and zenith must describe the same instant. |
| pressure_mb | Finite nonnegative station pressure in millibars. |
| cfg | Physical aerosol optical depths, precipitable water/ozone centimetres and land ground-albedo fraction. Caller validates finite model ranges. |
|
noexcept |
Compute the dimensionless Bowen sensible-to-latent ratio at held weather.
| [in] | t_water_c | Water degC. |
| [in] | t_air_c | Air degC. |
| [in] | humidity_pct | Relative humidity percent, normally[0,100]. |
| [in] | pressure_ratio | Dimensionless atmospheric pressure ratio. |
Bowen ratio [-]. Returns 0 when the vapour-pressure deficit vanishes, which is the removable singularity in Br's definition, not an error.
|
noexcept |
Compute the cloud atmospheric-emissivity multiplier 1+k_lw*C^2.
| cloud_fraction | Cloud fraction; nonpositive or NaN returns literal one; positive values above one are capped at one. |
| k_lw | Finite dimensionless enhancement coefficient, normally nonnegative. |
|
noexcept |
Compute the cloud attenuation multiplier max(0,1-k*C^n).
| cloud_fraction | Cloud fraction; nonpositive or NaN returns literal one; positive values above one are capped at one. |
| k | Finite dimensionless attenuation coefficient, normally nonnegative. |
| n | Finite exponent compatible with the positive cloud fraction. |
|
noexcept |
Compute the positive-damping linearized equilibrium temperature.
| [in] | t0_c | Initial water degC. |
| [in] | j0 | Outward flux W/m2 at initial temperature. |
| [in] | j1 | Outward flux at t0_c+h. |
| [in] | h | Positive finite probe offset degC. |
The equilibrium temperature the linearization relaxes toward, °C — T₀ − J₀/J′. Exported so a gate can assert the no-overshoot property against it directly rather than recomputing the slope by hand. Returns t0_c when J′ ≤ 0, matching relaxT's fallback.
|
noexcept |
Compute signed vapor-deficit-driven water surface evaporation velocity.
Evaporative mass-transfer rate [m/s]. Negative under condensation.
| [in] | t_water_c | Qualified water degC. |
| [in] | t_air_c | Qualified air degC. |
| [in] | humidity_pct | Relative humidity percent, normally[0,100]; not clamped here. |
| [in] | wind_ms | Wind m/s, negative floored0. |
| [in] | a | Mass-transfer intercept m/s/kPa. |
| [in] | b | Mass-transfer wind slope (m/s/kPa)/(m/s). |
|
noexcept |
One exact step of the two-body solute exchange.
Both concentrations must use the same native units; no unit conversion or physical inventory mutation occurs. Positive finite volumes m3, exchange m3/s and dt s are required; each nonpositive/NaN argument returns zero. Exactly decays concentration difference and pairs increments by volume shares; computed nonfinite share returns zero silently, not an error diagnostic. No independent concentration positivity/finite validation or clock mutation; pure/allocation-free.
| c_w | Channel concentration. |
| c_b | Bed concentration. |
| vol_w | Channel water volume, m³. |
| vol_b | Bed water volume, m³ (bed volume x porosity is the honest reading; the reference uses the bulk volume and so does this, see the header note on porosity). |
| q_exch | Total exchange discharge, m³/s: D_sed*A/Y + v_hyp*A. |
| dt | Step, seconds. |
vol_w*dc_w + vol_b*dc_b == 0 to relative round-off. See the header on why this is not bit-exact.
|
noexcept |
Publish native conduit thermal region geometry in SI.
Shared LEGACY/LARD geometry adapter, in SI. ARD supplies its actual cell geometry.
| [in] | ctx | Stable native link/subtype/shape/length/depth/barrel metadata. |
| [in,out] | region | Its link selects valid conduit; receives length/depth m, free surface/bed m2. Invalid link/non-conduit returns leaving all existing geometry unchanged. |
|
noexcept |
Sample the global held deep-ground temperature at native absolute model time.
| [in,out] | ctx | Stable sediment configuration/table store/current_date; lookup can advance selected table's mutable cursor without changing table ordinates or engine clock. |
The deep-ground temperature in force this step, °C — resolves the GROUND_TEMPERATURE TIMESERIES spelling against the simulation clock. Non-const because the timeseries lookup advances the table's own cursor, exactly as table_tseries_lookup_cursor does everywhere else.
|
noexcept |
Choose one element's held deep-ground constant or globally sampled series temperature.
| [in] | ctx | Stable global sediment.ground_ts_index configuration. |
| [in] | sc | Resolved per-element sediment block with ground_temp degC. |
| [in] | t_gr_global | Previously sampled global ground temperature degC. |
PE2: the deep-ground temperature in force for ONE element. The global GROUND_TEMPERATURE TIMESERIES wins when configured — the TIMESERIES spelling is GLOBAL-only by grammar (per-element series are PE3/D-PE7) — otherwise the element's own resolved constant. For a model with no overrides sc.ground_temp IS the global constant, so this returns exactly what groundTemperature returned, by construction.
|
noexcept |
Compute visible land-cover longwave contribution into water.
Land-cover longwave [W/m²], INTO the water.
| [in] | t_air_c | Radiating land-cover temperature degC; parameter historical name reflects fallback air temperature, caller may supply configured distinct land-cover temperature. |
| [in] | emiss_landcover | Dimensionless emissivity, normally[0,1]. |
| [in] | sky_view | Visible-sky fraction, so land cover uses complement1-sky_view. |
|
noexcept |
Convert signed surface evaporation into outward latent heat flux.
Latent heat flux [W/m²], POSITIVE out of the water.
| [in] | t_water_c | Water degC for vapor pressure and latent heat. |
| [in] | t_air_c | Air degC. |
| [in] | humidity_pct | Relative humidity percent. |
| [in] | wind_ms | Wind m/s, negative floored0. |
| [in] | a | Wind-function intercept m/s/kPa. |
| [in] | b | Wind-function slope (m/s/kPa)/(m/s). |
| [in] | water_density | Positive water density kg/m3. |
|
noexcept |
Compute temperature-dependent latent heat of vaporization.
| [in] | t_c | Qualified water temperature degC. |
Latent heat of vaporization at t_c degrees Celsius [J/kg] (Martin & McCutcheon 1998).
|
noexcept |
Compute wetted conduit bed contact area from native geometry.
| [in] | ctx | Stable valid conduit subtype mapping, native dimensions/depth/length/barrels. |
| [in] | link | Valid zero-based native link index, unchecked before several array accesses. |
Bed contact area for link j, m² — wetted perimeter × length × barrels (divergence 1). 0 for a dry link or a non-conduit.
|
noexcept |
Compute native open-conduit free surface for heat/evaporation binding.
| [in] | ctx | Stable prepared subtype/shape/geometry, length and barrel metadata. |
| [in] | link | Valid zero-based native link index, unchecked. |
Free-surface area for link j, ft² — top width × length × barrels for an OPEN conduit, 0 otherwise. The Routing.cpp:597 evaporation-area expression, exported so the LARD binding does not grow a fourth copy of the XSectParams builder.
|
noexcept |
Sum enabled element latent/sensible and radiative flux under one outward sign convention.
Net outward surface flux at t_w, summed over every enabled module [W/m²].
| [in] | ctx | Stable heat/weather/element-override context; providers nonthrowing and already sampled. |
| [in] | elem | Element identity selecting prepared local attributes/weather, or global default. |
| [in] | t_w | Qualified water degC, passed unchanged to both flux families. |
Each module's evaluator returns 0 when its own [HEAT_FLUXES] toggle is off, so this sums unconditionally and no caller has to know which families exist. This is the extension point: a new flux family is one added term here and nowhere else.
Shared with the ARD mesh and watershed bindings, which have their own element geometry but must compose the flux identically — the alternative being four hand-rolled copies of the same sum, which is the duplication that produced the defect above.
PE1: elem names WHICH element is being evaluated, so a module can read per-element attributes (shading, sky view, bed properties) instead of one global block. Passing a default- constructed HeatElement yields the global config — which is exactly what every caller got before PE — so a binding that forgets to pass its element degrades to the old behaviour rather than reading element 0's attributes.
|
noexcept |
Combine water emission with absorbed shortwave, sky longwave and land-cover longwave.
| [in] | t_water_c | Qualified water degC. |
| [in] | t_air_c | Held air degC. |
| [in] | humidity_pct | Held relative humidity percent. |
| [in] | cfg | Stable element radiative parameters; NaN landcover_temp selects air fallback, otherwise configured degC is used directly. Fractions/emissivities must already qualify. |
| [in] | jin_wm2 | Held incident W/m2; negative sentinel uses cfg.shortwave_wm2, zero is valid night. |
| [in] | cloud_factor | Held dimensionless atmospheric enhancement, used for estimated sky flux. |
| [in] | incoming_longwave | Nonnegative measured/shared sky W/m2 before reflection/sky-view; negative sentinel estimates sky from weather. Measured branch bypasses Brunt/cloud estimate. |
Net radiative flux [W/m²], positive OUT of the water so it sums with SurfaceExchange's Je + Jc.
H6a adds two optional arguments and changes nothing without them:
jin_wm2 < 0 (the default) means "use `cfg.shortwave_wm2`", the H3 behaviour. A caller with a resolved per-step Jin passes it here. The sentinel is negative rather than NaN because a deck may legally mean 0 W/m² (night), and 0 must not be mistaken for "unset".cloud_factor defaults to 1.0 — see atmosphericEmissivity.
|
noexcept |
Compute absorbed incident shortwave after albedo and shade.
Net absorbed shortwave [W/m²], INTO the water.
| [in] | incoming_wm2 | Qualified nonnegative incident solar W/m2. |
| [in] | albedo | Dimensionless reflected fraction, normally[0,1], not clamped. |
| [in] | shade_factor | Dimensionless shade fraction; values>1 fully shade via max(0,1-shade). |
|
noexcept |
Estimate standard-atmosphere station pressure from elevation.
| elevation_m | Finite metres above sea level; negative elevations allowed. Keep 1-2.25577e-5*elevation_m nonnegative for the power-law domain. |
|
noexcept |
Evaluate element radiative flux using the configured global family enable.
| [in] | ctx | Stable held heat/weather/override context, queried without refresh. |
| [in] | elem | Borrowed native element/global identity for local parameter/forcing selection. |
| [in] | t_w | Qualified water degC. |
This module's contribution to the net outward flux at t_w [W/m²]. Returns 0 unless HEAT_TRANSPORT is on AND [HEAT_FLUXES] / RADIATIVE_EXCHANGE is enabled, so a caller sums it unconditionally.
D-H5e: this module no longer has a binding of its own. It had one, with its own element traversal and its own explicit conversion, and that is how it came to relax separately from SurfaceExchange toward a different equilibrium — making the answer depend on which module ran last.
|
noexcept |
Evaluate held element radiation with an explicit domain enable and no global toggle mutation.
Same evaluator with an explicit domain enable; no global mutation.
| [in] | ctx | Stable heat/climate config, prepared solar/cloud/shared longwave and override/provider bindings. Accessors must remain live and nonthrowing through this noexcept query. |
| [in] | elem | Element/global identity selecting cached radiative block and local weather/shortwave. |
| [in] | t_w | Qualified water degC. |
| [in] | enabled | Domain-selected radiation enable, independent of global family flag. |
|
noexcept |
Borrow resolved element radiation parameters with global fallback.
The radiative attributes in force for e.
| [in] | ctx | Stable already-resolved dense radiative overrides and global base, alive through use. |
| [in] | e | Element kind/index; nonnegative in-range LINK/NODE/CELL2D selects corresponding vector. |
Returns the GLOBAL config when no override targets this family, when the element index is out of range, or when the element is not a kind that carries radiative overrides. The empty-vector path returns the very same object the pre-PE engine used, which is what makes a non-PE model bit-identical by construction rather than by tolerance.
|
noexcept |
One exact step of the coupled (water, bed) pair.
| [in] | dt | Positive finite accepted duration s; nonpositive/NaN returns zero increments. |
| g | Conductances and capacities for this element. |
| t_w | Current channel water temperature, °C. |
| t_b | Current bed temperature, °C. |
| j0 | Net outward SURFACE flux at t_w, W/m² (netFluxOut). |
| j1 | The same flux at t_w + h — the probe relaxT already takes, passed in rather than recomputed so the pair is stepped against exactly the function the single body was. |
| h | Probe offset, °C. <= 0 disables the linearization and takes j0 as a constant forcing. |
| area_m2 | Free-surface area the surface flux acts on, m². May be 0 for a closed conduit — the bed terms still apply.
|
{0,0} when g is not viable.relaxT when g_wb == g_bg == 0, to within 1-2 ULP — the two take different but algebraically identical routes to the same scalar, so the last bit can differ. Measured over dt in {1, 60, 900, 86400}: 1 ULP at every step, well inside the 4 ULP EXPECT_DOUBLE_EQ allows. The reduction is what keeps pre-H6b answers unchanged, and it holds only because the module is OFF by default — a deck without SEDIMENT_EXCHANGE never enters relaxPair at all, so byte-identity is exact for the reason that matters, not for this one.
|
noexcept |
One element's temperature change, integrated SEMI-IMPLICITLY [°C].
| [in] | dt | Positive accepted interval s; nonpositive/NaN returns0. |
| [in] | rho | Water density kg/m3; rho*cp*vol_m3 must be positive finite for qualified physics. |
| [in] | cp | Water specific heat J/(kg*K). |
Plan D-H5d. The energy balance ρ cp V dT/dt = −A·J(T) is linearized about the current temperature and the resulting linear ODE is integrated exactly:
k = A·J′ / (ρ cp V) [1/s] T_eq = T₀ − J₀/J′ ΔT = (J₀/J′)·expm1(−k·dt)
This replaces a forward-Euler step that diverged to NaN. Heat capacity is ρ cp V, so a thin film has almost none: a 0.52 ft³ film over 27,226 ft² took a +862 °C step in 60 s and the sequence ran 5 → 182 → −1.8e4 → −3.9e9 → inf → NaN. The explicit form had simply stopped representing the ODE.
Three properties earned this scheme its place, and each is gated:
|ΔT| ≤ |T_eq − T₀| always — the step cannot overshoot equilibrium, whatever dt is. That is an assertion needing no reference value, so no deck or timestep change can stale it.dt → 0 (expm1(−x) ≈ −x), so every small-step answer is unchanged from H2/H3.The flux FORMULATIONS of H2 and H3 were never wrong; only the stepping was. CSH runs these same formulas at a 1e-4 s timestep with a selectable ODE solver — we took its physics and not its integrator.
| j0 | Net flux OUT of the water at T₀, W/m² (sum of every enabled module: Je + Jc from here, Jr from RadiativeExchange — all signed positive out, so they add). |
| j1 | The same sum re-evaluated at T₀ + h. |
| h | The probe offset used for j1; kProbeC unless testing. |
| area_m2 | Exchange area. |
| vol_m3 | Element volume — the thermal mass, and the reason this function exists. |
J′ ≤ 0 (anti-damping: the linearized system has no fixed point to relax onto, so there is nothing to be stable about). | std::vector< std::string > openswmm::transport::heat::resolveHeatOverrides | ( | SimulationContext & | ctx | ) |
Materialize retained per-element/tag/mesh heat attributes in dense lookup vectors.
Materialise the dense per-element vectors from the parsed rows.
| [in,out] | ctx | Fully parsed matching native names/tags and optional mesh, global radiative/ sediment config and retained override rows; receives resolved flag and dense family vectors. |
Called ONCE from SWMMEngine::open, after every process component has applied — the D-RQ1 timing, so link_names, node_names and the [TAGS] columns are all complete and an unknown element name can be reported with the row that named it.
Precedence is applied by CONSTRUCTION rather than by comparison: rows are swept in scope order (GLOBAL is already in the base config, then TAG, then element), so a later write simply wins. A comparison-based resolver would have to encode the ordering a second time and the two spellings could disagree.
|
noexcept |
Compute saturation vapor pressure from the Magnus water-temperature formula.
Saturation vapour pressure over water at t_c degrees Celsius [kPa].
| [in] | t_c | Qualified finite water/air temperature degC, away from -237.3 singular denominator. |
|
noexcept |
Borrow resolved conduit/mesh-cell sediment parameters with global fallback.
The bed attributes in force for e.
| [in] | ctx | Stable already-resolved dense sediment overrides/global base, alive through use. |
| [in] | e | Nonnegative in-range LINK or CELL2D selects matching dense row; NODE/global/invalid falls back to global block. |
Dense bed overrides support LINK and CELL2D scopes for their respective finite physical owners. NODE and unsupported/out-of-range identities read the global configuration. The accessor does not create a bed or qualify runtime ownership.
| void openswmm::transport::heat::seedBedTemperature | ( | SimulationContext & | ctx | ) |
Size and seed native link bed temperatures at their initial owner phase.
Size and seed the bed temperature array, idempotently.
| [in,out] | ctx | Retained bed state and current native link count/global sediment config. |
There is deliberately no applyBedHeatExchange. A function by that name would be called beside applyHeatFluxes and would step the bed in its own relaxation — which is D-H5e's defect, one phase after D-H5e removed it. The heat coupling instead happens INSIDE applyHeatFluxes's link loop, which calls relaxPair with the real j0/j1/area so the surface families and the bed are one simultaneous step. This function is only the state setup that loop needs first.
|
noexcept |
Form signed outward sensible flux from latent flux and Bowen ratio.
Sensible heat flux [W/m²], POSITIVE out of the water.
| [in] | latent_flux | Signed latent W/m2. |
| [in] | bowen_ratio | Dimensionless held ratio. |
|
noexcept |
Compute Spencer/NOAA sun geometry at a local civil-clock instant.
| day_of_year | Calendar ordinal in [1,366]; the fit uses a 365-day denominator. |
| hour_local | Finite decimal local hour, normally [0,24). |
| lat_deg | Latitude degrees north in [-90,90]. |
| lon_deg | Finite longitude degrees east, normally [-180,180]. |
| tz_hours | Finite civil offset hours east of UTC; no daylight-saving lookup. |
|
noexcept |
Evaluate one element's enabled latent+sensible outward atmospheric flux.
This module's contribution to the net outward flux at t_w [W/m²].
| [in] | ctx | Stable heat/process configuration, native climate and already prepared element forcing providers/caches; query callbacks must be nonthrowing for this noexcept path. |
| [in] | elem | Borrowed node/link/subcatch/global identity selecting held weather overrides. |
| [in] | t_w | Qualified water temperature degC. |
Returns 0 unless HEAT_TRANSPORT is on AND [HEAT_FLUXES] SURFACE_EXCHANGE is enabled, so a caller sums it unconditionally and the toggle stays this module's business.
k·dt it landed on whichever module ran last. Every flux family now sums into one J(T) before a single relaxation, in HeatFluxes.cpp. | void openswmm::climate::updateSolarForcing | ( | SimulationContext & | ctx, |
| double | seconds = 1 ) |
Update shared heat shortwave/cloud forcing with mesh radiation disabled.
| [in,out] | ctx | Initialized heat/climate/snow state at current_date; serializes table cursors and shared output state with other forcing readers/writers. |
| seconds | Interval seconds forwarded to the snow resolver when authored radiation/MET_FILE is present; default one. Otherwise legacy heat uses an instant. Equivalent to the three-argument overload with mesh_enabled=false; same failure and mutation behavior. Call before flux evaluation on each consuming clock. |
|
noexcept |
Evaluate the mass-transfer wind function with nonnegative wind speed.
Mass-transfer wind function a + b·w, w in m/s [m/s/kPa].
| [in] | wind_ms | Wind m/s, negative floored0; no general NaN/finite repair. |
| [in] | a | Intercept m/s/kPa. |
| [in] | b | Slope in (m/s/kPa)/(m/s). |
|
inlineconstexpr |
Bowen's coefficient, kPa/°C (CSH §4.5).
|
inlineconstexpr |
ft³ → m³.
|
inlineconstexpr |
Celsius → Kelvin offset.
|
inlineconstexpr |
mph → m/s. ClimateState::wind_speed is mph.
|
inlineconstexpr |
Probe offset for the flux derivative, °C. Small enough that J′ is the local slope, large enough that the difference is not float noise.
|
inlineconstexpr |
Solar constant, W/m² (Bird & Hulstrom 1981; WMO 1982).
|
inlineconstexpr |
ft² → m². Exported with relaxT, which is useless without it.
|
inlineconstexpr |
Sea-level standard pressure, millibars — Bird's pressure reference.
|
inlineconstexpr |
Stefan–Boltzmann constant, W/m²/K⁴ (rhemodel.cpp:46).