OpenSWMM Engine  6.0.0-alpha.4
Data-oriented, plugin-extensible SWMM Engine (6.0.0-alpha.4)
Loading...
Searching...
No Matches
Serialize2D.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
41
42#ifndef OPENSWMM_ENGINE_2D_SERIALIZE_2D_HPP
43#define OPENSWMM_ENGINE_2D_SERIALIZE_2D_HPP
44
45#include "MeshData.hpp"
46#include "BoundaryData.hpp"
47#include "PendingRows2D.hpp"
48
49#include <algorithm>
50#include <cstdint>
51#include <string>
52#include <unordered_map>
53#include <unordered_set>
54#include <vector>
55
56namespace openswmm::twoD {
57
82inline std::vector<PendingBoundaryRow> collectBCRows(
83 const std::vector<PendingBoundaryRow>* pending,
84 const BoundaryData* boundary,
85 bool drained,
86 double flow_to_si_applied = 1.0) {
87
88 const double flow_to_display =
89 (flow_to_si_applied > 0.0) ? 1.0 / flow_to_si_applied : 1.0;
90
91 if (!drained) {
92 if (pending && !pending->empty()) return *pending;
93 // Not drained and no pending rows: nothing has been authored yet
94 // (boundary, if sized at all, holds only WALL defaults).
95 }
96
97 std::vector<PendingBoundaryRow> rows;
98 if (!boundary) return rows;
99
100 const int n = boundary->size();
101 for (int idx = 0; idx < n; ++idx) {
102 const auto type =
103 static_cast<BoundaryType>(boundary->edge_bc_type[idx]);
104 if (type == BoundaryType::WALL) continue;
105
107 r.tri = MeshData::slot_cell(idx);
108 r.edge = MeshData::slot_local(idx);
109 r.bc_type = static_cast<int>(type);
110
111 switch (type) {
113 r.param1 = boundary->edge_bed_slope[idx];
114 break;
116 if (!boundary->edge_bc_tseries_name[idx].empty())
117 r.name = boundary->edge_bc_tseries_name[idx];
118 else
119 r.param1 = boundary->edge_bc_head[idx];
120 break;
122 if (!boundary->edge_bc_flow_tseries_name[idx].empty())
123 r.name = boundary->edge_bc_flow_tseries_name[idx];
124 else
125 r.param1 = boundary->edge_bc_flow[idx] * flow_to_display;
126 break;
128 r.name = boundary->edge_bc_rating_curve_name[idx];
129 break;
131 break;
132 }
133 rows.push_back(std::move(r));
134 }
135
136 // Re-attach the authored GROUP labels (organizational metadata that
137 // BoundaryData does not carry) from the retained pending rows.
138 if (pending && !pending->empty() && !rows.empty()) {
139 std::unordered_map<int, const std::string*> groups;
140 groups.reserve(pending->size());
141 for (const auto& p : *pending) {
142 if (!p.group.empty()) groups[MeshData::slot(p.tri, p.edge)] = &p.group;
143 }
144 if (!groups.empty()) {
145 for (auto& r : rows) {
146 auto it = groups.find(MeshData::slot(r.tri, r.edge));
147 if (it != groups.end()) r.group = *it->second;
148 }
149 }
150 }
151 return rows;
152}
153
173inline std::vector<PendingEdgeConveyanceRow> collectConveyanceRows(
174 const std::vector<PendingEdgeConveyanceRow>* pending,
175 const MeshData* mesh,
176 bool drained) {
177
178 if (!drained && pending && !pending->empty()) return *pending;
179
180 std::vector<PendingEdgeConveyanceRow> rows;
181 if (!mesh) return rows;
182
183 const int nt = mesh->n_triangles();
184 if (nt < 1 ||
185 mesh->edge_conveyance.size() < static_cast<std::size_t>(mesh->n_edge_slots()))
186 return rows;
187
188 std::unordered_set<std::int64_t> seen;
189 for (int t = 0; t < nt; ++t) {
190 const int nvc = mesh->cell_vertex_count(t);
191 for (int e = 0; e < nvc; ++e) {
192 const double k = mesh->edge_conveyance[MeshData::slot(t, e)];
193 if (k == 1.0) continue;
194 int ea, eb;
195 mesh->cell_edge_vertices(t, e, ea, eb);
196 const int va = std::min(ea, eb);
197 const int vb = std::max(ea, eb);
198 const std::int64_t key =
199 (static_cast<std::int64_t>(va) << 32)
200 | (static_cast<std::int64_t>(vb) & 0xFFFFFFFFLL);
201 if (!seen.insert(key).second) continue;
202 rows.push_back(PendingEdgeConveyanceRow{va, vb, k});
203 }
204 }
205 return rows;
206}
207
208} // namespace openswmm::twoD
209
210#endif // OPENSWMM_ENGINE_2D_SERIALIZE_2D_HPP
Structure-of-Arrays (SoA) storage for 2D mesh boundary conditions.
Structure-of-Arrays (SoA) storage for 2D triangular mesh geometry.
Parse-time scratch rows for [2D_BOUNDARY_CONDITIONS] and [2D_EDGE_CONVEYANCE] input sections.
Definition NodeCoupling.cpp:16
std::vector< PendingBoundaryRow > collectBCRows(const std::vector< PendingBoundaryRow > *pending, const BoundaryData *boundary, bool drained, double flow_to_si_applied=1.0)
Collect [2D_BOUNDARY_CONDITIONS]-shaped rows for serialization.
Definition Serialize2D.hpp:82
std::vector< PendingEdgeConveyanceRow > collectConveyanceRows(const std::vector< PendingEdgeConveyanceRow > *pending, const MeshData *mesh, bool drained)
Collect [2D_EDGE_CONVEYANCE]-shaped rows for serialization.
Definition Serialize2D.hpp:173
BoundaryType
Boundary condition types for 2D mesh edges.
Definition BoundaryData.hpp:56
@ RATING_CURVE
Stage → flow lookup (curve registry index)
Definition BoundaryData.hpp:61
@ SPECIFIED_FLOW
Prescribed discharge per metre of edge (constant or TS)
Definition BoundaryData.hpp:60
@ NORMAL_FLOW
Manning outflow using bed slope.
Definition BoundaryData.hpp:58
@ WALL
Zero-flux wall (default)
Definition BoundaryData.hpp:57
@ SPECIFIED_STAGE
Prescribed water surface elevation (constant or TS)
Definition BoundaryData.hpp:59
SoA storage for per-edge boundary conditions.
Definition BoundaryData.hpp:71
std::vector< std::string > edge_bc_flow_tseries_name
Timeseries name for deferred resolution (cleared after resolve).
Definition BoundaryData.hpp:112
std::vector< int8_t > edge_bc_type
Boundary condition type per edge (cast from BoundaryType)
Definition BoundaryData.hpp:74
std::vector< std::string > edge_bc_tseries_name
Timeseries name for deferred resolution (cleared after resolve).
Definition BoundaryData.hpp:91
std::vector< double > edge_bed_slope
Definition BoundaryData.hpp:79
std::vector< double > edge_bc_flow
Definition BoundaryData.hpp:104
std::vector< double > edge_bc_head
Definition BoundaryData.hpp:83
int size() const noexcept
Definition BoundaryData.hpp:148
std::vector< std::string > edge_bc_rating_curve_name
Curve name for deferred resolution (cleared after resolve).
Definition BoundaryData.hpp:123
SoA storage for 2D mixed triangle/quad mesh geometry and topology.
Definition MeshData.hpp:67
std::vector< double > edge_conveyance
Definition MeshData.hpp:133
int n_triangles() const noexcept
Definition MeshData.hpp:198
void cell_edge_vertices(int c, int k, int &a, int &b) const noexcept
Endpoint vertices of local edge k of cell c: v[(k+1)nv], v[(k+2)nv].
Definition MeshData.hpp:230
static constexpr int slot(int c, int k) noexcept
Flat edge/vertex slot of local index k in cell c.
Definition MeshData.hpp:219
int n_edge_slots() const noexcept
Number of internal edge slots (n_cells * kMaxCellVerts).
Definition MeshData.hpp:212
static constexpr int slot_cell(int s) noexcept
Definition MeshData.hpp:222
int cell_vertex_count(int c) const noexcept
Definition MeshData.hpp:224
static constexpr int slot_local(int s) noexcept
Local index k of a flat slot; cell of a flat slot.
Definition MeshData.hpp:221
Per-row buffer for [2D_BOUNDARY_CONDITIONS] parse output.
Definition PendingRows2D.hpp:53
double param1
slope (NormalFlow) / head (Stage) / flow (Flow)
Definition PendingRows2D.hpp:57
std::string name
TS name or curve name (TS_/Rating variants)
Definition PendingRows2D.hpp:58
int bc_type
openswmm::twoD::BoundaryType cast
Definition PendingRows2D.hpp:56
int tri
Definition PendingRows2D.hpp:54
int edge
0..2
Definition PendingRows2D.hpp:55
Per-row buffer for [2D_EDGE_CONVEYANCE] parse output (§11A).
Definition PendingRows2D.hpp:72