Esempio n. 1
0
def simulation_drainage(year, weatherforecast_kind,
                        weatherforecast_accumulationtime,
                        weatherforecast_updatesteps, penetration_rate,
                        control_type, number_simulation, original_swmm_file,
                        irrigation_start, irrigation_end, classification):
    startTime = dt.datetime.now()

    if control_type == 'smart':
        smart = True
    elif control_type == 'uncontrolled':
        smart = False
    else:
        print('usage control type: "uncontrolled" or "smart"')
        sys.exit(1)

    #input variable runoff coefficient
    runoff_coefficient = 0.95

    #input variable max garden area
    max_garden = 25

    #created variables
    analysetime = pd.to_datetime('{}.{}.{}'.format(irrigation_start[1],
                                                   irrigation_start[0], year),
                                 format='%d.%m.%Y')
    endtime = pd.to_datetime('{}.{}.{}'.format(irrigation_end[1],
                                               irrigation_end[0], year),
                             format='%d.%m.%Y')

    #created file names
    name = original_swmm_file[:-4] + '_{}_{}_{}_{}_{}_{}'.format(
        year, weatherforecast_kind, weatherforecast_accumulationtime,
        penetration_rate, control_type, number_simulation)
    swmm_file = name + '.inp'
    json_file = name + '.json'

    #create swmm input file
    f = open(original_swmm_file)  #read in
    success, val = read_write_swmm.swmm_input_read(f)

    if not success:
        print(val)
        sys.exit(1)

    houses_implementation_RBs, val, rain_barrel_total_volume = implement_LIDs.implementation(
        val, penetration_rate, max_garden, '_H_',
        classification)  #implementation of SRBs
    val = modify_swmm_input.change_parameters(val, analysetime, endtime,
                                              'rain{}.dat'.format(year))

    #print((houses_implementation_RBs))

    f = open(swmm_file, 'w')
    read_write_swmm.swmm_input_write(f, val)
    f.close()

    #set initial values - needed for simulation
    newday = analysetime
    irrigation_time = analysetime + pd.Timedelta(seconds=84600)
    ct_old = analysetime - pd.Timedelta(seconds=60)

    irrigation = False

    number_rain_barrels = len(houses_implementation_RBs)
    houses_lid_parameters = {}
    rainbarrels_control_states = {}

    # set final results
    rainbarrels_results = {}
    water_demand_supply = {}
    water_harvesting = {}
    system_results = {}

    #read in temperature
    if os.name == 'nt':
        temperature_path = 'weather\\temperature_{}.csv'.format(year)
    else:
        temperature_path = 'weather/temperature_{}.csv'.format(year)
    Temperature_mean, Temperature_max, Temperature_min = calculate_irrigation_demand.read_in_temperature(
        temperature_path)

    #read in weather forecast
    if os.name == 'nt':
        forecast_path = 'weather\\rain_forecast_{}_{}.csv'.format(
            year, weatherforecast_kind)
    else:
        forecast_path = 'weather/rain_forecast_{}_{}.csv'.format(
            year, weatherforecast_kind)
    weatherforecast = weather_forecast.read_in_weather_forecast(forecast_path)

    with pyswmm.Simulation(swmm_file) as sim:
        system_stats = pyswmm.SystemStats(sim)  #get system stats (rainfall)

        for n in range(number_rain_barrels):
            houses_lid_parameters[houses_implementation_RBs[n][
                0]] = houses_implementation_RBs[n][1:], pyswmm.LidGroups(sim)[
                    houses_implementation_RBs[n][0]][0], pyswmm.LidControls(
                        sim)[houses_implementation_RBs[n][3]]
            rainbarrels_control_states[houses_implementation_RBs[n][0]] = [
                0, 0, False, False, False, 0, 0
            ]
            rainbarrels_results[houses_implementation_RBs[n][0]] = [
                0, 0, 0, 0, 0
            ]
            water_demand_supply[houses_implementation_RBs[n][0]] = {}
            water_harvesting[houses_implementation_RBs[n][0]] = {}

        for step in sim:
            ct = sim.current_time  # current SWMM simulation time

            future_rainfall = False
            start_irrigation = False
            #print(ct)

            #daily control rules
            if ct >= newday:
                irrigation = irrigation_start <= (
                    newday.month, newday.day
                ) <= irrigation_end  #check if actual day is in irrigation period
                newday_timestamp = newday  #necessary for function irrigation_need and to find daily aggregated values in Temperature
                rain_day_beginning = system_stats.runoff_stats[
                    'rainfall']  #get rainfall amount at beginning of the day [mm]
                newday += pd.Timedelta(days=1)
                #print(ct)

            #smart - get rain prediction for specific analysetime
            if smart and ct >= analysetime:
                weatherforecast_analysetime = weatherforecast.loc[
                    analysetime,
                    '900':str(weatherforecast_accumulationtime
                              )]  #get weatherforecast specific analysetime
                weatherforecast_sum = sum(
                    weatherforecast_analysetime
                )  #get rainsum of choosen analysetime
                if weatherforecast_sum > 0:
                    future_rainfall = True
                    future_rain_sum = weatherforecast_sum * runoff_coefficient  #calculate effictive rainfall [mm]
                    previous_rain_sum = system_stats.runoff_stats[
                        'rainfall']  #get previous rainsum (rainsum is accumulated over simulation time)

                analysetime += pd.Timedelta(
                    seconds=weatherforecast_updatesteps)  #set new analysetime

            #calculate at irrigation demand at end of day - EN16941-1 (2018) EN 16941-1 On-site non-potable water systems.
            if ct > irrigation_time and irrigation:  #set end of day for irrigation
                crop_evapotranspiration_ref = calculate_irrigation_demand.EH0(
                    newday_timestamp, Temperature_max.loc[newday_timestamp,
                                                          'degC'],
                    Temperature_min.loc[newday_timestamp, 'degC'],
                    Temperature_mean.loc[newday_timestamp, 'degC']
                )  #get necessary irrigation demand based on daily temperature
                rain_day = system_stats.runoff_stats[
                    'rainfall'] - rain_day_beginning  #get daily rainfall
                absolut_evapotranspiration = max(
                    crop_evapotranspiration_ref - rain_day,
                    0) / 1000  #calculate irrigation demand [m3/m2]
                start_irrigation = True
                irrigation_time += pd.Timedelta(days=1)

            for subcatchment_name, (
                (House_area, green_area, RB_name, RainBarrel_volume,
                 RainBarrel_hight, RainBarrel_area,
                 Rain_Barrel_DrainageCoefficient), RainBarrel,
                    RainBarrel_control) in houses_lid_parameters.items():
                RainBarrel_storage_old, RainBarrel_irrigation_goal, irrigation_on, rain_on, storm_on, closing_time, water_age_old = rainbarrels_control_states[
                    subcatchment_name]
                irrigation_demand_overall, water_saving, water_detention, number_operations, water_age = rainbarrels_results[
                    subcatchment_name]

                RainBarrel_storage = RainBarrel.storage.depth / 1000 * RainBarrel_area  #[m3] get actual storage volume
                RainBarrel_available_storage = (
                    RainBarrel_volume - RainBarrel_storage
                )  #[m3] calclate available storage volume

                #smart and future_rainfall -> open rainbarrel
                if smart and future_rainfall:
                    future_outflow_house = future_rain_sum / 1000 * House_area * 10000
                    if future_outflow_house > RainBarrel_available_storage and future_outflow_house < RainBarrel_volume and RainBarrel_storage > 0.001:  #if predicted rainfall is higher than storage volume but less than rainbarrel volume
                        RainBarrel_control.drain.coefficient = Rain_Barrel_DrainageCoefficient  #open valve = set drainage coefficient
                        rain_on = True  #only open valve at analysetime
                        number_operations += 1  #count opening operations
                    if future_outflow_house > RainBarrel_volume:
                        max_intensity_lead_time = weatherforecast_analysetime.idxmax(
                        )  #get max intensity time
                        temp_time = max_intensity_lead_time
                        closing_time_RainBarrel = weatherforecast_analysetime.name + pd.Timedelta(
                            seconds=int(temp_time)) - pd.Timedelta(seconds=900)

                        if RainBarrel_storage > 0.001 and not storm_on:  #or not rain_sum_to_max_intensity == 0:
                            storm_on = True  #only open valve at analysetime
                            number_operations += 1  #count opening operations
                            RainBarrel_control.drain.coefficient = Rain_Barrel_DrainageCoefficient  #open valve = set drainage coefficient

                #irrigation time -> open rainbarrel
                if start_irrigation:
                    irrigation_demand = absolut_evapotranspiration * green_area
                    if irrigation_demand < RainBarrel_storage and irrigation_demand > 0:  #calcluate usable water for irrigation inside storage layer
                        water_usable = irrigation_demand
                        water_needed = 0
                        irrigation_on = True  #start irrigation
                    elif irrigation_demand > RainBarrel_storage and irrigation_demand > 0 and RainBarrel_storage > 0.001:
                        water_usable = RainBarrel_storage
                        water_needed = irrigation_demand - water_usable
                        irrigation_on = True  #start irrigation
                    else:
                        water_usable = 0
                        water_needed = irrigation_demand

                    if irrigation_on:  #start irrigation
                        RainBarrel.drain_node = 'Irrigation'  #set outflow node
                        RainBarrel_control.drain.coefficient = Rain_Barrel_DrainageCoefficient  #open valve = set draiange coefficient
                        RainBarrel_irrigation_goal = RainBarrel.water_balance.drain_flow + water_usable / RainBarrel_area * 1000  #calculate final outflow irrigation (RainBarrel_size is because of mm)
                        water_saving += water_usable  #calculate total water savings
                        number_operations += 1  #count opening operations

                    irrigation_demand_overall += irrigation_demand  #calculate total irrigation demand
                    water_demand_supply[subcatchment_name].update(
                        {str(newday_timestamp):
                         water_needed})  #get water demand for water supply
                    water_harvesting[subcatchment_name].update(
                        {str(newday_timestamp):
                         water_usable})  #get amout of water harvesting

                #calculate detention_volume during irrigation period
                if irrigation:  #only when irrigation time (21. March to 23. September)
                    water_detention += max(
                        RainBarrel_storage - RainBarrel_storage_old,
                        0)  #calculate total detention volume

                #calculate water_age
                if RainBarrel_storage > 0.001:  #only if storage > 1l
                    time_delta = pd.Timedelta(
                        ct - ct_old
                    ).seconds / 3600  #get time difference between routing time steps
                    water_age_actual = (
                        (water_age_old + time_delta) *
                        (RainBarrel_storage_old -
                         RainBarrel.new_drain_flow * time_delta * 3600 / 1000)
                    ) / RainBarrel_storage  #calculate actual water age
                else:
                    water_age_actual = 0
                water_age = max(water_age,
                                water_age_actual)  #set max water age

                #control rules every SWMM Step
                if irrigation_on:  #control rules for irrigation
                    if RainBarrel.water_balance.drain_flow >= RainBarrel_irrigation_goal or RainBarrel_storage < 0.001:  #either irrigation demand or minimum water level reached
                        irrigation_on = False  #stop irrigation process
                        RainBarrel_control.drain.coefficient = 0  #close valve - set drainage coefficient = 0
                        RainBarrel.drain_node = -1  #set outflow node
                if not irrigation_on and rain_on:  #control rules for rainfall lower than rain barrel volume
                    future_rain_storage = (
                        max(
                            future_rain_sum -
                            (system_stats.runoff_stats['rainfall'] -
                             previous_rain_sum), 0)
                    ) / 1000 * House_area * 10000  #calcute actuell rain storage volume
                    if future_rain_storage < RainBarrel_available_storage:  #if enough volume is available
                        rain_on = False  #stop emptying
                        RainBarrel_control.drain.coefficient = 0  #close valve = set drainage coefficient = 0
                if not irrigation_on and storm_on:
                    if ct >= closing_time_RainBarrel:
                        storm_on = False  #close valve
                        RainBarrel_control.drain.coefficient = 0  #close valve = set drainage coefficient = 0

                #set new list values
                RainBarrel_storage_old = RainBarrel_storage

                rainbarrels_control_states[subcatchment_name] = [
                    RainBarrel_storage_old, RainBarrel_irrigation_goal,
                    irrigation_on, rain_on, storm_on, closing_time,
                    water_age_actual
                ]
                rainbarrels_results[subcatchment_name] = [
                    irrigation_demand_overall, water_saving, water_detention,
                    number_operations, water_age
                ]

            #set old control step
            ct_old = ct

        #system states
        #flooding
        flooding_volume = 0
        number_nodes = 0
        flooding_nodes = {}
        for node in pyswmm.Nodes(sim):
            flooding_volume += node.statistics['flooding_volume']
            number_nodes += 1
            flooding_nodes.update(
                {node.nodeid: node.statistics['flooding_volume']})

        #outflows
        outflow_irrigation = pyswmm.Nodes(sim)['Irrigation'].cumulative_inflow
        outflow_mixed_overflox = pyswmm.Nodes(sim)['CSO'].cumulative_inflow
        outflow_wastewater_treatmentplant = pyswmm.Nodes(
            sim)['treatment_plant'].cumulative_inflow

        system_results = [
            number_nodes, flooding_volume, outflow_irrigation,
            outflow_mixed_overflox, outflow_wastewater_treatmentplant
        ]

    total_results = {}
    total_results['volume'] = [rain_barrel_total_volume]
    total_results['rainbarrels_results'] = [rainbarrels_results]
    total_results['water_demand_supply'] = [water_demand_supply]
    total_results['water_harvesting'] = [water_harvesting]
    total_results['system_results'] = [system_results]
    total_results['flooding_node'] = [flooding_nodes]

    results_json = json.dumps(total_results)
    f = open('results/{}'.format(json_file), "w")
    f.write(results_json)
    f.close()

    #print(dt.datetime.now()-startTime)

    os.remove(name + '.rpt')  #delete report file
    os.remove(name + '.out')  #delete out file
    os.remove(swmm_file)  #delete swmm file
