53#ifndef OPENSWMM_ENGINE_2D_INERTIAL_KERNELS_HPP
54#define OPENSWMM_ENGINE_2D_INERTIAL_KERNELS_HPP
71#ifndef OPENSWMM_KERNEL_FN
72#define OPENSWMM_KERNEL_FN inline
98 double reference_step)
noexcept {
99 if (!(reference_step > 0.0))
101 if (!(dt > 0.0) || theta == 1.0)
103 return -std::expm1(std::log(theta) * (dt / reference_step));
124 return std::sqrt(x * x +
y *
y);
149 bool vfr,
double vfr_min_wet_frac,
double V,
double& eta,
150 double& depth)
noexcept {
151 const double v = (V > 0.0) ? V : 0.0;
152 depth = (area > 1.0e-30) ? v / area : 0.0;
180 double z3,
bool vfr,
double vfr_min_wet_frac,
181 double eta)
noexcept {
186 const double d = eta - cz;
187 return (d > 0.0) ? area * d : 0.0;
213 double A2,
bool vfr,
double vfr_min_wet_frac,
double V,
214 double& eta,
double& depth)
noexcept {
215 const double v = (V > 0.0) ? V : 0.0;
216 depth = (area > 1.0e-30) ? v / area : 0.0;
243 double A1,
double A2,
bool vfr,
244 double vfr_min_wet_frac,
double eta)
noexcept {
247 const double d = eta - cz;
248 return (d > 0.0) ? area * d : 0.0;
251#if defined(__GNUC__) || defined(__clang__)
252#define OPENSWMM_2D_NOINLINE __attribute__((noinline))
253#elif defined(_MSC_VER)
254#define OPENSWMM_2D_NOINLINE __declspec(noinline)
256#define OPENSWMM_2D_NOINLINE
277 int i,
double V,
double& eta,
278 double& depth)
noexcept {
280 m.tri_area[i], m.tri_cz[i], &m.quad_vfr_z[
static_cast<std::size_t
>(i) *
kQuadVfrZ],
281 m.quad_vfr_a[
static_cast<std::size_t
>(i) * 2],
282 m.quad_vfr_a[
static_cast<std::size_t
>(i) * 2 + 1],
true, o.vfr_min_wet_frac, V, eta, depth);
302 double& depth)
noexcept {
308 etaDepthScalar(m.tri_area[i], m.tri_cz[i], 0.0, 0.0, 0.0,
false, o.vfr_min_wet_frac, V, eta,
312 if (m.cell_nv[
static_cast<std::size_t
>(i)] == 4) {
316 etaDepthScalar(m.tri_area[i], m.tri_cz[i], m.vz[m.cell_vertex(i, 0)], m.vz[m.cell_vertex(i, 1)],
317 m.vz[m.cell_vertex(i, 2)],
true, o.vfr_min_wet_frac, V, eta, depth);
335 double volume)
noexcept {
339 return m.tri_area[i];
340 double eta = 0, depth = 0;
343 if (m.cell_nv[std::size_t(i)] == 4)
345 m.quad_vfr_a[std::size_t(i) * 2],
346 m.quad_vfr_a[std::size_t(i) * 2 + 1], eta);
348 double a = m.vz[m.cell_vertex(i, 0)], b = m.vz[m.cell_vertex(i, 1)],
349 c = m.vz[m.cell_vertex(i, 2)];
353 return m.tri_area[i] * std::clamp(fraction, 0., 1.);
372 double eta)
noexcept {
373 if (m.cell_nv[
static_cast<std::size_t
>(i)] == 4) {
375 m.tri_area[i], m.tri_cz[i], &m.quad_vfr_z[
static_cast<std::size_t
>(i) *
kQuadVfrZ],
376 m.quad_vfr_a[
static_cast<std::size_t
>(i) * 2],
377 m.quad_vfr_a[
static_cast<std::size_t
>(i) * 2 + 1], o.cell_closure ==
CellClosure2D::VFR,
378 o.vfr_min_wet_frac, eta);
381 m.vz[m.cell_vertex(i, 1)], m.vz[m.cell_vertex(i, 2)],
400 return std::max(etaL, etaR) - zface;
424 const double dz = z_hi - z_lo;
428 const double t = eta - z_lo;
429 return t * t / (2.0 * dz);
431 return eta - 0.5 * (z_lo + z_hi);
451 double z_hi)
noexcept {
486 double slope,
double n2,
double q_mag,
487 double adv = 0.0) noexcept {
488 const double h73 = hf * hf * std::cbrt(hf);
489 const double num = qhat - dt * (
kGravity * hf * slope + adv);
490 const double den = 1.0 +
kGravity * dt * n2 * q_mag / h73;
520 double hR,
double inv_dx_normal)
noexcept {
521 const double FL = unL * ((unL > 0.0) ? hL * unL : q_f);
522 const double FR = unR * ((unR > 0.0) ? q_f : hR * unR);
523 return (FR - FL) * inv_dx_normal;
540 const double qcap = fr_max * hf * std::sqrt(
kGravity * hf);
541 return std::clamp(q, -qcap, qcap);
559 const double c = std::sqrt(
kGravity * h) + speed;
560 return (c > 1.0e-12) ? alpha * lchar / c : 1.0e30;
578 double beta)
noexcept {
579 if (outflow_m3s <= 0.0 || dt <= 0.0)
581 const double avail = beta * std::max(V, 0.0);
582 const double take = outflow_m3s * dt;
583 return (take <= avail) ? 1.0 : avail / take;
#define OPENSWMM_KERNEL_FN
Definition ExplicitKokkosSurfaceSolver.cpp:22
#define OPENSWMM_2D_NOINLINE
Definition InertialKernels.hpp:256
Structure-of-Arrays (SoA) storage for 2D triangular mesh geometry.
Volume–free-surface relationship (VFR) for a quadrilateral cell.
Configuration options for the 2D surface routing solver.
Volume–free-surface (VFR) closure for a planar-bed triangular cell.
Definition InertialKernels.hpp:75
OPENSWMM_KERNEL_FN double momentumBlendFraction(double theta, double dt, double reference_step) noexcept
Fraction of reconstructed momentum mixed over one physical face step.
Definition InertialKernels.hpp:97
void cellEtaDepth(const MeshData &m, const SolverOptions2D &o, int i, double V, double &eta, double &depth) noexcept
Volume → (η, depth) closure — the SAME semantics as the CVODE/ARKODE reconstructFromVolume: depth = m...
Definition InertialKernels.hpp:301
OPENSWMM_KERNEL_FN double froudeCap(double q, double hf, double fr_max) noexcept
Froude-number clamp: |q| ≤ Fr_max · h_f · √(g·h_f). The steep-face guard — the local-inertial scheme ...
Definition InertialKernels.hpp:539
OPENSWMM_KERNEL_FN double qMagnitude(double x, double y) noexcept
|(x, y)| for the marcher's discharge vectors.
Definition InertialKernels.hpp:123
double cellVolumeFromEta(const MeshData &m, const SolverOptions2D &o, int i, double eta) noexcept
Exact inverse of the closure: cell volume holding free surface η — FLAT A·max(0, η − z_c); VFR the re...
Definition InertialKernels.hpp:371
OPENSWMM_KERNEL_FN double inertialAdvection(double q_f, double unL, double hL, double unR, double hR, double inv_dx_normal) noexcept
Convective momentum flux difference ∂(u·q)/∂n at an interior face — [2D_OPTIONS] ADVECTION,...
Definition InertialKernels.hpp:519
OPENSWMM_KERNEL_FN double cellCflDt(double alpha, double lchar, double h, double speed) noexcept
Per-cell CFL stable step: dt = α·L_char/(√(g·h) + |u|), with |u| = |q⃗|/h the cell speed from the Per...
Definition InertialKernels.hpp:558
constexpr double kEtaDeadband
Definition InertialKernels.hpp:85
OPENSWMM_KERNEL_FN double volumeFromEtaScalar(double area, double cz, double z1, double z2, double z3, bool vfr, double vfr_min_wet_frac, double eta) noexcept
Scalar core of the η → V inverse (device-callable).
Definition InertialKernels.hpp:179
double cellWetArea(const MeshData &m, const SolverOptions2D &o, int i, double volume) noexcept
Physical planimetric water contact, distinct from the cell-mean depth V/A returned above....
Definition InertialKernels.hpp:334
OPENSWMM_2D_NOINLINE void cellEtaDepthQuad(const MeshData &m, const SolverOptions2D &o, int i, double V, double &eta, double &depth) noexcept
Quad (B&S 2007 two-plane) VFR closure, kept OUT OF LINE on purpose: its safeguarded Newton (QuadVfr....
Definition InertialKernels.hpp:276
OPENSWMM_KERNEL_FN void etaDepthScalar(double area, double cz, double z1, double z2, double z3, bool vfr, double vfr_min_wet_frac, double V, double &eta, double &depth) noexcept
Scalar core of the V → (η, depth) closure (device-callable; the MeshData wrapper below loads the geom...
Definition InertialKernels.hpp:148
OPENSWMM_KERNEL_FN double positivityScale(double V, double outflow_m3s, double dt, double beta) noexcept
Positivity scale factor λ for a cell about to export volume: outgoing fluxes (+ explicit sinks) may t...
Definition InertialKernels.hpp:577
OPENSWMM_KERNEL_FN double faceFlowDepth(double etaL, double etaR, double zface) noexcept
Flow depth at a face: the water surface above the higher of the two interface beds....
Definition InertialKernels.hpp:399
OPENSWMM_KERNEL_FN double volumeFromEtaQuadScalar(double area, double cz, const double *zs, double A1, double A2, bool vfr, double vfr_min_wet_frac, double eta) noexcept
Quad η → V inverse (device-callable).
Definition InertialKernels.hpp:242
OPENSWMM_KERNEL_FN double inertialFaceUpdate(double q, double qhat, double hf, double dt, double slope, double n2, double q_mag, double adv=0.0) noexcept
One local-inertial face update over Δt. q is the current face discharge, qhat the θ-averaged discharg...
Definition InertialKernels.hpp:485
OPENSWMM_KERNEL_FN void etaDepthQuadScalar(double area, double cz, const double *zs, double A1, double A2, bool vfr, double vfr_min_wet_frac, double V, double &eta, double &depth) noexcept
Quad (B&S 2007 two-plane) V → (η, depth) closure core. zs / A1 / A2 are the precomputed quad VFR data...
Definition InertialKernels.hpp:212
constexpr double kGravity
matches the existing kernels
Definition InertialKernels.hpp:77
OPENSWMM_KERNEL_FN double faceDepthFromEta(double eta, double z_lo, double z_hi) noexcept
Wetted-edge flow depth from a free surface η over an edge with endpoint beds z_lo ≤ z_hi — Begnudelli...
Definition InertialKernels.hpp:421
OPENSWMM_KERNEL_FN double faceFlowDepthVfr(double etaL, double etaR, double z_lo, double z_hi) noexcept
Flow depth at an interior face under FACE_RECONSTRUCTION = VFR_FACE: the B&S Eq. 14 wetted-edge depth...
Definition InertialKernels.hpp:450
OPENSWMM_KERNEL_FN double vfrMeanDepthFromEta(double z1, double z2, double z3, double eta, double eps) noexcept
Regularized cell-mean depth h̄(η): exact for η ≥ η_s (wet fraction ≥ eps), tangent-line continuation ...
Definition VfrClosure.hpp:214
OPENSWMM_KERNEL_FN void vfrSort3(double &z1, double &z2, double &z3) noexcept
Sort three vertex elevations in place so z1 <= z2 <= z3.
Definition VfrClosure.hpp:85
constexpr int kQuadVfrZ
Definition QuadVfr.hpp:73
OPENSWMM_KERNEL_FN double quadEtaFromMeanDepth(const double *zs, double A1, double A2, double mean_depth, double eps) noexcept
Regularised free-surface elevation η(h̄) of the quad — the solver closure. Monotone inverse of quadMe...
Definition QuadVfr.hpp:177
OPENSWMM_KERNEL_FN double vfrWetFraction(double z1, double z2, double z3, double eta) noexcept
Wetted-area fraction A_wet/A of the planar-bed cell at stage eta. Piecewise C0, monotone from 0 (η ≤ ...
Definition VfrClosure.hpp:117
OPENSWMM_KERNEL_FN double quadMeanDepthFromEta(const double *zs, double A1, double A2, double eta, double eps) noexcept
Regularised cell-mean depth h̄(η) of the quad — the area-weighted sum of the two sub-triangle closure...
Definition QuadVfr.hpp:110
OPENSWMM_KERNEL_FN double quadWetFraction(const double *zs, double A1, double A2, double eta) noexcept
Wetted-area fraction of the quad at stage η (dh̄/dη away from the ε-tail). zs: six sorted elevations ...
Definition QuadVfr.hpp:88
OPENSWMM_KERNEL_FN double vfrEtaFromMeanDepth(double z1, double z2, double z3, double mean_depth, double eps) noexcept
Regularized free-surface elevation η(h̄) — the solver closure.
Definition VfrClosure.hpp:249
@ VFR
Planar-bed VFR closure (regularized), CPU solvers only.
Definition SolverOptions2D.hpp:62
double * y
Definition odesolve.c:37
SoA storage for 2D mixed triangle/quad mesh geometry and topology.
Definition MeshData.hpp:65
Definition SolverOptions2D.hpp:257