Skip to content

Fix/issue 1 junction surface area#5

Open
wiesnerfriedman wants to merge 11 commits intoSWMM-Project:swmm6_relfrom
wiesnerfriedman:fix/issue-1-junction-surface-area
Open

Fix/issue 1 junction surface area#5
wiesnerfriedman wants to merge 11 commits intoSWMM-Project:swmm6_relfrom
wiesnerfriedman:fix/issue-1-junction-surface-area

Conversation

@wiesnerfriedman
Copy link
Copy Markdown

Node::getSurfArea returns MIN_SURFAREA as a constant for non-storage nodes, which gets added to conduit half-areas instead of acting as a floor. This inflates junction surface area, damping depth response. Fix moves the floor to DWSolver::setNodeDepth as max(surfArea, MIN_SURFAREA).

wiesnerfriedman and others added 7 commits April 17, 2026 21:26
Only strip conduit/orifice half-areas at a STORAGE node when the
storage curve provides area > MIN_SURFAREA. For degenerate storage
nodes (zero or near-zero curve), keep the legacy pipe-half
contribution so the Picard denominator stays bounded away from
MIN_SURFAREA.

Fixes: DynamicWave.cpp::updateNodeFlows (conduit path)
Fixes: SWMMEngine.cpp non-conduit callback (orifice path)
Tests: 5 new StorageHalfAreaGuard unit tests
… regimes

Anderson acceleration (AA) requires a smooth fixed-point operator G
between consecutive Picard iterates. Three surcharge formulations
violate this assumption:

  EXTRAN:       discontinuous dQ/dH formulation at crown
  DYNAMIC_SLOT: per-iterate geometry rewrite (Sharior et al. 2023)
  SLOT:         C⁰ kink at the slot cutoff (~0.985·yFull)

The existing code only skipped AA for EXTRAN surcharged nodes (from
pr/aa-extran-guard). This extends the guard to all three regimes via
a per-node aa_skip_ flag vector, scatter-computed each Picard iteration
after geometry is known:

  - EXTRAN: skip when xnode_.is_surcharged
  - DPS:    skip end-nodes of conduits with active slot area (As > 0)
  - SLOT:   skip end-nodes of conduits with depth_mid/yFull in [0.98, 1.02]

Free-surface nodes (95%+ of network) retain full AA speedup.
No physics is altered; only the numerical accelerator is gated.

Implementation:
  - DynamicWave.hpp: add aa_skip_ (vector<uint8_t>), computeAASkipFlags()
    declaration, aaSkipFlags() const accessor
  - DynamicWave.cpp: allocate aa_skip_ in init(), implement
    computeAASkipFlags() with O(n_conduits) scatter, call after
    computeLinkGeometry() in execute(), guard AA block in
    updateNodeDepths() with !aa_skip_[ui]

Tests: 6 new AASkipFlagTest cases in test_routing.cpp
  - FreeSurfaceNoSkip, ExtranSurchargedSkips, DPSActiveSkipsEndNodes,
    SlotNearKinkSkipsEndNodes, SlotFarFromKinkNoSkip, AADisabledNoFlags
  All 61 routing tests pass.
…orage-conduit-halves

fix(issue-2): conditionally zero storage-node conduit half-areas
…derson-acceleration-scope

fix(issue-3): extend Anderson acceleration skip guard to DPS and SLOT…
…Node, wire option into DWSolver with unit conversion, add .inp-driven regression tests

Phase 1: Non-storage getSurfArea() returns 0.0 (physical area only)
Phase 2: Storage getSurfArea() purely geometric (no MIN_SURFAREA clamp)
         Wire MIN_SURFAREA/HEAD_TOL options into DWSolver with UCF conversion
Phase 3: Add minimal_conduit.inp fixture and DWNodeContinuity tests
         (DepthRisesWithForcedLateralInflow, MultipleStepsAccumulateDepth)

All 61 routing + 21 site-drainage tests pass.
@wiesnerfriedman wiesnerfriedman force-pushed the fix/issue-1-junction-surface-area branch from dac366e to 8f75098 Compare April 21, 2026 02:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants