Skip to main content

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 series example.dat) must sit next to the .inp in the parameter-set directory, since SWMM resolves them relative to the input file. The .inp and 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

  • SWMM is a ContainerizedModel that points at the ghcr.io/ewatercycle/swmm-grpc4bmi image built from eWaterCycle/swmm-bmi.
  • setup() writes a swmm_config.json configuration file (read by the container on initialize()) into a per-run directory. It points the container at the .inp in place in the parameter-set directory — which eWaterCycle mounts into the container — rather than copying it. SWMM's writable outputs (the .rpt report and .out binary) 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 Simulation object, so you can largely treat the model like a pySWMM Simulation.

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.py checks the package metadata (version, plugin entry point, container image reference) and the bundled example.inp. These need only the standard library, so they run anywhere.
  • tests/test_model.py checks the SWMM wrapper class wiring. These require ewatercycle to 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.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ewatercycle_swmm-0.1.1.tar.gz (2.4 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

ewatercycle_swmm-0.1.1-py2.py3-none-any.whl (7.3 kB view details)

Uploaded Python 2Python 3

File details

Details for the file ewatercycle_swmm-0.1.1.tar.gz.

File metadata

  • Download URL: ewatercycle_swmm-0.1.1.tar.gz
  • Upload date:
  • Size: 2.4 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.14.0

File hashes

Hashes for ewatercycle_swmm-0.1.1.tar.gz
Algorithm Hash digest
SHA256 4cac4435dd3a56f56ab3dd23a96cc3f8f6e45a3aba49125b9484990c04fbda8b
MD5 e0f2c5480fd8de74718be1f568d4a439
BLAKE2b-256 59235f0b4b770c04b50aac9af16d10d53042bf9e85da7c37d172ffe765830e55

See more details on using hashes here.

File details

Details for the file ewatercycle_swmm-0.1.1-py2.py3-none-any.whl.

File metadata

File hashes

Hashes for ewatercycle_swmm-0.1.1-py2.py3-none-any.whl
Algorithm Hash digest
SHA256 da4fc4747e78ecbbfa0084f317b85f1defc6cf735c927a78f1012037bbcde430
MD5 5572aefc91b03c0a1b49f24a64dfa1c1
BLAKE2b-256 783ed91e20aa1e2925f6efbdf3fdbfbc8f714b872f17e2fbc87c84a27d107188

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 files

0.1.0

2 files

0.0.4

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page