pyswmm / Stormwater-Management-Model

PySWMM Stormwater Management Model repository
Other
99 stars 77 forks source link

Possible set start/end date calculation precision issue #405

Open bemcdonnell opened 6 months ago

bemcdonnell commented 6 months ago

This was reported by a pyswmm user. When we use the swmm_setSimulationDateTime SWMM recalculates the new StartDateTime and TotalDuration or EndDateTime and TotalDuration for the state and end times, respectively. When we launch into the simulation, and use PySWMM to print the sim.current_time during the sim.after_step callback, we find that if we use the start/end time setter, the model prints the last time step 1 second short. I ran a matrix of trials using pyswmm-v1.5.1 and pyswmm-v2 using the step_advance and not. I have 100% isolated it to when the start/end time setters are used. This isn't a huge concern but it's not perfect. :)

Archive.zip

In my model I have the following:

[OPTIONS]
;;Options            Value
;;------------------ ------------
FLOW_UNITS           MGD
INFILTRATION         HORTON
FLOW_ROUTING         DYNWAVE
START_DATE           10/20/2016
START_TIME           12:00:00
REPORT_START_DATE    10/20/2016
REPORT_START_TIME    12:00:00
END_DATE             10/21/2016
END_TIME             12:15:00

in the PySWMM code i have one run where I do not use the start/end time setter and the other uses the setter (to set the model to the same time as in the original model).

from datetime import datetime
import pyswmm

print("\n First Model \n")

with pyswmm.Simulation("SWMMExtCntrlModel.inp") as sim:
    sim.step_advance(4*3600)

    def time_step_print():
        print(sim.current_time)

    sim.add_after_step(time_step_print)
    for step in sim:
        pass

    time_step_print()

print("\n Second Model \n")

with pyswmm.Simulation("SWMMExtCntrlModel.inp") as sim:
    sim.start_time = datetime(2016, 10, 20, 12, 0, 0)
    sim.end_time = datetime(2016, 10, 21, 12, 15, 0)
    sim.step_advance(4*3600)

    def time_step_print():
        print(sim.current_time)

    sim.add_after_step(time_step_print)
    for step in sim:
        pass

    time_step_print()

The Output is as follows (pyswmm-v1.5.1)

 First Model 

2016-10-20 16:00:18
2016-10-20 20:00:29
2016-10-21 00:00:42
2016-10-21 04:00:45
2016-10-21 08:01:04
2016-10-21 12:01:14
2016-10-21 12:15:00
2016-10-21 12:15:00

 Second Model 

2016-10-20 16:00:18
2016-10-20 20:00:29
2016-10-21 00:00:42
2016-10-21 04:00:45
2016-10-21 08:01:04
2016-10-21 12:01:14
2016-10-21 12:14:59
2016-10-21 12:14:59

For pyswmm-v2

 First Model 

2016-10-20 16:00:00
2016-10-20 20:00:00
2016-10-21 00:00:00
2016-10-21 04:00:00
2016-10-21 08:00:00
2016-10-21 12:00:00
2016-10-21 12:15:00
2016-10-21 12:15:00

 Second Model 

2016-10-20 16:00:00
2016-10-20 20:00:00
2016-10-21 00:00:00
2016-10-21 04:00:00
2016-10-21 08:00:00
2016-10-21 12:00:00
2016-10-21 12:14:59
2016-10-21 12:14:59

If i add 1 second sim.end_time = datetime(2016, 10, 21, 12, 15, 1) here is the output:

 Second Model 

2016-10-20 16:00:00
2016-10-20 20:00:00
2016-10-21 00:00:00
2016-10-21 04:00:00
2016-10-21 08:00:00
2016-10-21 12:00:00
2016-10-21 12:15:01
2016-10-21 12:15:01