OpenSWMM Engine  6.0.0-alpha.4
Data-oriented, plugin-extensible SWMM Engine (6.0.0-alpha.4)
Loading...
Searching...
No Matches
openswmm::fv::FvGeometry Struct Reference

Cross-section closure for one conduit's cell chain. More...

#include <NetworkMeshData.hpp>

Collaboration diagram for openswmm::fv::FvGeometry:

Public Attributes

XSectParams xs {}
 section parameters (owns transect table ptrs)
 
const xsect::XsectEvaleval = nullptr
 
double y_full = 0.0
 full depth (ft)
 
double a_full = 0.0
 area when full (ft²)
 
double w_max = 0.0
 width at widest point (ft)
 
double r_full = 0.0
 hydraulic radius when full (ft)
 
double barrel_scale = 1.0
 
double y_crown = 0.0
 
double t_slot = 0.0
 
double a_crown = 0.0
 
double i1_crown = 0.0
 I₁(y_full) — the table's last entry, cached for the same reason.
 
uint8_t is_open = 0
 open section: no crown, no slot taper
 
double roughness = 0.01
 Manning n.
 
double rough_factor = 0.0
 g·(n/PHI)² — friction denominator factor
 
double loss_inlet = 0.0
 entrance loss coefficient K
 
double loss_outlet = 0.0
 exit loss coefficient K
 
int barrels = 1
 parallel identical barrels
 
int culvert_code = 0
 
double slope = 0.0
 
hydkernels::CulvertCurve culvert_curve {}
 
uint8_t culvert_mitered = 0
 
double i1_tbl [2 *kI1Samples] = {}
 
double h_tbl [kI1Samples] = {}
 

Detailed Description

Cross-section closure for one conduit's cell chain.

One continuous geometry valid from dry bed to full pressurization: the Preissmann slot is folded into A(h)/T(h)/R(h) so every cell evaluates the same flux function and "transition" is just a depth crossing the crown (plan §3.3). t_slot is derived from FV_SLOT_CELERITY, and the slot mouth is tapered over [y_crown, y_full] so dA/dh stays Lipschitz through the crown — a discontinuous dA/dh would produce spurious reflections and corrupt the Riemann solver's wave-speed estimates.

Member Data Documentation

◆ a_crown

double openswmm::fv::FvGeometry::a_crown = 0.0

A(y_full) INCLUDING the slot area accumulated over the tapered mouth. Cached because every above-crown evaluation and the analytic I₁ extension start from it.

◆ a_full

double openswmm::fv::FvGeometry::a_full = 0.0

area when full (ft²)

◆ barrel_scale

double openswmm::fv::FvGeometry::barrel_scale = 1.0

barrels as a factor on AREA and TOP WIDTH (see barrels below). Kept beside the fields every area evaluation already loads.

◆ barrels

int openswmm::fv::FvGeometry::barrels = 1

parallel identical barrels

◆ culvert_code

int openswmm::fv::FvGeometry::culvert_code = 0

[XSECTIONS] culvert code (0 = not a culvert), and the conduit slope the HEC-5 inlet-control equations need. Cold: read only at the conduit's upstream boundary face, and only when the code is set.

◆ culvert_curve

hydkernels::CulvertCurve openswmm::fv::FvGeometry::culvert_curve {}

The type code's inlet-control curve, RESOLVED at mesh build. Keeping the resolved coefficients rather than the code is what lets the solver evaluate the closure with no engine dependency — the table lookup is host work, the curve is all the kernel needs.

◆ culvert_mitered

uint8_t openswmm::fv::FvGeometry::culvert_mitered = 0

◆ eval

const xsect::XsectEval* openswmm::fv::FvGeometry::eval = nullptr

Where the section's own geometry is evaluated. A pointer, not a copy: the evaluator carries the shared geometry tables, and which memory space those live in is exactly what differs between the host solver and the device backend. The mesh builder binds this to xsect::hostEval(); a device backend rebinds it to its own device-resident pair, and the same kernel bodies then run unchanged on both (plan §5.1).

◆ h_tbl

double openswmm::fv::FvGeometry::h_tbl[kI1Samples] = {}

The INVERSE of the area column: depth sampled uniformly in AREA over [0, a_crown], h_tbl[j] being the exact root of A(h) = j·a_crown/(n−1).

The forward table is uniform in depth, which is the wrong grid to invert on. Bracketing a query area in it costs a binary search — seven dependent loads with unpredictable branches — and near the crown, where A is nearly flat in h, one depth panel spans a wide range of areas, so the bracket it yields is loose and the root-find needs several evaluations of the closure. Profiling put depthOfArea and the area lookups it drives at 87 % of solver time on a Δx = 20 ft run.

Sampling uniformly in area instead makes the panel a single divide, and makes the residuals at its two ends known WITHOUT evaluating the closure — they are the sample areas themselves. Built at init from the bracketed inverse, so it costs nothing at run time.

◆ i1_crown

double openswmm::fv::FvGeometry::i1_crown = 0.0

I₁(y_full) — the table's last entry, cached for the same reason.

◆ i1_tbl

double openswmm::fv::FvGeometry::i1_tbl[2 *kI1Samples] = {}

First moment I₁(h) = ∫₀ʰ A(η)dη sampled uniformly on h ∈ [0, y_full], followed by the companion A(h) samples on the same grid — 2·kI1Samples entries, [0, kI1Samples) = I₁ and [kI1Samples, 2·kI1Samples) = A. One buffer because both are read together on every evaluation.

Built once at init by composite integration of the same A(h) the solver evaluates. Quadrature error does not threaten well-balancedness — that needs only a single-valued I₁(h) — but it does set the accuracy of the pressure term, hence the fine sub-sampling in buildI1Table.

A fixed inline array rather than a vector: the whole struct is copied into device memory by the accelerated backend, and an owning container cannot cross that boundary. At 129 samples this is 2 kB per DISTINCT cross-section — a few hundred at most in a real model.

◆ is_open

uint8_t openswmm::fv::FvGeometry::is_open = 0

open section: no crown, no slot taper

◆ loss_inlet

double openswmm::fv::FvGeometry::loss_inlet = 0.0

entrance loss coefficient K

◆ loss_outlet

double openswmm::fv::FvGeometry::loss_outlet = 0.0

exit loss coefficient K

◆ r_full

double openswmm::fv::FvGeometry::r_full = 0.0

hydraulic radius when full (ft)

◆ rough_factor

double openswmm::fv::FvGeometry::rough_factor = 0.0

g·(n/PHI)² — friction denominator factor

◆ roughness

double openswmm::fv::FvGeometry::roughness = 0.01

Manning n.

◆ slope

double openswmm::fv::FvGeometry::slope = 0.0

◆ t_slot

double openswmm::fv::FvGeometry::t_slot = 0.0

Top width of the slot above the crown, g·A_full/c_slot². Open shapes carry w_max here so the vertical-wall extension is one code path.

◆ w_max

double openswmm::fv::FvGeometry::w_max = 0.0

width at widest point (ft)

◆ xs

XSectParams openswmm::fv::FvGeometry::xs {}

section parameters (owns transect table ptrs)

◆ y_crown

double openswmm::fv::FvGeometry::y_crown = 0.0

Depth at which the slot begins to open. Closed shapes: SLOT_CROWN_CUTOFF · y_full (Sjöberg-style, engages just below the crown). Open shapes: y_full, with no taper — the section simply continues with vertical walls.

◆ y_full

double openswmm::fv::FvGeometry::y_full = 0.0

full depth (ft)


The documentation for this struct was generated from the following file: