OpenSWMM Engine  6.0.0-alpha.3
Data-oriented, plugin-extensible SWMM Engine (6.0.0-alpha.3)
Loading...
Searching...
No Matches
UnitConversion.hpp
Go to the documentation of this file.
1
24
25#ifndef OPENSWMM_UNIT_CONVERSION_HPP
26#define OPENSWMM_UNIT_CONVERSION_HPP
27
28#include <array>
29
30namespace openswmm {
31
33
34namespace ucf {
35
36// ============================================================================
37// Quantity codes — matching legacy enums.h
38// ============================================================================
39
53
54// ============================================================================
55// Conversion factor tables — identical to legacy Ucf[10][2] and Qcf[6]
56// ============================================================================
57
60static constexpr double Ucf[10][2] = {
61 // US SI
62 {43200.0, 1097280.0 }, // RAINFALL: in/hr, mm/hr → ft/sec
63 {12.0, 304.8 }, // RAINDEPTH: in, mm → ft
64 {1036800.0, 26334720.0}, // EVAPRATE: in/day, mm/day → ft/sec
65 {1.0, 0.3048 }, // LENGTH: ft, m → ft
66 {2.2956e-5, 0.92903e-5}, // LANDAREA: ac, ha → ft²
67 {1.0, 0.02832 }, // VOLUME: ft³, m³ → ft³
68 {1.0, 1.608 }, // WINDSPEED: mph, km/hr → mph
69 {1.0, 1.8 }, // TEMPERATURE: °F, °C → °F
70 {2.203e-6, 1.0e-6 }, // MASS: lb, kg → mg
71 {43560.0, 3048.0 } // GWFLOW: cfs/ac, cms/ha → ft/sec
72};
73
75static constexpr double Qcf[6] = {
76 1.0, // CFS → cfs
77 448.831, // GPM → cfs
78 0.64632, // MGD → cfs
79 0.02832, // CMS → cfs
80 28.317, // LPS → cfs
81 2.4466 // MLD → cfs
82};
83
84// ============================================================================
85// Precomputed reciprocal tables — multiply instead of divide
86// ============================================================================
87//
88// Display → internal conversion is `internal = display / Ucf` everywhere. To
89// let hot/peripheral conversion sites multiply by a hoisted loop-invariant
90// instead of dividing, expose the compile-time reciprocals. These are derived
91// from Ucf/Qcf so they can never drift out of sync.
92//
93// Convention: internal = display * Ucf_inv[q][us] (display → internal)
94// display = internal * Ucf[q][us] (internal → display)
95
96namespace detail {
97inline constexpr std::array<std::array<double, 2>, 10> makeUcfInv() {
98 std::array<std::array<double, 2>, 10> r{};
99 for (int q = 0; q < 10; ++q)
100 for (int u = 0; u < 2; ++u)
101 r[static_cast<std::size_t>(q)][static_cast<std::size_t>(u)] =
102 1.0 / Ucf[q][u];
103 return r;
104}
105inline constexpr std::array<double, 6> makeQcfInv() {
106 std::array<double, 6> r{};
107 for (int f = 0; f < 6; ++f) r[static_cast<std::size_t>(f)] = 1.0 / Qcf[f];
108 return r;
109}
110} // namespace detail
111
113inline constexpr std::array<std::array<double, 2>, 10> Ucf_inv = detail::makeUcfInv();
114
116inline constexpr std::array<double, 6> Qcf_inv = detail::makeQcfInv();
117
118// ============================================================================
119// Convenience constants — common fixed conversions not unit-system dependent
120// ============================================================================
121
122static constexpr double ACRES_TO_FT2 = 43560.0;
123static constexpr double FT3_TO_MGAL = 7.48052e-6;
124static constexpr double SEC_PER_DAY = 86400.0;
125
126// ============================================================================
127// UCF function — matching legacy UCF()
128// ============================================================================
129
146double UCF(int quantity, const SimulationOptions& opts);
147
160double UCF_inv(int quantity, const SimulationOptions& opts);
161
169int getUnitSystem(int flow_units);
170
172inline constexpr const char* FlowUnitWords[6] =
173 { "CFS", "GPM", "MGD", "CMS", "LPS", "MLD" };
174
175// ============================================================================
176// DisplayUnits — single source of truth for internal → display conversion
177// ============================================================================
178//
179// Built once from SimulationOptions via DisplayUnits::from(). Carries the
180// internal→display multipliers (display = internal * factor) plus the matching
181// unit-label words, so every output / report consumer shares one definition
182// instead of re-deriving Ucf / Qcf inline. Mirrors legacy statsrpt.c / report.c
183// UCF()-based output and the VolUnitsWords / PondingUnitsWords tables.
185 int unit_system = 0;
186 int flow_units = 0;
187
188 // --- internal → display multipliers (display = internal * factor) ---
189 double flow = 1.0;
190 double length = 1.0;
191 double volume = 1.0;
192 double rainfall = 1.0;
193 double raindepth = 1.0;
194 double evaprate = 1.0;
195 double landarea = 1.0;
196 double mvol = 1.0;
197 double landvol = 1.0;
198
199 // --- unit-label words (legacy statsrpt.c / report.c) ---
200 const char* flow_word = "CFS";
201 const char* length_word = "Feet";
202 const char* depth_word = "in";
203 const char* vel_word = "ft/sec";
204 const char* mvol_word = "10^6 gal";
205 const char* landvol_word = "acre-feet";
206 const char* storage_vol_word = "1000 ft3";
207
209 static DisplayUnits from(const SimulationOptions& opts);
210
212 double temperature(double tF) const {
213 return unit_system == 0 ? tF : (5.0 / 9.0) * (tF - 32.0);
214 }
215};
216
217} // namespace ucf
218} // namespace openswmm
219
220#endif // OPENSWMM_UNIT_CONVERSION_HPP
Definition UnitConversion.hpp:96
constexpr std::array< double, 6 > makeQcfInv()
Definition UnitConversion.hpp:105
constexpr std::array< std::array< double, 2 >, 10 > makeUcfInv()
Definition UnitConversion.hpp:97
Definition UnitConversion.cpp:15
constexpr const char * FlowUnitWords[6]
Legacy FlowUnitWords — index by FlowUnits enum (CFS,GPM,MGD,CMS,LPS,MLD).
Definition UnitConversion.hpp:172
constexpr std::array< std::array< double, 2 >, 10 > Ucf_inv
Reciprocal of Ucf[quantity][unit_system] — multiply display by this → internal.
Definition UnitConversion.hpp:113
Quantity
Definition UnitConversion.hpp:40
@ TEMPERATURE
Divide °F (US) or °C (SI) by this → °F.
Definition UnitConversion.hpp:48
@ EVAPRATE
Divide in/day (US) or mm/day (SI) by this → ft/sec.
Definition UnitConversion.hpp:43
@ LANDAREA
Divide ac (US) or ha (SI) by this → ft²
Definition UnitConversion.hpp:45
@ MASS
Divide lb (US) or kg (SI) by this → mg.
Definition UnitConversion.hpp:49
@ VOLUME
Divide ft³ (US) or m³ (SI) by this → ft³
Definition UnitConversion.hpp:46
@ FLOW
Divide display flow units by this → cfs.
Definition UnitConversion.hpp:51
@ RAINFALL
Divide in/hr (US) or mm/hr (SI) by this → ft/sec.
Definition UnitConversion.hpp:41
@ RAINDEPTH
Divide in (US) or mm (SI) by this → ft.
Definition UnitConversion.hpp:42
@ WINDSPEED
Divide mph (US) or km/hr (SI) by this → mph.
Definition UnitConversion.hpp:47
@ LENGTH
Divide ft (US) or m (SI) by this → ft.
Definition UnitConversion.hpp:44
@ GWFLOW
Divide cfs/ac (US) or cms/ha (SI) by this → ft/sec.
Definition UnitConversion.hpp:50
constexpr std::array< double, 6 > Qcf_inv
Reciprocal of Qcf[flow_units] — multiply display flow by this → cfs.
Definition UnitConversion.hpp:116
double UCF(int quantity, const SimulationOptions &opts)
Get unit conversion factor for a quantity.
Definition UnitConversion.cpp:23
double UCF_inv(int quantity, const SimulationOptions &opts)
Reciprocal of UCF — multiply display by this to get internal units.
Definition UnitConversion.cpp:37
int getUnitSystem(int flow_units)
Determine unit system (0=US, 1=SI) from flow units.
Definition UnitConversion.cpp:17
Definition NodeCoupling.cpp:15
All SWMM simulation options parsed from [OPTIONS] section.
Definition SimulationOptions.hpp:124
Definition UnitConversion.hpp:184
const char * depth_word
rainfall / runoff depth (in | mm)
Definition UnitConversion.hpp:202
int flow_units
FlowUnits enum value.
Definition UnitConversion.hpp:186
const char * vel_word
link velocity (ft/sec | m/sec)
Definition UnitConversion.hpp:203
double landarea
ft² → ac | ha
Definition UnitConversion.hpp:195
const char * flow_word
CFS | CMS | ...
Definition UnitConversion.hpp:200
const char * mvol_word
10^6 gal | 10^6 ltr
Definition UnitConversion.hpp:204
double length
ft → ft | m
Definition UnitConversion.hpp:190
double temperature(double tF) const
Internal temperature (°F) → display (°F for US, °C for SI).
Definition UnitConversion.hpp:212
static DisplayUnits from(const SimulationOptions &opts)
Build from simulation options (selects unit system + flow units).
Definition UnitConversion.cpp:51
double rainfall
ft/s → in/hr | mm/hr
Definition UnitConversion.hpp:192
double volume
ft³ → ft³ | m³
Definition UnitConversion.hpp:191
double raindepth
ft → in | mm (also runoff-depth columns)
Definition UnitConversion.hpp:193
const char * storage_vol_word
1000 ft3 | 1000 m3
Definition UnitConversion.hpp:206
double mvol
ft³ → 10^6 gal | 10^6 ltr
Definition UnitConversion.hpp:196
const char * landvol_word
acre-feet | hectare-m
Definition UnitConversion.hpp:205
int unit_system
0 = US, 1 = SI
Definition UnitConversion.hpp:185
double flow
cfs → display flow (Qcf)
Definition UnitConversion.hpp:189
double evaprate
ft/s → in/day | mm/day
Definition UnitConversion.hpp:194
double landvol
ft³ → acre-ft | hectare-m
Definition UnitConversion.hpp:197
const char * length_word
depth / HGL / surcharge column
Definition UnitConversion.hpp:201