![]() |
SWMMVis
6.0.0-alpha.4
Qt6/C++ GIS-based graphical user interface for the SWMMVis engine (6.0.0-alpha.4)
|
The 2D marcher's CFL characteristic length, per cell and summarised. More...
#include <meshcellstats.h>
Public Attributes | |
| double | min = 0.0 |
| The cell that sets dt0. | |
| double | p10 = 0.0 |
| double | p50 = 0.0 |
| double | p90 = 0.0 |
| double | max = 0.0 |
| double | ratio = 0.0 |
| p50 / min. Reportable, not a gate — see ltsWork. | |
| int | impliedTiers = 0 |
| double | ltsWork = 0.0 |
| int | count = 0 |
| Cells measured; 0 = stats invalid. | |
| int | interiorFaces = 0 |
| int | isolatedCells = 0 |
| No interior face; used the 2A/xi_max fallback. | |
The 2D marcher's CFL characteristic length, per cell and summarised.
This is the quantity that actually sets the explicit timestep, and it is NOT triangle area: a thin triangle can carry a respectable area and still have a tiny L_char. The engine computes
L_char[t] = sqrt( 2*A_t / SUM_f( xi_f * inv_dx_normal_f ) )
over that cell's INTERIOR faces, where xi_f is the shared edge length and inv_dx_normal_f is 1 / max(|dc . n|, 0.3*|dc|) with dc the centroid offset to the neighbour. Then dt = alpha * L_char / (sqrt(g*h) + |u|).
Mirrored from openswmm.engine src/engine/2d/solver/InertialEdges.cpp:41-135 (edge assembly and cell_lchar) and src/engine/2d/mesh/MeshBuilder.cpp:44-175 (edge-vertex convention, centroid, area, unit normal). The engine's derivation of that formula is dated 2026-08-03 and has changed once already, so a divergence check against the engine's own arrays belongs in the test, not in a comment.
Caveats, because this is a geometric proxy and not a runtime prediction: dt0 is taken over WET cells only, depth enters as 1/sqrt(g*h), and coupling and boundary cells pin to LTS tier 0 regardless of their size.
Units are the project CRS's, which may be feet.
| int mesh::CflStats::count = 0 |
Cells measured; 0 = stats invalid.
| int mesh::CflStats::impliedTiers = 0 |
Tiers local timestepping would need to cover the spread, versus the project's LTS_TIERS (default 4, so 8x is all it can hide).
| int mesh::CflStats::interiorFaces = 0 |
| int mesh::CflStats::isolatedCells = 0 |
No interior face; used the 2A/xi_max fallback.
| double mesh::CflStats::ltsWork = 0.0 |
Work proxy: relative marcher cost per unit simulated time at uniform depth, (1/min) * SUM_t 2^-tier(t) with the engine's tier rule min(K-1, floor(log2(L_t/min))). Runtime is a PRODUCT of cell count and 1/min, so this is the honest single number — a spread ratio alone is blind to a refinement explosion, which lowers the median and so improves the ratio while making the mesh strictly worse. Lower is better; compare conditioned against unconditioned.
| double mesh::CflStats::max = 0.0 |
| double mesh::CflStats::min = 0.0 |
The cell that sets dt0.
| double mesh::CflStats::p10 = 0.0 |
| double mesh::CflStats::p50 = 0.0 |
| double mesh::CflStats::p90 = 0.0 |
| double mesh::CflStats::ratio = 0.0 |
p50 / min. Reportable, not a gate — see ltsWork.