Command line
benchmark1d2d is an open V&V suite for free-surface and pressurized water solvers. You score a solver against catalog cases: Track A checks the physics against exact solutions, conservation laws and measurements; Track B checks parity with a pinned industry engine (EPA SWMM 5.2.4, EPANET 2.2).
1. Install
git clone https://github.com/scott-jeffers/benchmark1d2d.git
cd benchmark1d2d
python -m pip install -e ".[dev,engines]" # engines = EPA SWMM 5.2.4 and EPANET 2.2
python scripts/fetch_inputs.py # large inputs (DEMs), each checked by SHA-256
Confirm the CLI:
benchmark1d2d catalog list
benchmark1d2d engines
2. See the scoring work first
The repository scores real runs end to end. Each command writes score cards
to out/ and prints every criterion with its observed value:
python scripts/run_vertical_slice.py # 1D demo solvers: dam breaks, backwater, jump, water hammer, tracer
python scripts/run_network_cases.py # EPA EPANET 2.2 on the two pipe-network cases
python scripts/run_demo_2d.py A2A-010 # 2D demo finite-volume solver (omit the ID to run all 2D cases)
3. Write results in the common format
One Parquet file per run with columns t, x, y, h, u, v, p (SI units), plus
Q, c and bed elevation z where they apply. Network solvers add
element_id (node or link name) and element_type (node or link); for
pressurized networks h is the piezometric head. Each case page lists the
variables, output times and probe points it needs.
4. Score a Track A case
Pass every refinement level so the observed order of accuracy can be measured:
benchmark1d2d score A1F-010 --results out/mine_dx1.25.parquet \
--refinement out/mine_dx10.parquet out/mine_dx5.parquet out/mine_dx2.5.parquet out/mine_dx1.25.parquet \
--solver-name my-solver --solver-version 1.0
A pass needs every gating criterion and, on verification cases, the convergence check. A fail on a verification case means the equations are not being solved to the stated tolerance: Track A can prove a solver wrong. Steady closed-form cases (the pipe networks) have no grid to refine; their page says so.
5. Score a Track B case
Run your solver on the case's inputs/network.inp and write per-element
results (the swmm5 and epanet22 adapters show the format), then:
benchmark1d2d score B-RTC-001 --results my_rtc.parquet --solver-name my-solver
The score card names the worst node or link for each criterion. If a case's
reference is missing the CLI prints NOT SCORED, never a pass.
6. Score a SWMM engine across the corpus
Any engine with a swmm.toolkit-compatible Python build can be compared with
SWMM 5.2.4 on a whole tier of the HydroCouple corpus:
git clone https://github.com/HydroCouple/openswmm.engine.benchmarks hc # then check out the pinned commit
python scripts/corpus_parity.py --corpus hc/corpus --tier pr \
--candidate-python /path/to/candidate/python --label my-engine
Results land in out/corpus_parity/: one row per model with its worst node
and worst link, plus a summary. A difference says how far the candidate is
from the reference engine, not which one is right.
7. Check a score card
benchmark1d2d verify-card out/vertical_slice/A1F-010_ritter_dry_bed_dambreak.scorecard.json
This checks the content hash and says whether the card carries the public development key (demo runs) or a maintainer key.