Storm Water Management Model
Project description
ewatercycle-swmm
An eWaterCycle plugin for the EPA Storm Water Management Model (SWMM).
This plugin wraps the pySWMM Simulation object in
the Basic Model Interface (BMI) and runs it inside
a grpc4bmi container, so SWMM can be driven
step-by-step from Python and coupled to other models in the eWaterCycle
framework.
The containerized BMI model lives in a separate repository:
eWaterCycle/swmm-bmi. This plugin only
provides the thin eWaterCycle wrapper around the published container image
(ghcr.io/ewatercycle/swmm-grpc4bmi).
What is SWMM?
SWMM is the EPA's dynamic rainfall-runoff simulation model, used for single-event or long-term simulation of runoff quantity and quality, primarily in urban areas. A SWMM model represents the drainage network as subcatchments, nodes (junctions, outfalls, storage), links (conduits, pumps, weirs) and rain gages.
pySWMM is an open-source tool that provides "Pythonic"
access to the SWMM data model. Its Simulation object lets you step through a
running simulation, read and modify network state at each step, and post-process
results without manipulating SWMM input files directly. eWaterCycle has wrapped
this Simulation object in BMI — so for the most part you can use the model as
if it were a pySWMM Simulation, but through the standardized BMI calls
(initialize, update, get_value, set_value, finalize).
Cite pySWMM: McDonnell, B., Ratliff, K., Tryby, M., Wu, J. X., & Mullapudi, A. (2020). PySWMM: The Python Interface to Stormwater Management Model (SWMM). https://doi.org/10.21105/joss.02292
Installation
Install this package alongside your eWaterCycle installation:
pip install ewatercycle-swmm
SWMM then becomes available as one of the eWaterCycle models:
from ewatercycle.models import SWMM
The container image is pulled automatically the first time you run the model, so a working container runtime (Docker or Apptainer, as configured in eWaterCycle) is required.
Input data
To run the model you need a SWMM input file (example.inp). This file describes
the drainage network and the simulation options. It can be created with QGIS via
the generate_swmm_inp
plugin, or with any other SWMM model builder.
Note: any external data files referenced by the
.inp(e.g. a time seriesexample.dat) must sit next to the.inpin the parameter-set directory, since SWMM resolves them relative to the input file. The.inpand its data files are read directly from that directory — they are not copied into the run directory.
The input file is provided to eWaterCycle through a ParameterSet:
from pathlib import Path
from ewatercycle.base.parameter_set import ParameterSet
swmm_dir = Path.home() / "ewatercycle-swmm"
input_file = swmm_dir / "example.inp"
parameters = ParameterSet(
name="SWMM_parameter_files",
directory=swmm_dir,
config=input_file,
target_model="swmm",
)
Usage
A worked example is provided in
demo_containerized_model.ipynb, which
reproduces the "Latte" example from the pySWMM website (example.inp). The
essentials:
Set up and initialize
from ewatercycle.models import SWMM
model = SWMM(parameter_set=parameters)
cfg_file, _ = model.setup()
model.initialize(cfg_file)
The model grids
SWMM exposes its elements through four BMI grids:
| Grid | Element type |
|---|---|
| 0 | Subcatchments |
| 1 | Nodes |
| 2 | Links |
| 3 | Rain gages |
n_sc = model.get_grid_size(0) # subcatchments
n_nodes = model.get_grid_size(1) # nodes
n_links = model.get_grid_size(2) # links
Reading values: the time loop
The model is advanced one step at a time with update(), reading variables with
get_value() along the way — the standard BMI pattern:
import numpy as np
times, node_depth, link_flow = [], [], []
while model.time < model.end_time:
times.append(model.get_current_time())
node_depth.append(model.get_value("node_depth"))
link_flow.append(model.get_value("link_flow"))
model.update()
node_depth = np.array(node_depth) # shape: (n_steps, n_nodes)
link_flow = np.array(link_flow) # shape: (n_steps, n_links)
Output variables
| Variable | Grid | Units |
|---|---|---|
subcatchment_runoff |
subcatchments | m³/s |
node_depth |
nodes | m |
node_flooding |
nodes | m³/s |
link_flow |
links | m³/s |
Setting values: external forcing
Input variables can be set with set_value() before each update(), for
example to inject a lateral inflow at every node:
EXTERNAL_INFLOW_M3S = 0.05 # 50 L/s at every node, on top of storm runoff
while model.get_current_time() < model.get_end_time():
model.set_value("node_lateral_inflow", np.full(n_nodes, EXTERNAL_INFLOW_M3S))
model.update()
Input variables
| Variable | Grid | Units |
|---|---|---|
node_lateral_inflow |
nodes | m³/s (via pySWMM Node.generated_inflow) |
precipitation |
rain gages | in/hr or mm/hr (depends on flow units) |
Finalize
Always finalize the model when you are done. This shuts down the underlying container so it does not keep running in the background and consuming resources:
model.finalize()
How it works
SWMMis aContainerizedModelthat points at theghcr.io/ewatercycle/swmm-grpc4bmiimage built from eWaterCycle/swmm-bmi.setup()writes aswmm_config.jsonconfiguration file (read by the container oninitialize()) into a per-run directory. It points the container at the.inpin place in the parameter-set directory — which eWaterCycle mounts into the container — rather than copying it. SWMM's writable outputs (the.rptreport and.outbinary) are directed into the run directory instead, so nothing is copied on each run.- Any attribute eWaterCycle does not expose itself is delegated to the underlying
BMI/pySWMM
Simulationobject, so you can largely treat the model like a pySWMMSimulation.
For the BMI implementation, the container build, and the full list of exposed variables, see the swmm-bmi repository.
Development
Install the package with its development dependencies and run the test suite:
pip install -e .[dev]
pytest
The tests are intentionally lightweight and do not start a container or run the model:
tests/test_metadata.pychecks the package metadata (version, plugin entry point, container image reference) and the bundledexample.inp. These need only the standard library, so they run anywhere.tests/test_model.pychecks theSWMMwrapper class wiring. These requireewatercycleto be importable and are skipped automatically when it is not installed.
On a machine without ewatercycle you will see the metadata tests pass and the
model tests skipped; with ewatercycle installed all tests run.
License
ewatercycle-swmm is distributed under the terms of the
BSD-2-Clause license, following
the license of pySWMM. See
LICENSE.txt.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ewatercycle_swmm-0.0.4.tar.gz.
File metadata
- Download URL: ewatercycle_swmm-0.0.4.tar.gz
- Upload date:
- Size: 3.0 MB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
04b0130703bba3abfe5d698d426b511e48c8f5045f8d8e060796dc2150aa5e26
|
|
| MD5 |
82fa0bc5d28f7bf218f4b443c01aa560
|
|
| BLAKE2b-256 |
a615ba3afbaa0bb293f8645c7c8373b67eae68f2bb5a822d050868952663def5
|
File details
Details for the file ewatercycle_swmm-0.0.4-py2.py3-none-any.whl.
File metadata
- Download URL: ewatercycle_swmm-0.0.4-py2.py3-none-any.whl
- Upload date:
- Size: 7.3 kB
- Tags: Python 2, Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7063517951b148609143e4e9a21064698602d8214b7d1f4e1c0e18c1da23dbee
|
|
| MD5 |
96cb7a05543cb9338bde961ac21bebc3
|
|
| BLAKE2b-256 |
08a99a32814bab3db66cb1e37bd0caadd57e9c1196498130d2013d8959ae128f
|