External inflows#
Note
Engine: OpenSWMM 6 — refactored. Documents
openswmm.engine.Inflows.
The Inflows class registers static external inflows on nodes
at configure time:
External inflows — time-series flow with optional scale/baseline.
Dry-Weather Flow (DWF) — average flow with up to 4 multiplicative patterns (monthly / daily / hourly / weekend).
Rainfall-Dependent Inflow & Infiltration (RDII) — driven by a unit hydrograph attached to a sewershed area, with optional exponential initial-abstraction decay (
[RDII_DECAY]).Unit-hydrograph definitions (``[HYDROGRAPHS]``) — UH parameter rows, gage bindings, and group metadata.
For overrides applied during a running simulation (per-step
lateral inflows), see Nodes.set_lateral_inflow (one-shot)
or Forcing.node_lat_inflow (persistent).
Reference: openswmm_inflows.h.
Class signature#
class Inflows:
def __init__(self, solver: Solver) -> None: ...
Key methods#
External inflows (time-series)#
Method |
Action / returns |
|---|---|
|
Attach a time-series-driven inflow to a node. |
|
Number of registered external inflows. |
constituent—"FLOW"for hydraulic flow, or a pollutant ID for a water-quality inflow.ts_name— name of the driving time series (empty string for baseline-only).type— inflow-type string (default"FLOW").m_factor— units-conversion multiplier.s_factor— scaling factor.baseline— baseline value added on top of the time series.pattern— optional pattern name multiplying the baseline.
Dry-Weather Flow#
Method |
Action / returns |
|---|---|
|
Attach DWF with up to 4 multiplicative patterns. |
|
Number of registered DWF entries. |
constituent—"FLOW"or a pollutant ID.avg_value— average dry-weather flow.pat1/pat2/pat3/pat4— monthly / daily / hourly / weekend pattern names. Pass an empty string to skip a slot.
RDII#
Method |
Action / returns |
|---|---|
|
Attach RDII at a node, driven by a named unit hydrograph and sewershed area. |
|
Read back the |
|
Number of registered RDII entries. |
Unit hydrographs ([HYDROGRAPHS])#
The unit-hydrograph parameter table feeds the RDII model. Each row
defines the shape parameters (r, t, k) and initial-
abstraction defaults for a (uh_name, month, response) combination.
Method |
Action / returns |
|---|---|
|
Add a |
|
Read back a parameter row / count rows. |
|
Bind a rain-gage to a unit-hydrograph group. |
|
Counts for gage bindings and unique UH group names. |
|
Return the name of the idx-th UH group. |
Exponential IA decay ([RDII_DECAY])#
The exponential initial-abstraction decay model replaces the legacy
linear-recovery formulation for storm-by-storm IA bookkeeping.
Depletion follows exp(-k_dep * rainfall); recovery during dry
periods uses k_rec(T) = k_0 + k_T * exp(theta_rec * (T - T_ref))
with suppression when T <= T_freeze.
Method |
Action / returns |
|---|---|
|
Add an exponential-decay row for a |
|
Read back a decay row / count rows. |
End-to-end example#
from openswmm.engine import Solver, Inflows, Nodes, EngineState
with Solver("site_drainage.inp", "site_drainage.rpt", "site_drainage.out") as s:
nodes = Nodes(s)
inflows = Inflows(s)
node_idx = nodes.get_index("J1")
# Attach a flow time series to J1 (during model edit phase, before initialize)
s.open()
inflows.add_external(
node_idx=node_idx,
constituent="FLOW", # hydraulic flow
ts_name="WET_WEATHER_TS", # named time series
m_factor=1.0, # no unit conversion
s_factor=1.0, # no scaling
baseline=0.05, # cfs baseline
)
s.initialize()
s.start()
while s.state == EngineState.RUNNING:
if s.step() != 0:
break
s.end()
print(f"External inflows registered: {inflows.ext_inflow_count()}")
Common recipes#
Add Dry-Weather Flow with monthly + daily + hourly patterns#
inflows.add_dwf(
node_idx=nodes.get_index("J1"),
constituent="FLOW",
avg_value=0.5, # average DWF
pat1="MONTHLY_PATTERN",
pat2="DAILY_PATTERN",
pat3="HOURLY_PATTERN",
# pat4 unset -- no weekend override
)
Add RDII to a node#
inflows.add_rdii(
node_idx=nodes.get_index("J1"),
uh_name="UH1", # unit hydrograph defined in [HYDROGRAPHS]
area=12.5, # sewershed area
)
Define a unit hydrograph and exponential-decay row#
# Build a fresh UH group for the medium-response component
inflows.add_hydrograph(
uh_name="UH1",
month=-1, # all months
response=1, # MEDIUM
r=0.05, t=2.0, k=2.0,
dmax=0.2, drecov=0.0, dinit=0.0,
)
# Bind the gage that drives this UH group
inflows.add_hydrograph_gage("UH1", "RG1")
# Replace legacy linear IA recovery with the exponential model
inflows.add_rdii_decay(
uh_name="UH1",
response=1, # MEDIUM
k_dep=0.5, # depletion rate per inch of rain
k_0=0.01, # base recovery (1/hr)
k_T=0.005, # thermal recovery at T_ref (1/hr)
T_ref=10.0, # deg C
theta_rec=0.05,
T_freeze=0.0,
)
Combine baseline + scaling for unit conversion#
# Time series in m³/s, model in CFS:
inflows.add_external(
node_idx=nodes.get_index("J1"),
constituent="FLOW",
ts_name="INFLOW_M3S",
m_factor=35.3147, # m³/s → cfs
s_factor=1.0,
baseline=0.0,
)
Bulk arrays#
The Inflows class is a registration surface, not a per-step
data accessor. For per-step inflow values, use
Nodes.get_lateral_inflow() (per-node) or OutputReader
post-run (Output reader (binary .out file)).
EngineState requirements & exceptions#
Method group |
Required state |
Notes |
|---|---|---|
registration setters ( |
|
Must be done before |
count accessors |
|
n/a |
Common EngineError codes:
INVALID_INDEX— node index out of range.INVALID_TYPE— pollutant constituent given for a non-quality model.NOT_FOUND—ts_name,pattern,uh_nameorgage_namedoes not exist in the model.
See also#
Advanced forcing — runtime overrides that bypass the registered inflows.
Tables (time series, curves, patterns) — define the time series and patterns that drive inflows.
Nodes — observe the inflow state during the run.