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
90 double& ft)
noexcept {
92 fn = s.h * s.un * s.un + 0.5 *
kGravity * s.h * s.h;
93 ft = s.h * s.un * s.ut;
99 double& sl,
double& sr)
noexcept {
100 const double cl = std::sqrt(
kGravity * L.h);
101 const double cr = std::sqrt(
kGravity * R.h);
102 if (L.h > 0.0 && R.h > 0.0) {
103 const double ustar = 0.5 * (L.un + R.un) + cl - cr;
104 const double cstar = 0.5 * (cl + cr) + 0.25 * (L.un - R.un);
105 sl = std::min(L.un - cl, ustar - cstar);
106 sr = std::max(R.un + cr, ustar + cstar);
107 }
else if (L.h > 0.0) {
109 sr = L.un + 2.0 * cl;
110 }
else if (R.h > 0.0) {
111 sl = R.un - 2.0 * cr;
128 double& fh,
double& fn,
double& ft,
129 double& sstar)
noexcept {
130 if (L.h <= 0.0 && R.h <= 0.0) {
131 fh = fn = ft = 0.0; sstar = 0.0;
136 double fhl, fnl, ftl, fhr, fnr, ftr;
142 const double dl = L.h * (L.un - sl), dr = R.h * (R.un - sr);
143 const double den = dr - dl;
144 sstar = (std::fabs(den) > 1.0e-14) ? (sl * dr - sr * dl) / den
145 : 0.5 * (L.un + R.un);
148 fh = fhl; fn = fnl; ft = ftl;
149 }
else if (sr <= 0.0) {
150 fh = fhr; fn = fnr; ft = ftr;
153 const double inv = 1.0 / (sr - sl);
154 fh = (sr * fhl - sl * fhr + sl * sr * (R.h - L.h)) * inv;
155 fn = (sr * fnl - sl * fnr + sl * sr * (R.h * R.un - L.h * L.un)) * inv;
157 ft = fh * ((sstar >= 0.0) ? L.ut : R.ut);
177 double etaR,
double hR,
double qxR,
double qyR,
178 double nx,
double ny,
double h_dry,
180 double& corrL_x,
double& corrL_y,
181 double& corrR_x,
double& corrR_y)
noexcept {
185 const double zL = etaL - hL, zR = etaR - hR;
186 const double zf = (zL > zR) ? zL : zR;
188 L.
h = (etaL - zf > 0.0) ? etaL - zf : 0.0;
189 R.h = (etaR - zf > 0.0) ? etaR - zf : 0.0;
193 const double tx = -ny, ty = nx;
194 if (hL > h_dry && L.
h > 0.0) {
195 const double ux = qxL / hL, uy = qyL / hL;
196 L.
un = ux * nx + uy * ny;
197 L.
ut = ux * tx + uy * ty;
199 if (hR > h_dry && R.h > 0.0) {
200 const double ux = qxR / hR, uy = qyR / hR;
201 R.un = ux * nx + uy * ny;
202 R.ut = ux * tx + uy * ty;
204 corrL_x = corrL_y = corrR_x = corrR_y = 0.0;
205 if (L.
h <= 0.0 && R.h <= 0.0) {
209 double fh, fn, ft, sstar;
212 out.mx = fn * nx + ft * tx;
213 out.my = fn * ny + ft * ty;
216 const double cL = 0.5 *
kGravity * (L.
h * L.
h - hL * hL);
217 const double cR = 0.5 *
kGravity * (R.h * R.h - hR * hR);
218 corrL_x = cL * nx; corrL_y = cL * ny;
219 corrR_x = -cR * nx; corrR_y = -cR * ny;
236 double zL,
double hL_cell,
237 double etaRf,
double uxRf,
double uyRf,
238 double zR,
double hR_cell,
239 double nx,
double ny,
double h_dry,
241 double& corrL_x,
double& corrL_y,
242 double& corrR_x,
double& corrR_y)
noexcept {
243 const double zf = (zL > zR) ? zL : zR;
245 L.
h = (etaLf - zf > 0.0) ? etaLf - zf : 0.0;
246 R.h = (etaRf - zf > 0.0) ? etaRf - zf : 0.0;
247 const double tx = -ny, ty = nx;
248 if (hL_cell > h_dry && L.
h > 0.0) {
249 L.
un = uxLf * nx + uyLf * ny;
250 L.
ut = uxLf * tx + uyLf * ty;
252 if (hR_cell > h_dry && R.h > 0.0) {
253 R.un = uxRf * nx + uyRf * ny;
254 R.ut = uxRf * tx + uyRf * ty;
256 corrL_x = corrL_y = corrR_x = corrR_y = 0.0;
257 if (L.
h <= 0.0 && R.h <= 0.0) { out =
FaceFlux{};
return false; }
258 double fh, fn, ft, sstar;
261 out.mx = fn * nx + ft * tx;
262 out.my = fn * ny + ft * ty;
269 const double hLf = (etaLf - zL > 0.0) ? etaLf - zL : 0.0;
270 const double hRf = (etaRf - zR > 0.0) ? etaRf - zR : 0.0;
271 const double cL = 0.5 *
kGravity * (L.
h * L.
h - hLf * hLf);
272 const double cR = 0.5 *
kGravity * (R.h * R.h - hRf * hRf);
273 corrL_x = cL * nx; corrL_y = cL * ny;
274 corrR_x = -cR * nx; corrR_y = -cR * ny;
282 const double d = wf - w;
283 if (d > 1.0e-14)
return std::min(1.0, (wmax - w) / d);
284 else if (d < -1.0e-14)
return std::min(1.0, (wmin - w) / d);
291 double dt)
noexcept {
292 if (!(h > 0.0)) { qx = qy = 0.0;
return; }
293 const double qm = std::sqrt(qx * qx + qy * qy);
294 if (qm == 0.0)
return;
295 const double h73 = h * h * std::cbrt(h);
296 const double den = 1.0 +
kGravity * dt * n * n * qm / h73;
323 double h_interior)
noexcept {
324 const double rg = std::sqrt(
kGravity);
325 double s = std::sqrt(h_interior > 0.0 ? h_interior : 1.0e-6);
326 for (
int it = 0; it < 40; ++it) {
327 const double f = 2.0 * rg * s * s * s - r * s * s + q;
328 const double df = 6.0 * rg * s * s - 2.0 * r * s;
329 if (!(std::fabs(df) > 1.0e-12))
break;
330 const double s1 = s - f / df;
331 if (!(s1 > 0.0) || !std::isfinite(s1))
break;
332 const double step = std::fabs(s1 - s);
334 if (step < 1.0e-12 * (1.0 + s)) {
335 const double h = s * s;
336 return (h > 0.0 && std::isfinite(h)) ? h : h_interior;
339 const double h = s * s;
342 return (h > 0.0 && std::isfinite(h) &&
343 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:18
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:127
OPENSWMM_KERNEL_FN void frictionUpdate(double &qx, double &qy, double h, double n, double dt) noexcept
Definition SweKernels.hpp:290
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
Face flux from RECONSTRUCTED side states (RECONSTRUCTION_ORDER 2).
Definition SweKernels.hpp:235
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:89
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:176
constexpr double kGravity
Definition SweKernels.hpp:67
OPENSWMM_KERNEL_FN double criticalDepth(double q) noexcept
Definition SweKernels.hpp:303
OPENSWMM_KERNEL_FN void waveSpeeds(const FaceSide &L, const FaceSide &R, double &sl, double &sr) noexcept
Definition SweKernels.hpp:98
OPENSWMM_KERNEL_FN double depthFromInvariantAndDischarge(double r, double q, double h_interior) noexcept
Ghost depth of a SUBCRITICAL prescribed-discharge boundary.
Definition SweKernels.hpp:322
OPENSWMM_KERNEL_FN double bjLimiter(double w, double wf, double wmin, double wmax) noexcept
Definition SweKernels.hpp:281
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