Skip to main content

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 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.

Project details


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.0.4.tar.gz (3.0 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.0.4-py2.py3-none-any.whl (7.3 kB view details)

Uploaded Python 2Python 3

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

Hashes for ewatercycle_swmm-0.0.4.tar.gz
Algorithm Hash digest
SHA256 04b0130703bba3abfe5d698d426b511e48c8f5045f8d8e060796dc2150aa5e26
MD5 82fa0bc5d28f7bf218f4b443c01aa560
BLAKE2b-256 a615ba3afbaa0bb293f8645c7c8373b67eae68f2bb5a822d050868952663def5

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for ewatercycle_swmm-0.0.4-py2.py3-none-any.whl
Algorithm Hash digest
SHA256 7063517951b148609143e4e9a21064698602d8214b7d1f4e1c0e18c1da23dbee
MD5 96cb7a05543cb9338bde961ac21bebc3
BLAKE2b-256 08a99a32814bab3db66cb1e37bd0caadd57e9c1196498130d2013d8959ae128f

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page