OpenSWMM Engine  6.0.0-alpha.4
Data-oriented, plugin-extensible SWMM Engine (6.0.0-alpha.4)
Loading...
Searching...
No Matches
StorageGeometry.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
43
44#ifndef OPENSWMM_ENGINE_DATA_STORAGEGEOMETRY_HPP
45#define OPENSWMM_ENGINE_DATA_STORAGEGEOMETRY_HPP
46
47#include "NodeData.hpp"
48
49#include <cmath>
50#include <string>
51#include <string_view>
52
53namespace openswmm {
54
56inline constexpr double kStoragePi = 3.141592653589793;
57
66
74 double p1, double p2, double p3) noexcept {
75 if (!storage_shape_is_geometric(s)) return true;
76 if (p1 <= 0.0 || p2 <= 0.0 || p3 < 0.0) return false;
77 if (s == StorageShape::PARABOLOID && p3 == 0.0) return false;
78 return true;
79}
80
99inline bool storage_shape_coeffs(StorageShape s, double p1, double p2, double p3,
100 double& a, double& b, double& c) noexcept {
101 if (!storage_shape_is_geometric(s)) return false;
102 if (!storage_shape_params_valid(s, p1, p2, p3)) return false;
103
104 const double A = p1 / 2.0; // base/top semi-axis length
105 const double B = p2 / 2.0; // base/top semi-axis width
106 const double Z = p3; // side slope (run/rise), or height for PARABOLOID
107
108 switch (s) {
110 a = 0.0;
111 b = 0.0;
112 c = kStoragePi * A * B;
113 return true;
115 a = 2.0 * kStoragePi * B * Z;
116 b = kStoragePi * B / A * Z * Z;
117 c = kStoragePi * A * B;
118 return true;
120 a = kStoragePi * A * B / Z; // Z != 0 guaranteed by params_valid
121 b = 0.0;
122 c = 0.0;
123 return true;
125 a = 2.0 * (p1 + p2) * Z; // 2(L + W)Z — full base dims, not semi-axes
126 b = 4.0 * Z * Z;
127 c = p1 * p2; // L·W
128 return true;
129 default:
130 return false;
131 }
132}
133
139inline const char* storage_shape_keyword(StorageShape s) noexcept {
140 switch (s) {
141 case StorageShape::TABULAR: return "TABULAR";
142 case StorageShape::FUNCTIONAL: return "FUNCTIONAL";
143 case StorageShape::CYLINDRICAL: return "CYLINDRICAL";
144 case StorageShape::CONICAL: return "CONICAL";
145 case StorageShape::PARABOLOID: return "PARABOLIC";
146 case StorageShape::PYRAMIDAL: return "PYRAMIDAL";
147 }
148 return "FUNCTIONAL";
149}
150
157inline bool storage_shape_from_keyword(std::string_view kw, StorageShape& out) noexcept {
158 if (kw == "TABULAR") { out = StorageShape::TABULAR; return true; }
159 if (kw == "FUNCTIONAL") { out = StorageShape::FUNCTIONAL; return true; }
160 if (kw == "CYLINDRICAL") { out = StorageShape::CYLINDRICAL; return true; }
161 if (kw == "CONICAL") { out = StorageShape::CONICAL; return true; }
162 if (kw == "PARABOLIC" || kw == "PARABOLOID")
163 { out = StorageShape::PARABOLOID; return true; }
164 if (kw == "PYRAMIDAL") { out = StorageShape::PYRAMIDAL; return true; }
165 return false;
166}
167
169inline constexpr bool storage_shape_is_valid_code(int v) noexcept {
170 return v >= static_cast<int>(StorageShape::TABULAR) &&
171 v <= static_cast<int>(StorageShape::PYRAMIDAL);
172}
173
174} // namespace openswmm
175
176#endif // OPENSWMM_ENGINE_DATA_STORAGEGEOMETRY_HPP
Structure-of-Arrays (SoA) storage for all node types.
Definition NodeCoupling.cpp:16
StorageShape
Storage-unit surface-area relation.
Definition NodeData.hpp:104
@ CONICAL
Elliptical cone (p1, p2 = base axes, p3 = side slope)
Definition NodeData.hpp:108
@ PYRAMIDAL
Rectangular pyramid (p1 = length, p2 = width, p3 = side slope)
Definition NodeData.hpp:110
@ TABULAR
Area vs. depth from a curve (StorageData::curve)
Definition NodeData.hpp:105
@ PARABOLOID
Elliptical paraboloid(p1, p2 = top axes, p3 = height ≠ 0)
Definition NodeData.hpp:109
@ CYLINDRICAL
Elliptical cylinder (p1 = major axis, p2 = minor axis)
Definition NodeData.hpp:107
@ FUNCTIONAL
Area = c + a*d^b.
Definition NodeData.hpp:106
constexpr bool storage_shape_is_valid_code(int v) noexcept
True when v is a valid StorageShape ordinal (C API boundary check).
Definition StorageGeometry.hpp:169
bool storage_shape_from_keyword(std::string_view kw, StorageShape &out) noexcept
Parse a shape keyword (caller upper-cases first).
Definition StorageGeometry.hpp:157
constexpr double kStoragePi
π to the precision legacy uses (src/legacy/engine/consts.h).
Definition StorageGeometry.hpp:56
bool storage_shape_coeffs(StorageShape s, double p1, double p2, double p3, double &a, double &b, double &c) noexcept
Derive the area-relation coefficients for a geometric shape.
Definition StorageGeometry.hpp:99
bool storage_shape_params_valid(StorageShape s, double p1, double p2, double p3) noexcept
Validate raw shape parameters.
Definition StorageGeometry.hpp:73
constexpr bool storage_shape_is_geometric(StorageShape s) noexcept
True when s is one of the four geometric shapes (i.e. its a/b/c are the quadratic coefficients,...
Definition StorageGeometry.hpp:62
const char * storage_shape_keyword(StorageShape s) noexcept
Canonical INP/GeoPackage keyword for a shape.
Definition StorageGeometry.hpp:139