Esempio n. 2
0
import sys
import pyswmm

try:
    pyswmm.Simulation('')
except pyswmm.swmm5.SWMMException:
    pass
Esempio n. 3
0
def swmm_simulate(inpFile, simulationStartTime, simulationEndTime, 
                  selected_nodes = list(), selected_links = list(), selected_subcatchments = list(), 
                  output_time_step = 300, add_and_remove_hotstart_period = False, hotstart_period_h = 5):

    import numpy as np
    import pyswmm
    import datetime
    from dateutil.relativedelta import relativedelta
 
    
    # import pdb
    # pdb.set_trace()
    # create time objects in Python
    simulationStartTime = datetime.datetime.strptime(simulationStartTime,"%Y-%m-%d %H:%M").replace(tzinfo=datetime.timezone.utc)
    simulationStartTime -= datetime.timedelta(seconds=output_time_step) # subtract one time step from the start time - otherwise the first time is a bit late
    simulationEndTime  =  datetime.datetime.strptime(simulationEndTime,"%Y-%m-%d %H:%M").replace(tzinfo=datetime.timezone.utc)

    ## Allocate space in arrays for storing the results later 
    # we allocate a 10\% more of space just in case after the simulation it is freed...
    expected_timeseries_length = int(np.ceil(1.1*(simulationEndTime - simulationStartTime).total_seconds()/output_time_step))
    # "ynode" is a dict with time series for the specified points of interest
    output_dict = {}
    output_dict["time"] = [datetime.datetime.now() for i in range(expected_timeseries_length)]
    for node in selected_nodes:
        output_dict[node] = np.zeros(expected_timeseries_length)
    for link in selected_links:
        output_dict[link] = np.zeros(expected_timeseries_length)
    for subcatchment in selected_subcatchments:
        output_dict[subcatchment] = np.zeros(expected_timeseries_length)
    
    
    # define which time steps to tell the user how far the simulation has come
    message_at_step = (np.linspace(0.25,0.75,num=3) * ((expected_timeseries_length/1.1) + hotstart_period_h*60/(output_time_step/60))).round()
    
    
    with pyswmm.Simulation(inpFile) as sim:
        # preparing the settings for the simulation like start and end time
        sim.start_time = simulationStartTime
        sim.end_time = simulationEndTime
        sim.step_advance(output_time_step)
        
        # if it has been selected that a "transient period" should be added in front the of the event that is simulated, then we add it here
        if add_and_remove_hotstart_period: 
            sim.start_time = simulationStartTime - relativedelta(hours=hotstart_period_h)
            #Afterwards do not register the hotstart_period_h first hours!!!
    
        if len(selected_nodes)>0:
            l_node=[]
            allNodes = pyswmm.Nodes(sim)
            for node in selected_nodes:    
                l_node.append(allNodes[node])
    
        if len(selected_links)>0:
            allLinks = pyswmm.Links(sim)
            l_link=[]
            for link in selected_links:
                l_link.append(allLinks[link])
    
        if len(selected_subcatchments)>0:
            allSubcatchments = pyswmm.Subcatchments(sim)
            l_subcatchment=[]
            for subcatchment in selected_subcatchments:
                l_subcatchment.append(allSubcatchments[subcatchment])
        
        print("Simulation has started...")
        # run the model by moving one time step forward in time
        #nstep_hotstart = 0 # counter for number of time steps in the hotstart
        nstep = 0 # counter for the number of time steps in the model simulation
        message_step = 0
        for step in sim:
            tt = sim.current_time.replace(tzinfo=datetime.timezone.utc)
            #nstep_hotstart += 1
            message_step += 1
            if (tt-simulationStartTime).total_seconds() >= 0:   
                output_dict["time"][nstep] = tt.replace(tzinfo=datetime.timezone.utc) # save the time stamps for each time step
                
                for index, node in enumerate(selected_nodes):
                    output_dict[node][nstep] = l_node[index].depth # save the values for all the variables of interest
    
                for index, link in enumerate(selected_links):
                     output_dict[link][nstep] = l_link[index].flow
                
                for index, subcatchment in enumerate(selected_subcatchments):
                     output_dict[subcatchment][nstep]  = l_subcatchment[index].runoff
                
                nstep += 1 # increase the counter for the number of time steps
                
            if np.isin(message_step, message_at_step):
                print("Percent completed: " + str(round(sim.percent_complete*100)))
    
    # cut off the space that was intentionally allocated too much
    output_dict["time"] = output_dict["time"][:nstep] # there are only "nstep" number of time steps
    for i in output_dict:
        output_dict[i] = output_dict[i][:nstep]
    
    print("Simulation finished !!!!")
    return(output_dict)
