def fit_func(nest, My_Current_step, CONTROL_RULES, Current_States): sim = Simulation(r"./test.inp") Linkname = ["C1", "C2", "O1", "O2"] Nodename = ["St1", "St2", "J1", "J2"] links = Links(sim) nodes = Nodes(sim) t = 0 for link in Linkname: a2 = links[link] a2.initial_flow = Current_States[t][0] t = t + 1 for node in Nodename: a1 = nodes[node] a1.initial_depth = Current_States[t][0] t = t + 1 flood1 = np.array([]) flood2 = np.array([]) flood3 = np.array([]) flood4 = np.array([]) o1 = Links(sim)["O1"] o2 = Links(sim)["O2"] j1 = Nodes(sim)["J1"] j2 = Nodes(sim)["J2"] j3 = Nodes(sim)["St1"] j4 = Nodes(sim)["St2"] sim.start_time = my_Start_time + datetime.timedelta( minutes=My_timestep * (My_Current_step)) sim.end_time = my_Start_time + datetime.timedelta( minutes=My_timestep * (My_Current_step + HorizonLength + 1)) sim.step_advance(My_timestep * 60) CONTROL_RULES[My_Current_step:My_Current_step + HorizonLength] = nest.reshape([4, -1]) i = 0 for step in sim: o1.target_setting = CONTROL_RULES[i + My_Current_step][0] o2.target_setting = CONTROL_RULES[i + My_Current_step][1] i = i + 1 flood1 = np.append(flood1, [j1.flooding]) flood2 = np.append(flood2, [j2.flooding]) flood3 = np.append(flood3, [j3.flooding]) flood4 = np.append(flood4, [j4.flooding]) sim.close() return mytrape(flood1, 60 * My_timestep) + mytrape( flood2, 60 * My_timestep) + mytrape( flood3, 60 * My_timestep) + mytrape(flood4, 60 * My_timestep)
def test_simulation_iter(): with Simulation(MODEL_WEIR_SETTING_PATH) as sim: c1c2 = Links(sim)["C1:C2"] sim.step_advance(300) for ind, step in enumerate(sim): print(c1c2.flow, c1c2.target_setting) if c1c2.flow > 9.19: c1c2.target_setting = 0.9
def State_Update(CONTROL_RULES, Current_States, My_Current_step): sim = Simulation(r"./test.inp") Linkname = ["C1", "C2", "O1", "O2"] Nodename = ["St1", "St2", "J1", "J2"] links = Links(sim) nodes = Nodes(sim) o1 = Links(sim)["O1"] o2 = Links(sim)["O2"] t = 0 sim.start_time = my_Start_time + datetime.timedelta(minutes=My_timestep * (My_Current_step)) sim.end_time = my_Start_time + datetime.timedelta( minutes=My_timestep * (My_Current_step + HorizonLength + 1)) sim.step_advance(My_timestep * 60) for link in Linkname: a2 = links[link] a2.initial_flow = Current_States[t][0] t = t + 1 for node in Nodename: a1 = nodes[node] a1.initial_depth = Current_States[t][0] t = t + 1 i = 0 for step in sim: o1.target_setting = CONTROL_RULES[i + My_Current_step][0] o2.target_setting = CONTROL_RULES[i + My_Current_step][1] i = i + 1 t = 0 for link in Linkname: a2 = links[link] Current_States[t][0] = a2.flow t = t + 1 for node in Nodename: a1 = nodes[node] Current_States[t][0] = a1.depth t = t + 1 return Current_States
def test_links_1(): with Simulation(MODEL_WEIR_SETTING_PATH) as sim: print("\n\n\nLINKS\n") c1c2 = Links(sim)["C1:C2"] print(c1c2.flow) print(c1c2.is_conduit()) print(c1c2.is_pump()) print(c1c2.is_orifice()) print(c1c2.is_weir()) print(c1c2.is_outlet()) print(c1c2.connections) print(c1c2.inlet_node) print(c1c2.outlet_node) print(c1c2.average_head_loss) sim.step_advance(300) for ind, step in enumerate(sim): if c1c2.flow > 9.19: c1c2.target_setting = 0.9
def test_links_4(): with Simulation(MODEL_PUMP_SETTINGS_PATH) as sim: peak_pump_rate = 20 # cfs print("\n\n\nLINKS\n") c3 = Links(sim)["C3"] sim.step_advance(300) for ind, step in enumerate(sim): # setting adjustment if ind == 15: c3.target_setting = 0.9 if ind == 20: c3.target_setting = 0.8 if ind == 25: c3.target_setting = 0.7 if ind == 30: c3.target_setting = 0.6 if ind == 35: c3.target_setting = 2.0 if ind == 40: c3.target_setting = 0.4 if ind == 45: c3.target_setting = 0.3 if ind == 50: c3.target_setting = 0.2 if ind == 55: c3.target_setting = 0.1 if ind == 60: c3.target_setting = 0.0 if ind == 65: c3.target_setting = 1.0 # Check Results if ind == 16: assert (c3.target_setting == 0.9) assert (c3.flow == 0.9 * peak_pump_rate) if ind == 21: assert (c3.target_setting == 0.8) assert (c3.flow == 0.8 * peak_pump_rate) if ind == 26: assert (c3.target_setting == 0.7) assert (c3.flow == 0.7 * peak_pump_rate) if ind == 31: assert (c3.target_setting == 0.6) assert (c3.flow == 0.6 * peak_pump_rate) if ind == 36: assert (c3.target_setting == 2.0) assert (c3.flow >= peak_pump_rate) if ind == 41: assert (c3.target_setting == 0.4) assert (c3.flow == 0.4 * peak_pump_rate) if ind == 46: assert (c3.target_setting == 0.3) assert (c3.flow == 0.3 * peak_pump_rate) if ind == 51: assert (c3.target_setting == 0.2) assert (c3.flow == 0.2 * peak_pump_rate) if ind == 56: assert (c3.target_setting == 0.1) assert (c3.flow == 0.1 * peak_pump_rate) if ind == 61: assert (c3.target_setting == 0.0) assert (c3.flow == 0.0 * peak_pump_rate) if ind == 66: assert (c3.target_setting == 1.0) assert (c3.flow == 1.0 * peak_pump_rate)
def test_links_5(): with Simulation(MODEL_WEIR_SETTING_PATH) as sim: weir_pump_rate = 5 # cfs print("\n\n\nWEIR\n") c3 = Links(sim)["C3"] sim.step_advance(300) for ind, step in enumerate(sim): # setting adjustment if ind == 15: c3.target_setting = 0.9 if ind == 20: c3.target_setting = 0.8 if ind == 25: c3.target_setting = 0.7 if ind == 30: c3.target_setting = 0.6 if ind == 35: c3.target_setting = 0.5 if ind == 40: c3.target_setting = 0.4 if ind == 45: c3.target_setting = 0.3 if ind == 50: c3.target_setting = 0.2 if ind == 55: c3.target_setting = 0.1 if ind == 60: c3.target_setting = 0.0 if ind == 65: c3.target_setting = 1.0 # Check Results if ind == 16: assert (c3.target_setting == 0.9) assert (c3.flow >= 0.9 * weir_pump_rate) if ind == 21: assert (c3.target_setting == 0.8) assert (c3.flow >= 0.8 * weir_pump_rate) if ind == 26: assert (c3.target_setting == 0.7) assert (c3.flow >= 0.7 * weir_pump_rate) if ind == 31: assert (c3.target_setting == 0.6) assert (c3.flow >= 0.6 * weir_pump_rate) if ind == 36: assert (c3.target_setting == 0.5) assert (c3.flow >= 0.5 * weir_pump_rate) if ind == 41: assert (c3.target_setting == 0.4) assert (c3.flow >= 0.4 * weir_pump_rate) if ind == 46: assert (c3.target_setting == 0.3) assert (c3.flow >= 0.3 * weir_pump_rate) if ind == 51: assert (c3.target_setting == 0.2) assert (c3.flow >= 0.15 * weir_pump_rate) if ind == 56: assert (c3.target_setting == 0.1) assert (c3.flow >= 0.05 * weir_pump_rate) if ind == 61: assert (c3.target_setting == 0.0) assert (c3.flow == 0.0 * weir_pump_rate) if ind == 66: assert (c3.target_setting == 1.0) assert (c3.flow >= 1.0 * weir_pump_rate)
# Init sim count = 1 on_time = 0 total_count = 0 pump_reference_flow = 1 # [m^3/s] tank1.generated_inflow(2) for idx, step in enumerate(sim): # Make sure the system is always supplied with water # System identification setup: # # Outflow pump simple control in operating range: if tank2.depth > tank_offset + 1.5: pump2.target_setting = 1 * pump_reference_flow elif tank2.depth > tank_offset + 1.8: pump2.target_setting = 1.3 * pump_reference_flow elif tank2.depth < tank_offset + 0.2: pump2.target_setting = 0 # Create simple random controller if count > on_time: count = 0 on_time = random.randint(50, 100) pump1.target_setting = random.randint(0, 1) * pump_reference_flow # pump1.target_setting = random.uniform(0, 1)*pump_reference_flow # if tank2.depth > 0.9: # pump1.target_setting = 0 else: count += 1
Wt_fl = Wetland.flooding Wetland_floodingC.append(Wt_fl) Wt_of = Wetland.total_outflow Wetland_outflowC.append(DB_of) Wt_bp = Wtlnd_bypass.flow Wtlnd_bp_inflowsC.append(Wt_bp) Ch_f = Channel.flow Channel_flowC.append(Ch_f) Ch_d = Channel.depth Channel_depthC.append(Ch_d) # Wetland Control Actions (every 15 mins - 5 sec timesteps) if _tempcount == 180: # If wetland has capacity, slowly open both valves if Wt_d <= 9.5: Ells_valve.target_setting = min( 0.05, 70.6 / (np.sqrt(2.0 * 32.2 * Ell_d)) / 25) Wtlnd_valve.target_setting = min( 0.33, 70.6 / (np.sqrt(2.0 * 32.2 * Wt_d)) / 12.6) print("Ell and Wt cap, slow open both") # If wetland does not have capacity elif Wt_d > 9.5: # But Ellsworth does, close Ellsworth valve and slowly open Wetland valve if Ell_d <= 15: Ells_valve.target_setting = 0.0 Wtlnd_valve.target_setting = min( 0.33, 70.6 / (np.sqrt(2.0 * 32.2 * Wt_d)) / 12.6) print("Ell cap, Wt no cap, close Ell, slow open Wt") # If neither has capacity, slowly open both valves else: Ells_valve.target_setting = min( 0.05, 70.6 / (np.sqrt(2.0 * 32.2 * Ell_d)) / 25)
solver2.integrate(solver2.t + dt) solver3.set_initial_value(solver3.y, solver3.t) solver3.set_f_params(Wt_if, solver2.y, Wt_of, Wt_v, k_ni) solver3.integrate(solver3.t + dt) # Set new concentration sim._model.setNodePollutant("93-49759", 0, solver3.y[0]) # Wetland & Retention basin Control Actions (every 15 mins - 5 sec timesteps) if _tempcount == 180: # If DO level is not anoxic if DO_C > 1.0: # And if the wetland has capacity if Wt_d <= 9.5: # Close the wetland valve and proportionally open retention basin valve C = Qmax/(A*sqrt(2*g*d)) Wtlnd_valve.target_setting = 0.0 RB_valve.target_setting = 1.75 * ( 70.6 / (np.sqrt(2 * 32.2 * RB_d) * 78.5)) else: # If not, open the wetland valve and close the RBasin valve Wtlnd_valve.target_setting = 1.75 * ( 70.6 / (np.sqrt(2 * 32.2 * Wt_d) * 12.6)) RB_valve.target_setting = 0.0 # If DO level is anoxic elif DO_C <= 1.0: # And if the wetland NO concentration is low, open both valves proportionally if solver3.y[0] <= 5.0: Wtlnd_valve.target_setting = 1.75 * ( 70.6 / (np.sqrt(2 * 32.2 * Wt_d) * 12.6)) RB_valve.target_setting = 1.75 * ( 70.6 / (np.sqrt(2 * 32.2 * RB_d) * 78.5))
DB_d = Doyle_Basin.depth Doyle_Basin_depth.append(DB_d) DB_of = Doyle_Basin.total_outflow Doyle_Basin_outflow.append(DB_if) Wt_if = Wetland.total_inflow Wetland_inflow.append(Wt_if) Wt_d = Wetland.depth Wetland_depth.append(Wt_d) Wt_of = Wetland.total_outflow Wetland_outflow.append(DB_of) # Wetland Control Actions (every 30 mins) if _tempcount == 30: # If depth <= 6.75 ft then close valve if depth <= 6.75: Wtlnd_valve.target_setting = 0.0 # Proportional release but no more than 33% open else: Wtlnd_valve.target_setting = min( 0.33, Wt_of / (1.00 * np.sqrt(2.0 * 32.2 * Wt_d))) Wetland_valve.append(Wtlnd_valve.target_setting) # Ellsworth Control Actions (every 30 mins) # Proportional release after 36 hours if _time <= 2160: if _tempcount == 30: # If concentration >= 20 or depth <= 15 close valve if Ell_p >= 20.0 or Ell_d <= 15.0: Ells_valve.target_setting = 0.0 else: # Else proportional release but no more than 33% open
overflow_SU11 = [] outflow_SU11 = [] TSS_SU11 = [] # Create a empty list of current running step time step_time = [] #### Loop the simulation for each eclipse step and get the output for each defined variable for step in enumerate(sim): #get the current sim time and append time to an array dt = sim.current_time timearray = dt.strftime('%Y.%m.%d.%H.%M') step_time.append(timearray) # Append the time-series data to orifice and storage #Adjust the orifice OR48 setting based on the controller function orifice_OR48.target_setting = controller_1(storage_SU7.depth) #Get the orifice OR48 setting setting_OR48.append(orifice_OR48.target_setting) #Get the link flow for orifice OR48 flow_OR48.append(orifice_OR48.flow) #Get the nodal depth for storage unit SU7 depth_SU7.append(storage_SU7.depth) #Get the nodal inflow for each storage unit SU7 inflow_SU7.append(storage_SU7.total_inflow) #Get nodal overflow the SU7 which is equal to flooding overflow_SU7.append(storage_SU7.flooding) #Get nodal outflow for SU7 which can be obtain by( j1.total_outflow )function.outflow equals to the sum of connected orifice flow and nodal overflow outflow_SU7.append(storage_SU7.total_outflow) #Get the nodal TSS for SU7 TSS_SU7.append(storage_SU7.pollut_conc) #print("\t\t\t\torifice OR48 Setting: {:.2f} {}".format( \
def test_links_4(): with Simulation(MODEL_PUMP_SETTINGS_PATH) as sim: peak_pump_rate = 20 #cfs print("\n\n\nLINKS\n") c3 = Links(sim)["C3"] sim.step_advance(300) for ind, step in enumerate(sim): #setting adjustment if ind == 15: c3.target_setting = 0.9 if ind == 20: c3.target_setting = 0.8 if ind == 25: c3.target_setting = 0.7 if ind == 30: c3.target_setting = 0.6 if ind == 35: c3.target_setting = 2.0 if ind == 40: c3.target_setting = 0.4 if ind == 45: c3.target_setting = 0.3 if ind == 50: c3.target_setting = 0.2 if ind == 55: c3.target_setting = 0.1 if ind == 60: c3.target_setting = 0.0 if ind == 65: c3.target_setting = 1.0 #Check Results if ind == 16: assert (c3.target_setting == 0.9) assert (c3.flow == 0.9 * peak_pump_rate) if ind == 21: assert (c3.target_setting == 0.8) assert (c3.flow == 0.8 * peak_pump_rate) if ind == 26: assert (c3.target_setting == 0.7) assert (c3.flow == 0.7 * peak_pump_rate) if ind == 31: assert (c3.target_setting == 0.6) assert (c3.flow == 0.6 * peak_pump_rate) if ind == 36: assert (c3.target_setting == 2.0) assert (c3.flow >= peak_pump_rate) if ind == 41: assert (c3.target_setting == 0.4) assert (c3.flow == 0.4 * peak_pump_rate) if ind == 46: assert (c3.target_setting == 0.3) assert (c3.flow == 0.3 * peak_pump_rate) if ind == 51: assert (c3.target_setting == 0.2) assert (c3.flow == 0.2 * peak_pump_rate) if ind == 56: assert (c3.target_setting == 0.1) assert (c3.flow == 0.1 * peak_pump_rate) if ind == 61: assert (c3.target_setting == 0.0) assert (c3.flow == 0.0 * peak_pump_rate) if ind == 66: assert (c3.target_setting == 1.0) assert (c3.flow == 1.0 * peak_pump_rate)
def test_links_5(): with Simulation(MODEL_WEIR_SETTING_PATH) as sim: weir_pump_rate = 5 #cfs print("\n\n\nWEIR\n") c3 = Links(sim)["C3"] sim.step_advance(300) for ind, step in enumerate(sim): #setting adjustment if ind == 15: c3.target_setting = 0.9 if ind == 20: c3.target_setting = 0.8 if ind == 25: c3.target_setting = 0.7 if ind == 30: c3.target_setting = 0.6 if ind == 35: c3.target_setting = 0.5 if ind == 40: c3.target_setting = 0.4 if ind == 45: c3.target_setting = 0.3 if ind == 50: c3.target_setting = 0.2 if ind == 55: c3.target_setting = 0.1 if ind == 60: c3.target_setting = 0.0 if ind == 65: c3.target_setting = 1.0 #Check Results if ind == 16: assert (c3.target_setting == 0.9) assert (c3.flow >= 0.9 * weir_pump_rate) if ind == 21: assert (c3.target_setting == 0.8) assert (c3.flow >= 0.8 * weir_pump_rate) if ind == 26: assert (c3.target_setting == 0.7) assert (c3.flow >= 0.7 * weir_pump_rate) if ind == 31: assert (c3.target_setting == 0.6) assert (c3.flow >= 0.6 * weir_pump_rate) if ind == 36: assert (c3.target_setting == 0.5) assert (c3.flow >= 0.5 * weir_pump_rate) if ind == 41: assert (c3.target_setting == 0.4) assert (c3.flow >= 0.4 * weir_pump_rate) if ind == 46: assert (c3.target_setting == 0.3) assert (c3.flow >= 0.3 * weir_pump_rate) if ind == 51: assert (c3.target_setting == 0.2) assert (c3.flow >= 0.15 * weir_pump_rate) if ind == 56: assert (c3.target_setting == 0.1) assert (c3.flow >= 0.05 * weir_pump_rate) if ind == 61: assert (c3.target_setting == 0.0) assert (c3.flow == 0.0 * weir_pump_rate) if ind == 66: assert (c3.target_setting == 1.0) assert (c3.flow >= 1.0 * weir_pump_rate)
def run_local_model_simulation(time_step, sim, pump_ids, tank_ids, junction_ids, network_df, disturb_manager, num_sim_steps): pump1 = Links(sim)[pump_ids[0]] pump2 = Links(sim)[pump_ids[1]] tank1 = Nodes(sim)[tank_ids[0]] tank2 = Nodes(sim)[tank_ids[1]] disturb_pump = Links(sim)[pump_ids[2]] junction_n1 = Nodes(sim)[junction_ids[0]] junction_n2 = Nodes(sim)[junction_ids[1]] junction_n3 = Nodes(sim)[junction_ids[2]] junction_n4 = Nodes(sim)[junction_ids[3]] junction_n5 = Nodes(sim)[junction_ids[4]] network_elements = { "tank1_depth": tank1.depth, "tank1_volume": tank1.volume, "tank1_flooding": tank1.flooding, "tank1_inflow": tank1.total_inflow, "tank2_depth": tank2.depth, "tank2_volume": tank2.volume, "tank2_flooding": tank2.flooding, "tank2_inflow": tank2.total_inflow, "junction_n1_depth": junction_n1.depth, "junction_n2_depth": junction_n2.depth, "junction_n3_depth": junction_n3.depth, "junction_n4_depth": junction_n4.depth, "junction_n5_depth": junction_n5.depth, "pump1_flow": pump1.flow, "pump1_current_setting": pump1.current_setting, "pump1_target_setting": pump1.target_setting, "pump2_flow": pump2.flow, "pump2_current_setting": pump2.current_setting, "pump2_target_setting": pump2.target_setting, "disturbance": 0 } # start the simulation with the pumps closed # https://pyswmm.readthedocs.io/en/stable/reference/nodes.html # use these functions to set how much the pump is open for pump1.target_setting = PumpSetting.CLOSED.value pump2.target_setting = PumpSetting.CLOSED.value for idx, step in enumerate(sim): current_disturb = disturb_manager.get_k_disturbance(idx, 1) disturb_pump.target_setting = current_disturb network_df = network_df.append(network_elements, ignore_index=True) if num_sim_steps <= 0: user_key_input = input("Press any key to step, or q to quit") try: num_sim_steps = int(user_key_input) except ValueError: pass if user_key_input == "q": break else: # print(num_sim_steps) num_sim_steps -= 1 pump1.target_setting = local_controller(tank1, "t1", min_depth_tank=0.1) pump2.target_setting = local_controller(tank2, "t2", min_depth_tank=0.1) sim.step_advance(time_step) network_elements = { "tank1_depth": tank1.depth, "tank1_volume": tank1.volume, "tank1_flooding": tank1.flooding, "tank1_inflow": tank1.total_inflow, "tank2_depth": tank2.depth, "tank2_volume": tank2.volume, "tank2_flooding": tank2.flooding, "tank2_inflow": tank2.total_inflow, "junction_n1_depth": junction_n1.depth, "junction_n2_depth": junction_n2.depth, "junction_n3_depth": junction_n3.depth, "junction_n4_depth": junction_n4.depth, "junction_n5_depth": junction_n5.depth, "pump1_flow": pump1.flow, "pump1_current_setting": pump1.current_setting, "pump1_target_setting": pump1.target_setting, "pump2_flow": pump2.flow, "pump2_current_setting": pump2.current_setting, "pump2_target_setting": pump2.target_setting, "disturbance": float(current_disturb[0]) } return network_df
overflow_SU11 = [] outflow_SU11 = [] TSS_SU11 = [] #Create a empty list of current running step time step_time = [] #### Loop the simulation for each eclipse step and get the output for each defined variable for step in enumerate(sim): #get the current sim time and append time to an array dt = sim.current_time timearray = dt.strftime('%Y.%m.%d.%H.%M') step_time.append(timearray) # Append the time-series data to orifice and storage #Adjust the orifice OR48 setting based on the controller function orifice_OR48.target_setting = controller_1(storage_SU7.depth) #Get the orifice OR48 setting setting_OR48.append(orifice_OR48.target_setting) #Get the link flow for orifice OR48 flow_OR48.append(orifice_OR48.flow) #Get the nodal depth for storage unit SU7 depth_SU7.append(storage_SU7.depth) #Get the nodal inflow for each storage unit SU7 inflow_SU7.append(storage_SU7.total_inflow) #Get nodal overflow the SU7 which is equal to flooding overflow_SU7.append(storage_SU7.flooding) #Get nodal outflow for SU7 which can be obtain by( j1.total_outflow )function.outflow equals to the sum of connected orifice flow and nodal overflow outflow_SU7.append(storage_SU7.total_outflow) #Get the nodal TSS for SU7 TSS_SU7.append(storage_SU7.pollut_conc) #print("\t\t\t\torifice OR48 Setting: {:.2f} {}".format( \
pipe2 = Links(sim)["P2"] node3 = Nodes(sim)["N3"] pipe3 = Links(sim)["P3"] pipe4 = Links(sim)["P4"] tank2 = Nodes(sim)["T2"] # Init sim tank_area = 200 count = 1 on_time = 0 total_count = 0 pump_reference_flow = 1 / 5 lateral_inflow = 1 / 15 for idx, step in enumerate(sim): # Make sure the system is always supplied with water pump3.target_setting = 5 node3.generated_inflow(lateral_inflow) # System identification setup: if tank2.depth > 0.7: pump2.target_setting = 1 * pump_reference_flow elif tank2.depth > 0.9: pump2.target_setting = 1.3 * pump_reference_flow elif tank2.depth < 0.1: pump2.target_setting = 0 # Create simple random controller if count > on_time: count = 0 on_time = random.randint(5, 15) pump1.target_setting = random.uniform(0, 1) * pump_reference_flow
def run_euler_model_simulation(time_step, complete_model, prediction_horizon, sim, pump_ids, tank_ids, junction_ids, network_df, disturb_manager, num_sim_steps, steps_between_plots): pump1 = Links(sim)[pump_ids[0]] pump2 = Links(sim)[pump_ids[1]] tank1 = Nodes(sim)[tank_ids[0]] tank2 = Nodes(sim)[tank_ids[1]] disturb_pump = Links(sim)[pump_ids[2]] junction_n1 = Nodes(sim)[junction_ids[0]] junction_n2 = Nodes(sim)[junction_ids[1]] junction_n3 = Nodes(sim)[junction_ids[2]] junction_n4 = Nodes(sim)[junction_ids[3]] junction_n5 = Nodes(sim)[junction_ids[4]] network_elements = { "tank1_depth": tank1.depth, "tank1_volume": tank1.volume, "tank1_flooding": tank1.flooding, "tank1_inflow": tank1.total_inflow, "tank2_depth": tank2.depth, "tank2_volume": tank2.volume, "tank2_flooding": tank2.flooding, "tank2_inflow": tank2.total_inflow, "junction_n1_depth": junction_n1.depth, "junction_n2_depth": junction_n2.depth, "junction_n3_depth": junction_n3.depth, "junction_n4_depth": junction_n4.depth, "junction_n5_depth": junction_n5.depth, "pump1_flow": pump1.flow, "pump1_current_setting": pump1.current_setting, "pump1_target_setting": pump1.target_setting, "pump2_flow": pump2.flow, "pump2_current_setting": pump2.current_setting, "pump2_target_setting": pump2.target_setting } mpc_model = complete_model["mpc_model"] # start the simulation with the pumps closed # https://pyswmm.readthedocs.io/en/stable/reference/nodes.html # use these functions to set how much the pump is open for pump1.target_setting = PumpSetting.CLOSED.value pump2.target_setting = PumpSetting.CLOSED.value # x initial conditions states = [ tank1.initial_depth, junction_n1.initial_depth, junction_n2.initial_depth, junction_n3.initial_depth, junction_n4.initial_depth, junction_n5.initial_depth, tank2.initial_depth ] # u_prev, initial control input control_input = ca.DM.zeros(complete_model["num_inputs"], 1) # zeros for now # TODO: make sure to add a proper reference ref = set_euler_ref(prediction_horizon, complete_model["num_states"]) # To make the simulation precise, # make sure that the flow metrics are in Cubic Meters per Second [CMS] for idx, step in enumerate(sim): future_delta_disturb = disturb_manager.get_k_delta_disturbance( idx, prediction_horizon) prev_disturb = disturb_manager.get_k_disturbance(idx - 1, 1) current_disturb = disturb_manager.get_k_disturbance(idx, 1) disturb_pump.target_setting = current_disturb network_df = network_df.append(network_elements, ignore_index=True) if num_sim_steps <= 0: if idx % steps_between_plots == 0: mpc_model.plot_progress(ignore_states={2, 3, 4}, options={'drawU': 'U'}) user_key_input = input("Press any key to step, or q to quit") try: num_sim_steps = int(user_key_input) except ValueError: pass if user_key_input == "q": break else: print(num_sim_steps) num_sim_steps -= 1 mpc_model.step(states, control_input, disturbance=future_delta_disturb, prev_disturbance=prev_disturb) control_input = control_input + mpc_model.get_next_control_input_change( ) pump1.target_setting = control_input[0] pump2.target_setting = control_input[1] sim.step_advance(time_step) # tank1.depth, hp1.depth, hp2.depth ... hp5.depth, tank2.depth # this here is a python stl list, you cannot subtract like this safely states = [ tank1.depth, junction_n1.depth, junction_n2.depth, junction_n3.depth, junction_n4.depth, junction_n5.depth, tank2.depth ] network_elements = { "tank1_depth": tank1.depth, "tank1_volume": tank1.volume, "tank1_flooding": tank1.flooding, "tank1_inflow": tank1.total_inflow, "tank2_depth": tank2.depth, "tank2_volume": tank2.volume, "tank2_flooding": tank2.flooding, "tank2_inflow": tank2.total_inflow, "junction_n1_depth": junction_n1.depth, "junction_n2_depth": junction_n2.depth, "junction_n3_depth": junction_n3.depth, "junction_n4_depth": junction_n4.depth, "junction_n5_depth": junction_n5.depth, "pump1_flow": pump1.flow, "pump1_current_setting": pump1.current_setting, "pump1_target_setting": pump1.target_setting, "pump2_flow": pump2.flow, "pump2_current_setting": pump2.current_setting, "pump2_target_setting": pump2.target_setting, "disturbance": float(current_disturb[0]) } return network_df
k_ni3 = 0.000006 else: k_ni3 = 0.0 k_ni = k_ni1 + k_ni2 + k_ni3 Wetland_DO1C.append(DO1) Wetland_DO2C.append(DO2) Wetland_DO3C.append(DO3) t+=1 # Wetland Control Actions (every 15 mins) if _tempcount == 15: # If DO levels above anoxic condition: if (DO1 or DO2 or DO3) > 1.0: # And if Wetland depth <= 6.75 ft then close valve if Wt_d <= 6.75: Wtlnd_valve.target_setting = 0.0 # Else proportional release but no more than 33% open else: Wtlnd_valve.target_setting = min(0.50, 0.05*np.sqrt(2.0*32.2*Wt_d)) # Else proportional release but no more than 33% open else: Wtlnd_valve.target_setting = min(0.50, 0.05*np.sqrt(2.0*32.2*Wt_d)) #Wtlnd_valve.target_setting = min(0.25, 0.05*np.sqrt(2.0*32.2*Wt_d)) Wetland_valveC.append(Wtlnd_valve.target_setting) # Ellsworth Control Actions (every 15 mins) if _tempcount == 15: # If Ellsworth TSS conc < 20 if Ell_p > 20.0: