kLabUM / StormReactor

StormReactor: Python package for modeling any pollutant generation or removal method in SWMM
GNU Lesser General Public License v3.0
25 stars 7 forks source link

Add Exception if user is using sim.step_advance() feature in PySWMM #10

Closed bemcdonnell closed 1 year ago

bemcdonnell commented 1 year ago

@bemason, I ran a quick test this morning and we might need to plan some swmm-level changes in the implementation of this feature. Just so I am clear, this is not what I would consider a bug! There is just a small limitation on how you can use this with PySWMM as of today.

PySWMM has a feature called sim.step_advance() which allows the user to establish the approximate frequency in which we interact with the running simulation. In the case of how we are accessing (particularly "setting") the pollut attributes in SWMM, in its current form we are required to force set these values on each "routing" step. When using sim.step_advnace(), we are have a longer "stride" between our routing steps and I am wondering if maybe the code isn't correctly modifying the mass.

I ran a couple tests to help illustrate this. What I found was as follows: testing_step_Advance

Used this code:

'''
PySWMM and StormReactor Code Example A
Author: Brooke Mason
Version: 1
Date: December 21, 2022
'''
# Import libraries
from pyswmm import Simulation, Nodes
from StormReactor import waterQuality
import matplotlib.pyplot as plt

# Define water quality configuration dictionary
config = {'17': {'type': 'node', 'pollutant': 'TSS', 'method': 'EventMeanConc', 'parameters': {'C': 50.0}}}

fig = plt.figure(figsize=(11,8))

trial_step = [False, 150, 300]

for ind, step_advance in enumerate(trial_step):
    ax = fig.add_subplot(len(trial_step),1,ind+1)
    # Create lists to save TSS results
    UpstreamNode_TSS = []
    WQNode_TSS = []
    OutfallNode_TSS = []
    # Initalize SWMM simulation
    with Simulation(r'Example1_WQ.inp') as sim:
        # Node information
        UpstreamNode = Nodes(sim)['24']
        WQNode = Nodes(sim)['17']
        OutfallNode = Nodes(sim)['18']
        # Initialize StormReactor
        WQ = waterQuality(sim, config)
        sim.step_advance(step_advance)
        # Launch a simulation
        for step in sim:
            # Update water quality each simulation step
            WQ.updateWQState()
            # Get and save TSS concentrations
            UpstreamNode_TSS.append(UpstreamNode.pollut_quality['TSS'])
            WQNode_TSS.append(WQNode.pollut_quality['TSS'])
            OutfallNode_TSS.append(OutfallNode.pollut_quality['TSS'])

    # Plot TSS concentrations
    ax.plot(UpstreamNode_TSS, ':', label="Upstream Node")
    ax.plot(WQNode_TSS, '-', label="WQ Node")
    ax.plot(OutfallNode_TSS, '--',label="Outfall")
    ax.set_ylabel("TSS (mg/L)")
    if ind == 0:
        ax.set_title("without sim.step_advance()")
        ax.legend()

    if ind >= 1:
        ax.set_title("with pyswmm - sim.step_advance({}) #seconds".format(step_advance))
    if ind == len(trial_step):
        ax.set_xlabel("Time")

fig.tight_layout()
plt.savefig("testing_step_Advance.png")

I will submit quick PR to at least throw the Exception if the user tries to use a different sim.step_advance(). We can talk about other strategies to update this.