Files
pumpingStation/src
Rene De Ren d8490aa949 Predicted-volume hard-floor at 0 + spill flow position refactor
Volume integrator changes:
- Hard physical floor at 0 added to _updatePredictedVolume. Without
  it, a basin seeded below dryRunSafetyVol (calibration / startup
  / low seed) under continued net-outflow drifted volume arbitrarily
  negative; the level output looked clamped only because
  _calcLevelFromVolume floors at 0, masking the underlying drift.
- New cumulative diagnostic: underflowVolume.predicted.atequipment
  (m³) + getOutput().predictedUnderflowVolume. Non-zero indicates a
  flow-balance error (over-reported outflow / missing inflow).
- The transition-only dryRunSafetyVol clamp is preserved so
  startup-from-empty doesn't snap to 2.1 m³ on tick 1.

Spill flow refactor (taxonomic + bug fix):
- Synthetic spill moved from flow.predicted.out.<child='overflow'>
  to its own position flow.predicted.overflow.<default>. The spill
  is a derived quantity, not a physical sub-source sharing a position
  with pumps — .child() was the wrong knob.
- Removes the spillPrev self-subtraction in the integrator (no longer
  needed: outflowTotal at ['out','downstream'] cleanly excludes spill).
- Closes a latent fall-through bug exposed during this work:
  .child('overflow').getCurrentValue() returned the value of any
  available sibling child when overflow itself didn't yet exist.
  Hardened separately in generalFunctions@a516c2b.
- _selectBestNetFlow folds the overflow position into the outflow
  side so the predicted net-flow balance still reads ~0 while pinned.

Tests: 70/70 pass. 4 new subtests cover the 0-floor, accumulated
underflow tracking, getOutput surface, and refill-from-empty.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 17:18:23 +02:00
..