62#ifndef OPENSWMM_ENGINE_2D_QUAD_VFR_HPP
63#define OPENSWMM_ENGINE_2D_QUAD_VFR_HPP
78 double eta)
noexcept {
81 return (A1 * w1 + A2 * w2) / (A1 + A2);
87 double eta,
double eps)
noexcept {
90 return (A1 * d1 + A2 * d2) / (A1 + A2);
97 double eta,
double eps)
noexcept {
99 for (
int k = 0; k < 2; ++k) {
100 const double z1 = zs[3 * k], z2 = zs[3 * k + 1], z3 = zs[3 * k + 2];
101 const double A = (k == 0) ? A1 : A2;
102 const double relief = z3 - z1;
112 w = (d > 0.0) ? eps : 0.0;
117 return s / (A1 + A2);
126 double mean_depth,
double eps)
noexcept {
127 const double A = A1 + A2;
128 const double zbar1 = (zs[0] + zs[1] + zs[2]) / 3.0;
129 const double zbar2 = (zs[3] + zs[4] + zs[5]) / 3.0;
130 const double zw = (A1 * zbar1 + A2 * zbar2) / A;
131 const double ztop = (zs[2] > zs[5]) ? zs[2] : zs[5];
132 const double zlow = (zs[0] < zs[3]) ? zs[0] : zs[3];
133 const double relief = ztop - zlow;
137 return zw + ((mean_depth > 0.0) ? mean_depth : 0.0);
140 if (mean_depth >= ztop - zw)
return zw + mean_depth;
144 const double dry1 =
vfrDryEta(zs[0], zs[1], zs[2], eps);
145 const double dry2 =
vfrDryEta(zs[3], zs[4], zs[5], eps);
146 const double lo0 = (dry1 < dry2) ? dry1 : dry2;
147 if (!(mean_depth > 0.0))
return lo0;
150 double lo = lo0, hi = ztop;
151 double eta = zw + mean_depth;
152 if (eta <= lo || eta >= hi) eta = 0.5 * (lo + hi);
153 for (
int it = 0; it < 80; ++it) {
155 if (f > 0.0) hi = eta;
else lo = eta;
157 double next = (df > 1.0e-12) ? eta - f / df : 0.5 * (lo + hi);
158 if (next <= lo || next >= hi) next = 0.5 * (lo + hi);
159 if (std::abs(next - eta) < 1.0e-13 * (1.0 + relief))
return next;
167 double eta,
double eps)
noexcept {
169 if (w < eps) w = eps;
170 if (w < 1.0e-12) w = 1.0e-12;
185 double* zs,
double& A1,
double& A2)
noexcept {
188 int p[4] = {0, 1, 2, 3};
189 for (
int i = 1; i < 4; ++i) {
190 const int key = p[i];
192 while (j >= 0 && z[p[j]] > z[key]) { p[j + 1] = p[j]; --j; }
195 const int n1 = p[0], n2 = p[1], n3 = p[2], n4 = p[3];
196 auto adjacent = [](
int a,
int b) {
const int d = (a - b + 4) % 4;
return d == 1 || d == 3; };
198 int t1[3], t2[3], kase;
199 if (!adjacent(n1, n4)) {
201 t1[0] = n1; t1[1] = n2; t1[2] = n4;
202 t2[0] = n1; t2[1] = n3; t2[2] = n4;
203 }
else if (adjacent(n2, n1)) {
205 t1[0] = n1; t1[1] = n2; t1[2] = n4;
206 t2[0] = n2; t2[1] = n3; t2[2] = n4;
209 t1[0] = n1; t1[1] = n3; t1[2] = n4;
210 t2[0] = n2; t2[1] = n3; t2[2] = n4;
212 auto tri_area = [&](
const int* t) {
213 const double dx1 = x[t[1]] - x[t[0]], dy1 =
y[t[1]] -
y[t[0]];
214 const double dx2 = x[t[2]] - x[t[0]], dy2 =
y[t[2]] -
y[t[0]];
215 return 0.5 * std::abs(dx1 * dy2 - dx2 * dy1);
219 zs[0] = z[t1[0]]; zs[1] = z[t1[1]]; zs[2] = z[t1[2]];
220 zs[3] = z[t2[0]]; zs[4] = z[t2[1]]; zs[5] = z[t2[2]];
225 if (!(A1 > 0.0)) { A1 = 0.0; }
226 if (!(A2 > 0.0)) { A2 = 0.0; }
#define OPENSWMM_KERNEL_FN
Definition ExplicitKokkosSurfaceSolver.cpp:18
Volume–free-surface (VFR) closure for a planar-bed triangular cell.
Definition NodeCoupling.cpp:16
OPENSWMM_KERNEL_FN double vfrMeanDepthFromEta(double z1, double z2, double z3, double eta, double eps) noexcept
Definition VfrClosure.hpp:144
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:78
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
Definition QuadVfr.hpp:125
int quadVfrPrecompute(const double *x, const double *y, const double *z, double *zs, double &A1, double &A2) noexcept
Choose the B&S 2007 diagonal for a quad and emit its precomputed VFR data.
Definition QuadVfr.hpp:184
OPENSWMM_KERNEL_FN double vfrDryEta(double z1, double z2, double z3, double eps) noexcept
Definition VfrClosure.hpp:228
constexpr double kVfrFlatRelief
Definition VfrClosure.hpp:75
OPENSWMM_KERNEL_FN double quadDEtaDMeanDepth(const double *zs, double A1, double A2, double eta, double eps) noexcept
dη/dh̄ of the regularised quad closure at stage η: 1/max(slope, eps).
Definition QuadVfr.hpp:166
OPENSWMM_KERNEL_FN double vfrWetFraction(double z1, double z2, double z3, double eta) noexcept
Definition VfrClosure.hpp:87
OPENSWMM_KERNEL_FN double quadMeanDepthFromEta(const double *zs, double A1, double A2, double eta, double eps) noexcept
Definition QuadVfr.hpp:86
OPENSWMM_KERNEL_FN double vfrStageAtWetFraction(double z1, double z2, double z3, double eps) noexcept
Definition VfrClosure.hpp:128
OPENSWMM_KERNEL_FN double quadWetFraction(const double *zs, double A1, double A2, double eta) noexcept
Definition QuadVfr.hpp:77
OPENSWMM_KERNEL_FN double quadMeanDepthSlope(const double *zs, double A1, double A2, double eta, double eps) noexcept
Definition QuadVfr.hpp:96
double * y
Definition odesolve.c:28