Below is an extended summary of the code, highlighting its purpose, key components, and how it fits into a broader PySWMM workflow.
Overview
This module expands upon PySWMM’s functionality by introducing higher-level classes to manage SWMM (Storm Water Management Model) simulations. Specifically, it provides a new Simulation
class (and a complementary SimulationPreConfig
class) that streamline how users can configure, run, and interact with SWMM simulations in Python. It also includes safety mechanisms and convenience features like callback registration and multi-simulation guards.
The primary class—Simulation
—is designed to handle everything from opening a SWMM model and iterating through time steps, to finalizing and closing the model. Additionally, the module addresses real-time simulation control, hotstart file usage, and advanced model editing capabilities via a SimulationPreConfig
class.
Core Classes
1. _SimulationStateManager
- Purpose: Maintains a global state to ensure only one SWMM simulation instance is active at a time in a given Python process.
- Why: USEPA-SWMM isn’t thread-safe or reentrant, so multiple concurrent SWMM instances can cause crashes or data corruption.
- Usage: When a
Simulation
is instantiated,_SimulationStateManager
is used to guard against a second simulation being opened concurrently.
2. Simulation
Purpose
- Wraps the lower-level
PySWMM
class to provide a more intuitive, Pythonic interface for setting up, running, and finalizing a SWMM simulation. - Supports context-manager usage (
with Simulation(...) as sim:
) to automatically handle opening and closing.
Key Attributes
_model
: An instance ofPySWMM
that manages the actual SWMM engine calls (opening files, stepping through time, closing)._is_open
: Indicates if the SWMM model is currently open._is_started
: Tracks whether the simulation has started stepping through time._advance_seconds
: If set, the simulation will “stride” in user-defined increments rather than at every SWMM routing step._terminate_request
: A flag to gracefully stop the simulation loop when conditions are met (e.g., flooding threshold)._callbacks
: A dictionary of callbacks (function hooks) that can be invoked at various simulation events (e.g., before start, after step, after close).
Core Methods
-
__init__
- Manages opening the input file via
PySWMM
and ensures single-instance constraints via_SimulationStateManager
. - Optionally uses a
SimulationPreConfig
object (if provided) to apply dynamic changes to the SWMM input file.
- Manages opening the input file via
-
Context Management:
__enter__
: Enters the context, disabling a warning about context usage.__exit__
: Completes the simulation if it hasn’t ended, closes the SWMM file, and triggers “after_close” callbacks.
-
Iteration:
__iter__
and__next__
:- Allows Python’s
for step in sim:
pattern. - Calls
swmm_step
orswmm_stride
until the simulation ends or a termination is requested. - Handles pre-step and post-step callbacks.
- Allows Python’s
-
Simulation Lifecycle:
start()
: Officially starts the simulation in manual stepping mode, calling any “before_start”/“after_start” callbacks.execute()
: Runs the simulation in a single call (no stepping iteration). This is a simpler approach but prevents interactive changes mid-run.
-
Callbacks:
- Provides methods like
add_before_start
,add_after_start
,add_before_step
,add_after_step
,add_before_end
,add_after_end
, andadd_after_close
. - Each accepts a callable that’s triggered at that point in the simulation lifecycle.
- Provides methods like
-
Hotstart File Support:
use_hotstart(file)
: Load a hotstart file at the beginning of the simulation.save_hotstart(file)
: Save the current state mid-run for later usage or branching scenarios.
-
Runoff/Routing/Quality Error Tracking:
- Properties like
runoff_error
,flow_routing_error
,quality_error
return mass balance error percentages at the end of a run.
- Properties like
-
Time Controls:
- Properties like
start_time
,end_time
, andreport_start
allow dynamic read/write of the SWMM simulation’s time boundaries. current_time
returns the current simulation time at each iteration.percent_complete
estimates progress by comparingcurrent_time
tostart_time
andend_time
.
- Properties like
-
Other Features:
terminate_simulation()
: Gracefully requests a simulation stop.report()
: Writes final report file data.
3. SimulationPreConfig
Purpose
- Allows a user to programmatically modify a SWMM input file prior to running the simulation.
- Useful for batch processing, scenario testing, or automated parameter calibration.
- Can handle changes like subcatchment property adjustments, timeseries data updates, or other
[SECTION]
manipulations.
Workflow:
- Add Updates:
add_update_by_token(section, obj_id, index, new_val, row_num=0)
- Defines a single change to apply to the input file at a specific row and column (parameter index).
- Example: Changing a subcatchment’s outlet from “J1” to “J2.”
- Apply Changes:
apply_changes()
reads the original.inp
file, edits the specified lines, and writes out a new.inp
with a customizable suffix.- The resulting file is used by the
Simulation
object if passed tosim_preconfig
.
Typical Usage Patterns
A. Simple Simulation with Context Manager
from pyswmm import Simulation
with Simulation('model.inp') as sim:
for step in sim:
# Access real-time data or adjust parameters
pass
B. Manual Execution
sim = Simulation('model.inp')
sim.execute() # Runs start -> simulation -> end -> close
C. Using Callbacks
def print_time():
print("Current time:", sim.current_time)
with Simulation('model.inp') as sim:
sim.add_before_step(print_time)
for step in sim:
pass
D. Applying Pre-Run Modifications
from pyswmm import Simulation, SimulationPreConfig
preconf = SimulationPreConfig()
preconf.add_update_by_token("SUBCATCHMENTS", "S1", 2, "J2") # E.g., change the outlet
with Simulation('model.inp', sim_preconfig=preconf) as sim:
for step in sim:
# The sim runs with a newly saved "model_mod.inp"
pass
Key Benefits
-
Thread-Safety and Single-Instance Guard:
_SimulationStateManager
ensures that even novice users don’t inadvertently run multiple SWMM instances simultaneously.
-
Callbacks:
- Flexible insertion points for user-defined functions at each major lifecycle stage (before/after start, each step, end, close).
-
Hotstart Integration:
- Simplifies saving/loading intermediate states for subsequent runs or scenario branching.
-
Programmatic Pre-Configuration:
SimulationPreConfig
eliminates manual editing of.inp
files, enabling rapid scenario testing or parameter updates.
-
Seamless Scripting:
- The context-manager approach (
with Simulation(...) as sim:
) handles cleanup automatically, preventing accidental resource leaks and ensuring complete finalization.
- The context-manager approach (
Conclusion
Overall, this module substantially enhances the user experience for running SWMM simulations in Python. It offers:
- Robust lifecycle management (open, iterate, close).
- Convenient callback hooks for real-time control or logging.
- Safeguards against common misuse (like multiple simulations at once).
- Dynamic model editing (
SimulationPreConfig
) for advanced scenario setups.
Thus, it provides a powerful foundation for developing interactive, automation-friendly SWMM workflows in Python, from simple one-shot runs to complex real-time control and calibration tasks.
No comments:
Post a Comment