62#ifndef OPENSWMM_ENGINE_2D_QUAD_VFR_HPP
63#define OPENSWMM_ENGINE_2D_QUAD_VFR_HPP
89 double eta)
noexcept {
92 return (A1 * w1 + A2 * w2) / (A1 + A2);
111 double eps)
noexcept {
114 return (A1 * d1 + A2 * d2) / (A1 + A2);
135 double eps)
noexcept {
137 for (
int k = 0; k < 2; ++k) {
138 const double z1 = zs[3 * k], z2 = zs[3 * k + 1], z3 = zs[3 * k + 2];
139 const double A = (k == 0) ? A1 : A2;
140 const double relief = z3 - z1;
150 w = (d > 0.0) ? eps : 0.0;
155 return s / (A1 + A2);
178 double mean_depth,
double eps)
noexcept {
179 const double A = A1 + A2;
180 const double zbar1 = (zs[0] + zs[1] + zs[2]) / 3.0;
181 const double zbar2 = (zs[3] + zs[4] + zs[5]) / 3.0;
182 const double zw = (A1 * zbar1 + A2 * zbar2) / A;
183 const double ztop = (zs[2] > zs[5]) ? zs[2] : zs[5];
184 const double zlow = (zs[0] < zs[3]) ? zs[0] : zs[3];
185 const double relief = ztop - zlow;
189 return zw + ((mean_depth > 0.0) ? mean_depth : 0.0);
192 if (mean_depth >= ztop - zw)
193 return zw + mean_depth;
197 const double dry1 =
vfrDryEta(zs[0], zs[1], zs[2], eps);
198 const double dry2 =
vfrDryEta(zs[3], zs[4], zs[5], eps);
199 const double lo0 = (dry1 < dry2) ? dry1 : dry2;
200 if (!(mean_depth > 0.0))
204 double lo = lo0, hi = ztop;
205 double eta = zw + mean_depth;
206 if (eta <= lo || eta >= hi)
207 eta = 0.5 * (lo + hi);
208 for (
int it = 0; it < 80; ++it) {
215 double next = (df > 1.0e-12) ? eta - f / df : 0.5 * (lo + hi);
216 if (next <= lo || next >= hi)
217 next = 0.5 * (lo + hi);
218 if (std::abs(next - eta) < 1.0e-13 * (1.0 + relief))
240 double eps)
noexcept {
265 double& A1,
double& A2)
noexcept {
268 int p[4] = {0, 1, 2, 3};
269 for (
int i = 1; i < 4; ++i) {
270 const int key = p[i];
272 while (j >= 0 && z[p[j]] > z[key]) {
278 const int n1 = p[0], n2 = p[1], n3 = p[2], n4 = p[3];
279 auto adjacent = [](
int a,
int b) {
280 const int d = (a - b + 4) % 4;
281 return d == 1 || d == 3;
284 int t1[3], t2[3], kase;
285 if (!adjacent(n1, n4)) {
293 }
else if (adjacent(n2, n1)) {
310 auto tri_area = [&](
const int* t) {
311 const double dx1 = x[t[1]] - x[t[0]], dy1 =
y[t[1]] -
y[t[0]];
312 const double dx2 = x[t[2]] - x[t[0]], dy2 =
y[t[2]] -
y[t[0]];
313 return 0.5 * std::abs(dx1 * dy2 - dx2 * dy1);
#define OPENSWMM_KERNEL_FN
Definition ExplicitKokkosSurfaceSolver.cpp:22
Volume–free-surface (VFR) closure for a planar-bed triangular cell.
Definition ExchangeLaw.hpp:60
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
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:264
OPENSWMM_KERNEL_FN double vfrDryEta(double z1, double z2, double z3, double eps) noexcept
Dry-cell free surface of the regularized closure: η(V = 0). This is the value a dry cell's head must ...
Definition VfrClosure.hpp:332
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:239
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 vfrStageAtWetFraction(double z1, double z2, double z3, double eps) noexcept
Stage η_s at which the wetted-area fraction equals eps (0 < eps < 1). Inputs must be sorted and non-f...
Definition VfrClosure.hpp:186
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 quadMeanDepthSlope(const double *zs, double A1, double A2, double eta, double eps) noexcept
Slope dh̄/dη of the REGULARISED sum at η: each sub-triangle contributes its wet fraction above its sw...
Definition QuadVfr.hpp:134
double * y
Definition odesolve.c:37