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.1.0.tar.gz (2.8 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.0-py2.py3-none-any.whl (7.2 kB view details)

Uploaded Python 2Python 3

File details

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

File metadata

  • Download URL: ewatercycle_swmm-0.1.0.tar.gz
  • Upload date:
  • Size: 2.8 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.1.0.tar.gz
Algorithm Hash digest
SHA256 3af303bad449c711bad6fd851560d3cc01fe92710de4487cda629d37ad45650d
MD5 f07f3c4450d84832858ac361e060e8b6
BLAKE2b-256 7df0cdfb23be5210b2ee1dfbec98ff684bb43860c3e94e33d54d60e445839ffe

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for ewatercycle_swmm-0.1.0-py2.py3-none-any.whl
Algorithm Hash digest
SHA256 ae76641ec7ed8fa6aaac8fc9dd2d71f7bb1b4878cdfac47296076efc2ddcf957
MD5 94b75a8f35c0e1e8ad42e21627418390
BLAKE2b-256 3391318669b20a72bf2eb198ab93863a60a43e1e3849dca0fd3e28b6b5f3ea6a

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