55#ifndef OPENSWMM_ENGINE_2D_SWE_KERNELS_HPP
56#define OPENSWMM_ENGINE_2D_SWE_KERNELS_HPP
61#ifndef OPENSWMM_KERNEL_FN
62#define OPENSWMM_KERNEL_FN inline
100 double& ft)
noexcept {
102 fn = s.h * s.un * s.un + 0.5 *
kGravity * s.h * s.h;
103 ft = s.h * s.un * s.ut;
120 double& sr)
noexcept {
121 const double cl = std::sqrt(
kGravity * L.h);
122 const double cr = std::sqrt(
kGravity * R.h);
123 if (L.h > 0.0 && R.h > 0.0) {
124 const double ustar = 0.5 * (L.un + R.un) + cl - cr;
125 const double cstar = 0.5 * (cl + cr) + 0.25 * (L.un - R.un);
126 sl = std::min(L.un - cl, ustar - cstar);
127 sr = std::max(R.un + cr, ustar + cstar);
128 }
else if (L.h > 0.0) {
130 sr = L.un + 2.0 * cl;
131 }
else if (R.h > 0.0) {
132 sl = R.un - 2.0 * cr;
155 double& ft,
double& sstar)
noexcept {
156 if (L.h <= 0.0 && R.h <= 0.0) {
163 double fhl, fnl, ftl, fhr, fnr, ftr;
166 const double dl = L.h * (L.un - sl), dr = R.h * (R.un - sr);
167 const double den = dr - dl;
168 sstar = (std::fabs(den) > 1.0e-14) ? (sl * dr - sr * dl) / den : 0.5 * (L.un + R.un);
175 }
else if (sr <= 0.0) {
184 const double inv = 1.0 / (sr - sl);
185 fh = (sr * fhl - sl * fhr + sl * sr * (R.h - L.h)) * inv;
186 fn = (sr * fnl - sl * fnr + sl * sr * (R.h * R.un - L.h * L.un)) * inv;
188 ft = fh * ((sstar >= 0.0) ? L.ut : R.ut);
222 double hR,
double qxR,
double qyR,
double nx,
double ny,
223 double h_dry,
FaceFlux& out,
double& corrL_x,
double& corrL_y,
224 double& corrR_x,
double& corrR_y)
noexcept {
228 const double zL = etaL - hL, zR = etaR - hR;
229 const double zf = (zL > zR) ? zL : zR;
231 L.
h = (etaL - zf > 0.0) ? etaL - zf : 0.0;
232 R.h = (etaR - zf > 0.0) ? etaR - zf : 0.0;
236 const double tx = -ny, ty = nx;
237 if (hL > h_dry && L.
h > 0.0) {
238 const double ux = qxL / hL, uy = qyL / hL;
239 L.
un = ux * nx + uy * ny;
240 L.
ut = ux * tx + uy * ty;
242 if (hR > h_dry && R.h > 0.0) {
243 const double ux = qxR / hR, uy = qyR / hR;
244 R.un = ux * nx + uy * ny;
245 R.ut = ux * tx + uy * ty;
250 const double cL = 0.5 *
kGravity * (L.
h * L.
h - hL * hL);
251 const double cR = 0.5 *
kGravity * (R.h * R.h - hR * hR);
256 if (L.
h <= 0.0 && R.h <= 0.0) {
258 return cL != 0.0 || cR != 0.0;
260 double fh, fn, ft, sstar;
263 out.mx = fn * nx + ft * tx;
264 out.my = fn * ny + ft * ty;
307 double hL_cell,
double etaRf,
double uxRf,
double uyRf,
308 double zR,
double hR_cell,
double nx,
double ny,
309 double h_dry,
FaceFlux& out,
double& corrL_x,
310 double& corrL_y,
double& corrR_x,
double& corrR_y,
311 double zLf,
double zRf)
noexcept {
312 const double zf = (zLf > zRf) ? zLf : zRf;
314 L.
h = (etaLf - zf > 0.0) ? etaLf - zf : 0.0;
315 R.h = (etaRf - zf > 0.0) ? etaRf - zf : 0.0;
316 const double tx = -ny, ty = nx;
317 if (hL_cell > h_dry && L.
h > 0.0) {
318 L.
un = uxLf * nx + uyLf * ny;
319 L.
ut = uxLf * tx + uyLf * ty;
321 if (hR_cell > h_dry && R.h > 0.0) {
322 R.un = uxRf * nx + uyRf * ny;
323 R.ut = uxRf * tx + uyRf * ty;
325 const double hLf = std::max(0.0, etaLf - zLf);
326 const double hRf = std::max(0.0, etaRf - zRf);
328 const double cL = 0.5 *
kGravity * (L.
h * L.
h - hLf * hLf - (hL_cell + hLf) * (zLf - zL));
329 const double cR = 0.5 *
kGravity * (R.h * R.h - hRf * hRf - (hR_cell + hRf) * (zRf - zR));
334 if (L.
h <= 0.0 && R.h <= 0.0) {
336 return cL != 0.0 || cR != 0.0;
338 double fh, fn, ft, sstar;
341 out.mx = fn * nx + ft * tx;
342 out.my = fn * ny + ft * ty;
376 double hL_cell,
double etaRf,
double uxRf,
double uyRf,
377 double zR,
double hR_cell,
double nx,
double ny,
double h_dry,
378 FaceFlux& out,
double& corrL_x,
double& corrL_y,
379 double& corrR_x,
double& corrR_y)
noexcept {
380 return faceFluxReconBed(etaLf, uxLf, uyLf, zL, hL_cell, etaRf, uxRf, uyRf, zR, hR_cell, nx, ny,
381 h_dry, out, corrL_x, corrL_y, corrR_x, corrR_y, zL, zR);
398 const double d = wf - w;
400 return std::min(1.0, (wmax - w) / d);
401 else if (d < -1.0e-14)
402 return std::min(1.0, (wmin - w) / d);
419 double dt)
noexcept {
424 const double qm = std::sqrt(qx * qx + qy * qy);
427 const double h73 = h * h * std::cbrt(h);
428 const double den = 1.0 +
kGravity * dt * n * n * qm / h73;
473 double h_interior)
noexcept {
474 const double rg = std::sqrt(
kGravity);
475 double s = std::sqrt(h_interior > 0.0 ? h_interior : 1.0e-6);
476 for (
int it = 0; it < 40; ++it) {
477 const double f = 2.0 * rg * s * s * s - r * s * s + q;
478 const double df = 6.0 * rg * s * s - 2.0 * r * s;
479 if (!(std::fabs(df) > 1.0e-12))
481 const double s1 = s - f / df;
482 if (!(s1 > 0.0) || !std::isfinite(s1))
484 const double step = std::fabs(s1 - s);
486 if (step < 1.0e-12 * (1.0 + s)) {
487 const double h = s * s;
488 return (h > 0.0 && std::isfinite(h)) ? h : h_interior;
491 const double h = s * s;
494 return (h > 0.0 && std::isfinite(h) &&
495 std::fabs(2.0 * rg * s * s * s - r * s * s + q) < 1.0e-6 * (1.0 + std::fabs(q)))
#define OPENSWMM_KERNEL_FN
Definition ExplicitKokkosSurfaceSolver.cpp:22
Definition SweKernels.hpp:65
OPENSWMM_KERNEL_FN void hllcFlux(const FaceSide &L, const FaceSide &R, double &fh, double &fn, double &ft, double &sstar) noexcept
HLLC flux in the face-normal frame.
Definition SweKernels.hpp:154
OPENSWMM_KERNEL_FN bool faceFluxReconBed(double etaLf, double uxLf, double uyLf, double zL, double hL_cell, double etaRf, double uxRf, double uyRf, double zR, double hR_cell, double nx, double ny, double h_dry, FaceFlux &out, double &corrL_x, double &corrL_y, double &corrR_x, double &corrR_y, double zLf, double zRf) noexcept
Second-order face flux with independently reconstructed depth/bed.
Definition SweKernels.hpp:306
OPENSWMM_KERNEL_FN void frictionUpdate(double &qx, double &qy, double h, double n, double dt) noexcept
Semi-implicit Manning friction on a cell's unit discharge over Δt: q⃗ ← q⃗ / (1 + g·Δt·n²·|q⃗| / h^{7...
Definition SweKernels.hpp:418
OPENSWMM_KERNEL_FN bool faceFluxRecon(double etaLf, double uxLf, double uyLf, double zL, double hL_cell, double etaRf, double uxRf, double uyRf, double zR, double hR_cell, double nx, double ny, double h_dry, FaceFlux &out, double &corrL_x, double &corrL_y, double &corrR_x, double &corrR_y) noexcept
Piecewise-constant-bed compatibility entry point.
Definition SweKernels.hpp:375
OPENSWMM_KERNEL_FN void physicalFlux(const FaceSide &s, double &fh, double &fn, double &ft) noexcept
Physical flux of the SWE in the normal frame: [h·un, h·un² + ½g h², h·un·ut].
Definition SweKernels.hpp:99
OPENSWMM_KERNEL_FN bool faceFlux(double etaL, double hL, double qxL, double qyL, double etaR, double hR, double qxR, double qyR, double nx, double ny, double h_dry, FaceFlux &out, double &corrL_x, double &corrL_y, double &corrR_x, double &corrR_y) noexcept
Full face evaluation: hydrostatic reconstruction, rotation, HLLC, rotation back, and the per-side bed...
Definition SweKernels.hpp:221
constexpr double kGravity
Definition SweKernels.hpp:67
OPENSWMM_KERNEL_FN double criticalDepth(double q) noexcept
Critical depth for a per-metre discharge q: (q²/g)^{1/3} — the ghost depth of a prescribed-flow bound...
Definition SweKernels.hpp:442
OPENSWMM_KERNEL_FN void waveSpeeds(const FaceSide &L, const FaceSide &R, double &sl, double &sr) noexcept
Wave-speed estimates S_L ≤ S_R (Toro 2001 §10.4): two-rarefaction estimate for wet–wet faces,...
Definition SweKernels.hpp:119
OPENSWMM_KERNEL_FN double depthFromInvariantAndDischarge(double r, double q, double h_interior) noexcept
Ghost depth of a SUBCRITICAL prescribed-discharge boundary.
Definition SweKernels.hpp:472
OPENSWMM_KERNEL_FN double bjLimiter(double w, double wf, double wmin, double wmax) noexcept
Barth–Jespersen limiter factor φ ∈ [0, 1] for one cell/variable given the cell value w,...
Definition SweKernels.hpp:397
Definition SweKernels.hpp:81
double my
Definition SweKernels.hpp:84
double mass
Definition SweKernels.hpp:82
double sstar
Definition SweKernels.hpp:85
double mx
Definition SweKernels.hpp:83
Definition SweKernels.hpp:72
double h
Definition SweKernels.hpp:73
double ut
Definition SweKernels.hpp:75
double un
Definition SweKernels.hpp:74