|
| OPENSWMM_KERNEL_FN double | sectionArea (const FvGeometry &g, double h) noexcept |
| |
| OPENSWMM_KERNEL_FN double | sectionWidth (const FvGeometry &g, double h) noexcept |
| |
| OPENSWMM_KERNEL_FN double | sectionHydRad (const FvGeometry &g, double h) noexcept |
| |
| OPENSWMM_KERNEL_FN double | slotRamp (double s) noexcept |
| |
| OPENSWMM_KERNEL_FN double | slotRampIntegral (double s) noexcept |
| |
| OPENSWMM_KERNEL_FN double | areaOfDepth (const FvGeometry &g, double h) noexcept |
| |
| OPENSWMM_KERNEL_FN double | widthOfDepth (const FvGeometry &g, double h) noexcept |
| | Top width dA/dh at depth h, INCLUDING the tapered slot.
|
| |
| OPENSWMM_KERNEL_FN double | hydRadOfDepth (const FvGeometry &g, double h) noexcept |
| | Hydraulic radius at depth h.
|
| |
| OPENSWMM_KERNEL_FN double | i1OfDepth (const FvGeometry &g, double h, double area_at_h) noexcept |
| | Hydrostatic first moment I₁(h) = ∫₀ʰ A(η)dη.
|
| |
| OPENSWMM_KERNEL_FN double | depthOfAreaBracketed (const FvGeometry &g, double a) noexcept |
| | Invert A → h — the EXACT inverse of areaOfDepth above.
|
| |
| OPENSWMM_KERNEL_FN double | depthOfArea (const FvGeometry &g, double a) noexcept |
| | Invert A → h. Same root as depthOfAreaBracketed, found far faster.
|
| |
| OPENSWMM_KERNEL_FN double | celerity (double a, double t) noexcept |
| |
| OPENSWMM_KERNEL_FN void | waveSpeeds (const FaceState &L, const FaceState &R, double &sl, double &sr) noexcept |
| |
| OPENSWMM_KERNEL_FN void | physicalFlux (const FaceState &S, double &fa, double &fq) noexcept |
| | Physical flux of one state.
|
| |
| OPENSWMM_KERNEL_FN FaceFlux | riemannFlux (const FaceState &L, const FaceState &R) noexcept |
| | Flux for the conservative St. Venant system, plus the contact speed.
|
| |
| OPENSWMM_KERNEL_FN double | speciesFlux (const FaceState &L, const FaceState &R, const FaceFlux &f, double phi_l, double phi_r, bool hllc) noexcept |
| | Species flux for the A(phi) component.
|
| |
| OPENSWMM_KERNEL_FN double | frictionUpdate (double q, double u, double r, double dt, double rough_factor) noexcept |
| | Semi-implicit Manning friction — unconditionally stable, so friction imposes no time-step restriction.
|
| |
| OPENSWMM_KERNEL_FN double | localLossUpdate (double q, double u, double k, double dx, double dt) noexcept |
| | Semi-implicit entrance/exit loss at a node-coupling face.
|
| |
| OPENSWMM_KERNEL_FN double | ufUpdate (double q, double a, double u_old, double k3, double grad_term, double dt) noexcept |
| | Unsteady-friction momentum update (issue #156).
|
| |
| OPENSWMM_KERNEL_FN double | tpaDepthOfArea (const FvGeometry &g, double a) noexcept |
| |
| OPENSWMM_KERNEL_FN double | tpaAreaOfDepth (const FvGeometry &g, double h) noexcept |
| |
| OPENSWMM_KERNEL_FN double | tpaI1OfDepth (const FvGeometry &g, double h) noexcept |
| |
| OPENSWMM_KERNEL_FN double | faceCflDt (double cfl, double dx, double u, double c) noexcept |
| | CFL-limited step for one face: α·Δx/(|u| + c).
|
| |
| OPENSWMM_KERNEL_FN double | positivityScale (double vol, double outflow, double dt) noexcept |
| | Positivity scale for a cell about to export more volume than it holds.
|
| |
Invert A → h. Same root as depthOfAreaBracketed, found far faster.
This is the solver's hottest kernel by a wide margin — profiling a Δx = 20 ft run put it and the closure evaluations it drives at 87 % of total time — so how it converges matters more than anywhere else in the scheme.
Why the obvious approach is slow. Illinois regula-falsi on the depth-uniform bracket does not converge superlinearly here: measured 16 closure evaluations per call on a circular pipe and 35 on a trapezoid, with the iteration count falling only linearly as the tolerance is relaxed — the signature of bisection. Seeding it better changes nothing, because the exit test is the BRACKET collapsing and Illinois replaces only one end per step.
Why not Newton. The width is dA/dh analytically, and Newton with it needs 3–5 evaluations. But for tabulated shapes W and A are INDEPENDENT legacy tabulations rather than an exact derivative pair (§7A.2), and the error that introduces is not small: measured round-trip error 4.7e-4 ft on a 3 ft circular pipe, five orders worse than the scheme needs and enough to break lake-at-rest.
Brent. Inverse quadratic interpolation with a secant fallback and a bisection safeguard — superlinear using function values ONLY, so the width inconsistency cannot mislead it. 5.9 / 3.1 / 6.3 evaluations on circular / rectangular / trapezoidal at full round-trip accuracy (≤ 2.7e-15 ft).
The bracket comes from the area-uniform inverse table widened by one panel each side and is then VERIFIED by evaluating both ends. The two evaluations that costs are why a rectangular pipe — which the old path nailed in 1.5 — now takes 3.1; that trade is worth it, and the guard falls back to the bracketed inverse if the table's bracket somehow fails to contain the root.
Invert A → h — the EXACT inverse of areaOfDepth above.
This must be a true inverse, not merely an accurate one. The solver carries A and derives the free surface as η = z_b + depthOfArea(A); if the composition depthOfArea∘areaOfDepth were not the identity, cells sitting at the same η but different bed elevations would reconstruct DIFFERENT surfaces, and lake-at-rest — the property the whole well-balanced construction exists to deliver — would fail on every partly-full pipe.
xsect::getYofA cannot be used for this. The legacy geometry tables are INDEPENDENT tabulations of the same shape — A_Circ gives area from depth, Y_Circ gives depth from area — and they round-trip only to table resolution (measured: 0.016 ft on a 3 ft circular pipe near the crown, ~0.5 % of the diameter). That is fine for the legacy solver, which never composes them; it is fatal here.
So the inverse is built from the forward closure itself: bracket on the A samples stored alongside the I₁ table (both were produced by areaOfDepth, so the bracket is exact), then Illinois-regula-falsi inside the panel. A is strictly increasing — a monotone section plus a strictly increasing slot term — so the bracket always holds and convergence is unconditional; within one panel A is nearly linear, so it typically takes four or five evaluations.
Above the crown A is exactly linear, so that branch is closed-form.
Flux for the conservative St. Venant system, plus the contact speed.
The hydrodynamic flux is HLL, and that is not a shortcut — it is what HLLC reduces to here. The system U = [A, Q] is 2x2 with two genuinely nonlinear fields and NO middle wave: the contact appears only once a third component is carried, U = [A, Q, A(phi)], whose eigenvalues are u-c, u, u+c. Applying the Euler-style HLLC star-state construction to the 2x2 subsystem is inconsistent — the resulting momentum flux violates the HLL consistency condition, and on a pressurized/part-full interface (a surcharged manhole feeding a half-full pipe — the case this solver exists for) it disagrees with HLL by more than an order of magnitude and drives the flow backwards.
So S* is computed here for its actual job: selecting the upwind side for the ADVECTED SCALAR (see speciesFlux). That is exactly the role plan §3.2 assigns it — "λ = v IS the contact discontinuity that
carries the species" — and it is why FV_RIEMANN changes the transport answer while leaving the hydraulics identical.
Species flux for the A(phi) component.
HLLC upwinds on the sign of the contact speed and multiplies by the SAME mass flux the water used. Flux consistency is a hard requirement, not a detail: computing this from a separately-evaluated velocity — the usual trap when transport is bolted onto a hydraulic solver — decouples solute mass from water mass and produces spurious extrema and non-conservation. Reusing the mass flux guarantees exact solute conservation, a discrete maximum principle, and that a uniform field stays uniform under any flow (plan §3.2).
HLL instead averages the whole fan into one intermediate state, smearing precisely the wave that carries the species. It still preserves a uniform field (the average is linear in phi when phi is constant), so it is a legitimate baseline — just a diffusive one. The §6.11(d) front-width comparison separates this layer's contribution from the reconstruction's.