Esempio n. 4
0
#PySWMM test code

import pyswmm as ps  # import package

sim = ps.Simulation(
    'tutorial1.inp')  # load & run simulation with no interaction
sim.execute()

with ps.Simulation('tutorial1.inp'
                   ) as sim:  # load and run simulation and print each timestep
    for step in sim:
        print(sim.current_time)
    sim.report()
Esempio n. 5
0
def swmm_model_inventory(inpFile):
    import pandas as pd
    import pyswmm

    node_id_list = list()
    junction_list = list()
    outfall_list = list()
    storage_list = list()

    link_id_list = list()
    connections_list = list()
    conduit_list = list()
    orifice_list = list()
    outlet_list = list()
    pump_list = list()
    weir_list = list()

    raingauge_id_list = list()

    subcatchment_id_list = list()
    subcatchment_connection_list = list()

    with pyswmm.Simulation(inpFile) as sim:
        allNodes = pyswmm.Nodes(sim)
        for node in allNodes:
            node_id_list.append(node.nodeid)
            #temp_node = pyswmm.Nodes(sim)[node_list[i]]
            junction_list.append(node.is_junction())
            outfall_list.append(node.is_outfall())
            storage_list.append(node.is_storage())

        allLinks = pyswmm.Links(sim)
        for link in allLinks:
            link_id_list.append(link.linkid)
            connections_list.append(link.connections)
            conduit_list.append(link.is_conduit())
            orifice_list.append(link.is_orifice())
            outlet_list.append(link.is_outlet())
            pump_list.append(link.is_pump())
            weir_list.append(link.is_weir())

        allRainGauges = pyswmm.RainGages(sim)
        for rg in allRainGauges:
            raingauge_id_list.append(rg.raingageid)

        allSubcatchments = pyswmm.Subcatchments(sim)
        for subcatchment in allSubcatchments:
            subcatchment_id_list.append(subcatchment.subcatchmentid)
            subcatchment_connection_list.append(subcatchment.connection)

    #node_type = ["" for x in range(len(node_id_list))]
    nodes_overview = pd.DataFrame({
        "id":
        node_id_list,
        "type": ["" for x in range(len(node_id_list))]
    })
    nodes_overview.loc[junction_list, "type"] = "junction"
    nodes_overview.loc[outfall_list, "type"] = "outfall"
    nodes_overview.loc[storage_list, "type"] = "storage"

    #links_type = ["" for x in range(len(link_id_list))]
    links_overview = pd.DataFrame({
        "id":
        link_id_list,
        "type": ["" for x in range(len(link_id_list))],
        "upstream_node":
        [connections_list[x][0] for x in range(len(connections_list))],
        "downstream_node":
        [connections_list[x][1] for x in range(len(connections_list))]
    })
    links_overview.loc[conduit_list, "type"] = "conduit"
    links_overview.loc[orifice_list, "type"] = "orifice"
    links_overview.loc[outlet_list, "type"] = "outlet"
    links_overview.loc[pump_list, "type"] = "pump"
    links_overview.loc[weir_list, "type"] = "weir"

    subcatchments_overview = pd.DataFrame({
        "id":
        subcatchment_id_list,
        "connection_node": [
            subcatchment_connection_list[x][1]
            for x in range(len(subcatchment_connection_list))
        ]
    })

    return (nodes_overview, links_overview, subcatchments_overview,
            raingauge_id_list)