SWMMVis  6.0.0-alpha.4
Qt6/C++ GIS-based graphical user interface for the SWMMVis engine (6.0.0-alpha.4)
Loading...
Searching...
No Matches
VertexDepthReconstruct Namespace Reference

Classes

struct  CellSplit
 One cell of a mixed triangle/quad mesh, pre-split for the reconstruction (workplans/TRI_QUAD_MESHING_PLAN_2026-09-06.md). More...
 

Functions

double cellEtaFromMeanDepth (double h, double za, double zb, double zc)
 
double triMeanDepthFromEta (double eta, double za, double zb, double zc)
 
double quadEtaFromMeanDepth (const double zs[6], double a1, double a2, double h)
 
void reconstructVertexSignedDepths (const std::vector< CellSplit > &cells, const std::vector< float > &cellDepths, const std::vector< float > &cellZc, const std::vector< double > &vz, float dryF, std::vector< float > &vsum, std::vector< float > &wsum, std::vector< float > &outVertexDepth)
 Reconstruct per-vertex SIGNED depths (η_v − z_v) from per-cell mean depths on a mixed triangle/quad mesh.
 
void reconstructVertexSignedDepths (const std::vector< std::array< int, 3 > > &tris, const std::vector< float > &cellDepths, const std::vector< float > &cellZc, const std::vector< double > &vz, float dryF, std::vector< float > &vsum, std::vector< float > &wsum, std::vector< float > &outVertexDepth)
 
void extrapolateDryCorners (double z0, double z1, double z2, float &sd0, float &sd1, float &sd2)
 Replace the NO-DATA sentinel at a partially-wet cell's dry corners with the extrapolated signed depth, in place.
 

Function Documentation

◆ cellEtaFromMeanDepth()

double VertexDepthReconstruct::cellEtaFromMeanDepth ( double  h,
double  za,
double  zb,
double  zc 
)
inline

Free-surface elevation η of one cell from its mean depth h̄ — inverts the planar-bed stage–storage relation through the cell's three vertex elevations (mirror of the engine's cellFreeSurfaceElevation, VertexReconstruction.cpp). For a PARTIALLY wet cell (η < highest vertex) this pools the water over the wetted fraction instead of the flat closure z̄ + h̄, which overstates η on cells spanning a bed step — the other half of the "water climbs the step" artifact. Fully wet reduces exactly to z̄ + h̄.

Here is the caller graph for this function:

◆ extrapolateDryCorners()

void VertexDepthReconstruct::extrapolateDryCorners ( double  z0,
double  z1,
double  z2,
float &  sd0,
float &  sd1,
float &  sd2 
)
inline

Replace the NO-DATA sentinel at a partially-wet cell's dry corners with the extrapolated signed depth, in place.

Parameters
z0,z1,z2Corner bed elevations.
sd0,sd1,sd2Corner signed depths (η−z); exactly 0 == no data. Dry corners of a cell that has at least one wet corner are overwritten with maxEta − z_k (negative where the bed stands above the pool).

The map's marching-triangles bands/isolines and the Gouraud fills interpolate these corner values LINEARLY, but the sentinel is not a depth — reading it as one drags the waterline out to the dry vertex and paints water on bed that stands above the free surface (2D_MAP_POOLING_EXTRAPOLATION_PLAN_2026-08-04.md).

The scalar that IS linear on a triangle is η − z: the bed z is linear by construction and the extrapolated η is constant in the dry direction, so filling the dry corners with maxEta − z_k makes the linear blend reproduce max(0, η − z) exactly — the marching passes then cut the shoreline on the true sub-cell bed intercept, matching the constant-η surface CellSurfaceInterp::depthAt already gives the profile.

Bounded by the driving head: every filled corner sits exactly on the pool surface maxEta, so nothing rises above the water that supplies it. Applied per triangle on the per-cell corner copies (SceneTri::dv*), so the extrapolation reaches exactly one cell beyond the wet front and cannot propagate into ground the solver never wetted.

Fully-wet (all sd > 0) and fully-dry (no sd > 0) cells are left byte-for-byte unchanged. A filled corner below the pool is non-supplying in CellSurfaceInterp (sd < 0) exactly as the sentinel was, so the profile path is unaffected on the canonical bank case.

◆ quadEtaFromMeanDepth()

double VertexDepthReconstruct::quadEtaFromMeanDepth ( const double  zs[6],
double  a1,
double  a2,
double  h 
)
inline

Free-surface elevation η of a QUAD from its mean depth h̄ — inverts the area-weighted sum of the two planar sub-triangle relations h̄(η) = [A₁·d̄₁(η) + A₂·d̄₂(η)] / (A₁+A₂) (mirror of the engine's quadEtaFromMeanDepth, QuadVfr.hpp, ε = 0). Closed form when fully wet; bisection on the monotone sum otherwise. zs holds the six sub-triangle vertex elevations (sub 1 then sub 2, any order within a triple).

Here is the call graph for this function:
Here is the caller graph for this function:

◆ reconstructVertexSignedDepths() [1/2]

void VertexDepthReconstruct::reconstructVertexSignedDepths ( const std::vector< CellSplit > &  cells,
const std::vector< float > &  cellDepths,
const std::vector< float > &  cellZc,
const std::vector< double > &  vz,
float  dryF,
std::vector< float > &  vsum,
std::vector< float > &  wsum,
std::vector< float > &  outVertexDepth 
)
inline

Reconstruct per-vertex SIGNED depths (η_v − z_v) from per-cell mean depths on a mixed triangle/quad mesh.

Each cell's η comes from its own planar-bed closure (triangle: the B&S 2006 inversion; quad: the two-sub-triangle sum, quadEtaFromMeanDepth). The depth weight is scaled by 3/nv — the plan's "1/nv per incident cell" weighting normalised so an all-triangle mesh is bit-identical to the historical (h-weighted) result: a triangle contributes h, a quad 3h/4.

vsum,wsum are caller-owned scratch (resized here) so the per-frame maxDepthPerVertex loop never allocates. outVertexDepth is resized to vz.size(); a vertex with no qualifying incident cell yields 0. After the call wsum[v] > 0 iff vertex v had a qualifying (wet, corner-reaching) incident cell this frame.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ reconstructVertexSignedDepths() [2/2]

void VertexDepthReconstruct::reconstructVertexSignedDepths ( const std::vector< std::array< int, 3 > > &  tris,
const std::vector< float > &  cellDepths,
const std::vector< float > &  cellZc,
const std::vector< double > &  vz,
float  dryF,
std::vector< float > &  vsum,
std::vector< float > &  wsum,
std::vector< float > &  outVertexDepth 
)
inline

All-triangle convenience overload (historical signature): wraps each triangle as a one-sub-triangle CellSplit and delegates.

Here is the call graph for this function:

◆ triMeanDepthFromEta()

double VertexDepthReconstruct::triMeanDepthFromEta ( double  eta,
double  za,
double  zb,
double  zc 
)
inline

Exact planar-triangle mean depth h̄(η) — the forward stage–storage relation cellEtaFromMeanDepth inverts (B&S 2006). za,zb,zc in any order.

Here is the caller graph for this function: