A translation of the 1D engine of OpenSWMM 6 (HydroCouple/openswmm.engine, branch swmm6_rel, commit 88329d6)
into Python, held to the same output as the C++ engine: the same binary .out file and the same .rpt
report, apart from the three clock lines. It is not SWMM6 and not a HydroCouple or EPA release; it is a
translation checked against SWMM6.
412 of the 413 models run are byte-identical (of those run, 1 did not finish within the time limit, EPA/72_H&H_Elements(2).inp after 7000 s; untested, not failed) against the C++ reference engine built from the same commit and run on one thread
(OMP_NUM_THREADS=1), on the 480-model gate set (the one the SWMM5 ports were checked on), drawn from
1729-SWMM5-Models-2030. Gate run
py2; every result, with the SHA-256 of each .out and .rpt, is in gate/evidence/. The other 67 of the 480, the slowest for this port, were not run on this build: the run was stopped there by choice, not by a failure.
The same engine on the 452 extra decks: 450 of 452 extra decks byte-identical (2 did not finish within the time limit: legacy_small.inp, refactored_small.inp; untested, not failed). These are SWMM6's own tests, which the corpus cannot be:
the input files in the upstream repository's tests folder at 88329d6, and the synthetic decks of
swmm6-rust's gate, which probe the finite-volume solver, its
structure coupling, the newer hydrology and the input checks. Gate run
py_x2, in gate/evidence/ with the same hashes.
A model passes when its .out is byte-identical to the reference's (when the reference writes one), its .rpt is
identical after removing the lines "Analysis begun", "Analysis ended" and "Total elapsed time", and its exit code is
the same (the command line exits nonzero when a model stops on an input error).
The six translations, all from the same C# and gated the same way: swmm6-csharp, swmm6-go, swmm6-java, swmm6-typescript, swmm6-fortran and swmm6-python, under SWMMBobSWMM6.
The C++ engine was translated to C# first, and the C# gated to 480 of 480. The other five languages are
translated from that C#, not from the C++. tools/cs2x/Cs2Py.cs translates the verified C# engine (cs/gen) through Roslyn (py/gen/engine.py; the mapping is in tools/cs2x/PY.md); py/cpp is the runtime library in Python. CPython's math module calls the system's glibc, as the C++ does, so its results are glibc's.
Nothing in the generated engine is edited by hand. Where the output depends on the C library (printf's rounding,
strtod, sscanf, the order of a hash table's nodes, introsort's swaps), the runtime reproduces glibc and libstdc++
exactly; the checks in tests/ compare it with them case by case.
Needs CPython 3.13 (nothing else). No build step. Then run a model the way the C++ command line runs it:
py/runswmm6 model.inp model.rpt model.out
To regenerate the engine: tools/cs2x/build_py.sh, then dotnet tools/cs2x/bin/cs2py.dll cs py/gen, then python3 py/tools/gen_init.py. The C# engine it starts from is regenerated from the C++ source with
tools/cpp2x (see the header of tools/cpp2x/emit_cs.py and cs/README.md), which needs the OpenSWMM source at
commit 88329d6 and libclang.
gate/make_ref.sh makes the reference outputs with the C++ engine (ref/runswmm6: build openswmm.engine at
88329d6 and run it single-threaded); gate/gate.py NAME "py/runswmm6" --resume runs this engine on every model in
gate/models_all.tsv (paths relative to the corpus; set SWMM_CORPUS) and compares; gate/cmp1.sh checks one
model. The extra decks are listed in gate/models_extra.tsv, with paths relative to a folder that holds clones of
openswmm.engine (at 88329d6) and swmm6-rust: make their references with
SWMM_CORPUS=FOLDER MODELS=gate/models_extra.tsv REF=$PWD/gate/ref_outputs_extra gate/make_ref.sh, then run
gate/gate.py NAME "py/runswmm6" --models gate/models_extra.tsv --ref gate/ref_outputs_extra --root FOLDER --resume.
The median time per model in the gate run was 1.92 s (the C# engine's: 0.76 s, which includes .NET's start-up and JIT compilation). The times were measured on a shared two-core cloud machine while other runs were going, so they are a
rough guide, not a benchmark.
- Agreement on models outside the 480 and the 452. The two sets are broad (EPA's examples, the OWA EXTRAN set, hydrology, hydraulics, water quality, LID, RDII, controls, hot start, input errors, the FV solver and SWMM6's own tests), but a feature no gate model or deck uses is untested.
- The reference's parallel runs. Every parallel loop runs on one thread, in order, which is what the C++ engine does when it is held to one thread; results with OpenMP threads can differ in the last bits.
- The 2D and other modules of OpenSWMM 6 beyond the 1D engine the command line runs.
This repository is a translation of the OpenSWMM 6 engine.
OpenSWMM Engine — Copyright 2026 HydroCouple Developers, licensed under the Apache License, Version 2.0. See
LICENSE and NOTICE. Source: https://github.com/HydroCouple/openswmm.engine (branch
swmm6_rel, commit 88329d6).
Every generated engine file here is a modified, mechanically translated form of the OpenSWMM sources: its header
names what it was generated from, and each C# file in cs/gen names the OpenSWMM source file it came from.
Portions derive from the USEPA Storm Water Management Model, which is in the public domain under 17 USC § 105. The USEPA does not endorse this product, and neither does HydroCouple.
The translators, the runtime, the gate and the notes: Copyright 2026 Robert Dickinson, licensed under the Apache License, Version 2.0.
Made with Claude (Anthropic): the translators, the runtime, the gate and the notes are Claude's work, directed by Robert Dickinson; the engine itself is OpenSWMM's, translated mechanically. See AI-USE.md.