Depth each description assigns to the same stored fraction
What you are looking at
A LEGACY run reads area from depth through one table (A_xxx, or the inverted Y_xxx for the four shapes that ship no area table), depth from area through another (Y_xxx), top width through a third (W_xxx), and — for Gothic, Catenary, Semi-elliptical and Semi-circular — hydraulic radius through a fourth, the section-factor table, via R = (S/A)3/2. Width is the derivative of area, so at most one of these can be right about any real pipe.
The band is Corinne's Figure 2: a 2 m gothic sewer holding 2% of its capacity sits at 90 mm by its depth-of-area table and at 145 mm by its own width table. She reports 146 mm; the 1 mm is integration step. At 0.5% the gap is a factor of three.
xsect_tables.hpp at commit 7ff727be (a verbatim translation of EPA xsect.dat 5.2.1), read through the lookup()/invLookup() logic of xsect.c. Full-section constants from xsect_setParams().(dA/dy − W) / W. It needs no outside reference — the two tables simply have to agree with each other, and they do not. Under linear resample this reproduces the article's table digit for digit.Relative disagreement between dA/dy and W
All eight tabulated closed shapes
Two notes on reading that table (hers): the 2% depth column is a local slope, so it is sensitive to where the table's own nodes fall — y/D = 0.02 is exactly a node of Circular's 51-point table, and the slope jumps from −34% just below it to +22% just above. The last two columns are dense sweeps and are not node-sensitive.
A third note (this app's): the four worst rows are the four shapes with no area table. Their area comes from inverting the depth-of-area table — a second digitisation of the same pipe — which is exactly why it need not agree with the first.
docs/dev/legacy_defects.md.XPOLYGON boundary is a closed chain of straight segments and DXF-bulge arcs. Area, perimeter, top width and first moment come from one Green's-theorem contour integral, so T = dA/dy holds by construction — check it at any depth below. Then export the [CURVES] and [XSECTIONS] lines.Section curves from the one boundary
Identity check |dA/dy − T| / T
Export
Syntax from Appendix D of the OpenSWMM v6 manual at the same commit: Link POLYGON Scale Open 0 0 Barrels Bcurve; Barrels must be supplied because Bcurve is read from the token after it. A clockwise chain is reoriented automatically with every bulge sign flipped; a self-crossing chain is rejected; |bulge| > 1 is rejected (a half circle is the largest single arc). This app's own validity test is stricter than a chord check: it walks the arcs as 48-piece polylines and refuses touching and overlap as well as crossing, so a boundary that passes here is simple in the plain geometric sense — whether the engine at this commit accepts exactly the same set is a claim I have not verified. The invert is located automatically as the boundary's lowest point, arc interiors included. Runs only on openswmm.engine at or after feature/xsect-geometry; EPA SWMM 5.2.4 will stop with ERROR 205 on the keyword.
Reported in the article — not recomputed here
Bellinge: 1015 conduits, 48 h dry weather, one binary, one changed option — XSECT_GEOMETRY LEGACY versus EXACT.
| LEGACY | EXACT | ||
|---|---|---|---|
| FV, 2 h window | −2.253% | −0.134% | ~17× better |
| FV, filling window | −4.453% | −0.022% | ~200× better |
| DYNWAVE continuity | −0.073% | +0.085% | no meaningful change |
- What moved under DYNWAVE
- Of 189 conduits carrying > 1 L/s, 80% diverge by more than 1% of their own peak at some instant, 45% by more than 10%, 33% by more than 25%. Median 7.0% at the worst instant; 1.2% averaged over 48 h (upper decile 14%). Node depths: median 5.8%; one node differs by 755 mm at one moment.
- What did not move
- Peak flows agree to a median of 0.20%; the largest change in any node's peak depth is 2 mm. Exact geometry shifts timing and shape under an almost unchanged peak.
- Cost of the shipped build
- DYNWAVE 40.0 s → 63.1 s (~1.58×); FV 2 h 319.9 s → 536.2 s (~1.68×). Part of that is
-ffp-contract=off, kept for bit-parity with EPA 5.2.4; the split is unmeasured. Gothic compiles 5.6× faster than its legacy path; Circular ~1.15× slower. - Her own caveat
- 953 of Bellinge's 1031 sections are circular and the other 78 are shapes EXACT does not compile. Restricting EXACT to every shape except circular gives output byte-for-byte identical to LEGACY. Bellinge cannot show what exact geometry is worth on the shapes it helps most.
One-cell caricature: run it
Depth: width-table head update vs consistent head update
Continuity residual, % of total inflow
Why the residual is a state function
In the cell, head advances by dy = (Qin − Qout) dt / (T·L) and stored volume is reported as V = A(y)·L. The continuity residual after any stretch of time is therefore
∫(Qin − Qout) dt − ΔV = L · ∫y₀y₁ (T − dA/dy) dy = L · [Φ(y₁) − Φ(y₀)]
It depends on where the depth started and ended, not on the path between. A dry-weather run that finishes near where it began returns a residual near zero however far the depth wandered in between — while every intermediate head, and every outflow computed from it, carried the width error. The curve below is Φ for the selected shape; the residual you just plotted is the difference of two of its values. This is a caricature of one node-and-conduit, not of SWMM's network solver, but the mechanism is the same one her measurement shows: the check confirms the bookkeeping is self-consistent; it was never an instrument for asking whether the geometry is right.
FvKernels.hpp requires depthOfArea ∘ areaOfDepth to be the identity — two independently digitised tables cannot satisfy that, one boundary can.The twelve moves, in her order
Fill the template
Preview, in her stylesheet
Rendered with the article page's own tokens and type (Sora, Inter, JetBrains Mono) so you can see the piece as it would sit on hydrocouple.org. The preview stays light in both themes — that is her site's palette, quoted.
Her markup skeleton
Her CSS tokens (from css/site.css)
lookup(), the parsed shape tables and the Green's-theorem boundary evaluator. This tab runs the same test file the build ran in Node — against the copy of the code that is executing in your browser right now — so a passing count is evidence about this page, not about a build on someone else's machine.Embedded verification suite
lookup() against closed-form circle geometry · the LD-2 register number · the Appendix D four-arc circle (area, perimeter, width, hydraulic radius, T = dA/dy) · degenerate boundaries rejected (bow-tie, vertex-on-edge, repeated vertex, zero-length chord, fold-back, inward arc crossings) · legitimate concave and inward-arc shapes accepted · the one-cell continuity caricature · SI ↔ US round trip on this page's own controls. Sources and pinned commits are behind the Sources button in the header.