Monday, December 30, 2024

PYSWMM lidgroups.py Summary

 Below is an extended summary of this code, focusing on its structure, overarching purpose, and how each class interacts with SWMM’s LID (Low Impact Development) units at the subcatchment level.


Overview

This module manages LID (Low Impact Development) usage across subcatchments within a SWMM model. It introduces several Pythonic classes (LidGroups, LidGroup, LidUnit) that encapsulate SWMM’s underlying LID usage data, allowing users to retrieve, iterate over, and dynamically adjust LID parameters during a simulation. This higher-level interface is part of PySWMM and relies on lower-level calls to the SWMM toolkit.

Key Capabilities:

  1. Iterate Over LID Usage: Provide loops and lookups to access all subcatchments with defined LIDs.
  2. Access/Modify LID Units: Change certain LID parameters (e.g., area, drain node) before or even during a simulation.
  3. Retrieve Real-Time Results: Get time-varying flow components (e.g., drain flow, infiltration, evaporation) from each LID unit during or after a simulation.

Core Classes

1. LidGroups

  • Purpose: Acts as a container/iterator for all subcatchment-level LID groups. Since every subcatchment can define one or more LID units, each subcatchment effectively “has” one LidGroup instance.
  • Initialization:
    lid_groups = LidGroups(sim)
    
    • Ensures that the SWMM model is open (fileLoaded == True).
  • Iteration (__iter__, __next__, __getitem__):
    • Each iteration yields a LidGroup object representing the LID usage in a single subcatchment.
    • len(lid_groups) returns the total number of subcatchments, which is also the number of lid groups (even if some subcatchments have 0 LID units).
    • lid_groups[some_subcatch_id] returns a LidGroup for that subcatchment.
  • Example:
    for lid_group in LidGroups(sim):
        print(lid_group)  # Prints the subcatchment name
    

2. LidGroup

  • Purpose: Represents all LID units defined within a specific subcatchment.
  • Initialization:
    lid_group = LidGroup(model, "SubcatchID")
    
    • Checks that the subcatchment ID is valid in the SWMM model.
  • Iteration:
    • Each iteration yields a LidUnit object.
    • len(lid_group) returns how many LID units are defined on this subcatchment.
    • lid_group[i] retrieves the LidUnit at index i.
  • LID Group-Level Results:
    • pervious_area: Amount of pervious area within this subcatchment influenced by LID(s).
    • flow_to_pervious: How much LID outflow is sent to pervious surfaces.
    • old_drain_flow, new_drain_flow: Drain flow from the previous/current simulation step, aggregated for all LID units in this subcatchment.
  • Example:
    lid_group_j1_j3 = LidGroups(sim)["J1_J3_qqqqqqq"]
    lid_unit0 = lid_group_j1_j3[0]  # Access the first LID unit in subcatchment "J1_J3_qqqqqqq"
    

3. LidUnit

  • Purpose: Encapsulates a single LID usage instance within a subcatchment. For example, if a subcatchment has two “permeable pavement” LIDs, you can differentiate them via their indexes in the LidGroup.
  • Initialization:
    lid_unit = LidUnit(model, "SubcatchID", lid_index)
    
    • lid_index is the 0-based index referencing a particular LID usage record in SWMM.
  • Sub-Components / Layers:
    • surface, pavement, soil, storage: Each of these returns a specialized class (Surface, Pavement, Soil, Storage) that manages layer-specific parameters (e.g., thickness, porosity, infiltration rates).
    • water_balance: Summarizes infiltration, evaporation, drain flow, etc.
  • Parameters (via @property):
    • Physical Properties
      • unit_area, full_width
      • initial_saturation: how saturated the LID’s layers are at simulation start
      • from_impervious, from_pervious: fraction of drainage area from impervious/pervious surfaces directed to this LID unit
    • Connections
      • index, number, to_pervious: references to how many units are replicated, whether outflow is sent to a pervious area, etc.
      • drain_subcatchment, drain_node: IDs or indices specifying where the LID’s underdrain flow is routed (another subcatchment or a node).
    • Runtime Results
      • dry_time: time since last rainfall event (seconds)
      • old_drain_flow, new_drain_flow: drain flows at previous and current timestep.
      • evaporation, native_infiltration: real-time infiltration and evaporation rates.
  • Modifiability:
    • Some parameters can only be changed before a simulation (e.g., unit area, number of replicate units).
    • Others (like drain_node) can be changed during a simulation, enabling real-time control.

Typical Usage Examples

A. Iterating Through All LID Groups and Units

from pyswmm import Simulation, LidGroups

with Simulation('lid_model.inp') as sim:
    for lid_group in LidGroups(sim):
        print("Subcatchment with LID usage:", lid_group)

        for lid_unit in lid_group:
            print("  LID Unit Index:", lid_unit.index)
            print("  LID Area:", lid_unit.unit_area)

B. Changing Drain Node Mid-Simulation

from pyswmm import Simulation, LidGroups

with Simulation('lid_model.inp') as sim:
    lid_group_s1 = LidGroups(sim)['S1']
    lid_unit0 = lid_group_s1[0]

    for step_index, step_time in enumerate(sim):
        # After 50 simulation steps, reroute drain flow to node "J04"
        if step_index == 50:
            lid_unit0.drain_node = "J04"

C. Retrieving LID Performance Data

from pyswmm import Simulation, LidGroups

with Simulation('lid_model.inp') as sim:
    lid_group_s1 = LidGroups(sim)['S1']
    lid_unit0 = lid_group_s1[0]

    for step in sim:
        # Access water balance layer
        wb = lid_unit0.water_balance
        print("Inflow:", wb.inflow)
        print("Drain Flow:", wb.drain_flow)

Architectural Notes

  1. Integration with PySWMM:

    • The classes in this file build on top of the lower-level toolkitapi and the pyswmm.swmm5 interface.
    • They rely on numeric SWMM parameters, object indices, and enumerations for LID usage (LidUParams, LidUOptions, etc.).
  2. Error Handling:

    • Custom exceptions (PYSWMMException) are raised if invalid IDs or indexes are used, or if the SWMM model is not open.
  3. Consistency and Scalability:

    • Each subcatchment is associated with exactly one LidGroup, even if that group has zero or multiple LID units.
    • The iteration pattern (__iter__, __next__) is consistent with Python best practices, allowing convenient loops over items.
  4. Runtime Flexibility:

    • Because certain LID parameters can be adjusted mid-simulation, PySWMM opens the door to advanced real-time control scenarios, such as changing how water is routed or adjusting infiltration settings based on ongoing conditions.

Conclusion

This code provides a high-level, object-oriented interface for managing and querying SWMM’s LID usage data at both subcatchment and individual LID levels. By encapsulating complex details into easy-to-use classes and properties, PySWMM empowers users to:

  • Enumerate and manage LID groups across all subcatchments,
  • Modify LID unit parameters (e.g., drain nodes, area, infiltration) before or during a run,
  • Examine real-time or post-run data (flow rates, infiltration, evaporation) for each LID unit.

This design greatly simplifies typical LID modeling and real-time control workflows, making sophisticated water management strategies more accessible to practitioners and researchers alike.

No comments:

A comprehensive explanation of how minimum travel distance relates to link length in InfoSewer

In hydraulic modeling of sewer networks, the minimum travel distance is a fundamental parameter that affects how accurately the model can si...