def constraint_checker(diameter_array, min_pre, min_vel, max_vel, file, num_nodes, num_links, num_pipes): # reconstruct .inp file from diameter array and store it as a temp file for pipe in range(len(diameter_array)): if diameter_array[pipe] > 0: ep.ENsetlinkvalue(pipe + 1, 0, diameter_array[pipe]) ep.ENsaveinpfile(file) ep.ENopenH() ep.ENinitH() ep.ENrunH() # initialize an array of nodal heads head_array = np.zeros(num_nodes) # initialize an array of pipe velocities velocity_array = np.zeros(num_links) fail_pressure_list = [] fail_min_vel_list = [] fail_max_vel_list = [] negative_diameter_list = [] fail_pressure = False fail_min_vel = False fail_max_vel = False negative_diameter = False for node in range(num_nodes): if ep.ENgetnodevalue(node + 1, 11) < min_pre and ep.ENgetnodetype(node + 1) == 0: fail_pressure_list.append(node) fail_pressure = True for pipe in range(num_pipes): if ep.ENgetlinkvalue(pipe + 1, 9) < min_vel: fail_min_vel_list.append(pipe) fail_min_vel = True elif ep.ENgetlinkvalue(pipe + 1, 9) > max_vel: fail_max_vel_list.append(pipe) fail_max_vel = True i = 0 for diameter in diameter_array: i += 1 if diameter <= 0: negative_diameter_list.append(i) negative_diameter = True print('Fail pressure list (nodes):', fail_pressure_list) print('Lower than min velocity list (links):', fail_min_vel_list) print('Higher than max velocity list (links):', fail_max_vel_list) if fail_pressure or fail_min_vel or fail_max_vel or negative_diameter: return False else: return True
def HydrantRating(MyNode, Demands): #Open the EPANET toolkit & hydraulics solver em.ENopen("example2.inp", "example2.rpt") em.ENopenH() # Get the index of the node of interest nodeindex = em.ENgetnodeindex(MyNode) rating = [] # Iterate over all demands for dem in Demands: em.ENsetnodevalue(nodeindex, em.EN_BASEDEMAND, dem) em.ENinitH(em.EN_NOSAVE) em.ENrunH() pressure = em.ENgetnodevalue(nodeindex, em.EN_PRESSURE) rating.append(pressure) # Close hydraulics solver & toolkit */ em.ENcloseH() em.ENclose() return rating
def simulation_supply(year, weatherforecast_kind, weatherforecast_accumulationtime, penetration_rate, control_type, number_simulation, original_epanet_file, original_swmm_file, irrigation_start, irrigation_end): #created file names name = original_epanet_file[:-4] + '_{}_{}_{}_{}_{}_{}'.format(year, weatherforecast_kind, weatherforecast_accumulationtime, penetration_rate, control_type, number_simulation) epanet_file = name + '.inp' epanet_report_file = name + '.rpt' json_file_drainage = original_swmm_file[:-4] + '_{}_{}_{}_{}_{}_{}.json'.format(year, weatherforecast_kind, weatherforecast_accumulationtime, penetration_rate, control_type, number_simulation) json_file = name + '.json' #read in results from urban drainage simulation with open('results/{}'.format(json_file_drainage)) as myfile: data = json.load(myfile) water_demand_supply = data['water_demand_supply'][0] water_harvesting = data['water_harvesting'][0] #read in classifcation houses to junctions if os.name == 'nt': classification_path = 'water\\Classification_Houses_Junctions.csv' else: classification_path = 'water/Classification_Houses_Junctions.csv' classification = pd.read_csv(classification_path, sep=';', header=None, names=['PropertyID','JunctionID']) classification.set_index('PropertyID',inplace=True) #read in daily weather data if os.name == 'nt': daily_weather_path = 'weather\\weather_daily_2015.csv' else: daily_weather_path = 'weather/weather_daily_2015.csv' daily_weather = pd.read_csv(daily_weather_path, sep=';', header=0) daily_weather['Date'] = pd.to_datetime(daily_weather['Date'], format='%d.%m.%Y') daily_weather.set_index('Date', inplace=True) #set irrigation period start_irrigation = pd.to_datetime('{}.{}.{}'.format(irrigation_start[1], irrigation_start[0], year), format='%d.%m.%Y') end_irrigation = pd.to_datetime('{}.{}.{}'.format(irrigation_end[1], irrigation_end[0], year), format='%d.%m.%Y') + pd.Timedelta(hours = 23) duration = end_irrigation - start_irrigation hours = int(duration.days * 24 + (duration.seconds/3600)) #set daily demand pattern patterns = {} patterns['March'] = [0.40, 0.30, 0.15, 0.10, 0.15, 0.50, 1.00, 1.50, 1.60, 1.50, 1.30, 1.20, 1.30, 1.20, 1.15, 1.20, 1.20, 1.40, 1.60, 1.50, 1.20, 1.05, 0.90, 0.60] patterns['April'] = [0.35, 0.20, 0.20, 0.20, 0.35, 0.70, 1.20, 1.40, 1.40, 1.30, 1.25, 1.20, 1.30, 1.20, 1.25, 1.25, 1.45, 1.70, 1.60, 1.30, 1.10, 0.95, 0.70, 0.45] patterns['May'] = [0.40, 0.30, 0.30, 0.30, 0.40, 0.85, 1.25, 1.35, 1.30, 1.25, 1.20, 1.15, 1.25, 1.20, 1.15, 1.25, 1.40, 1.65, 1.50, 1.30, 1.15, 0.95, 0.70, 0.45] patterns['June'] = [0.45, 0.45, 0.40, 0.40, 0.40, 0.80, 1.25, 1.40, 1.30, 1.25, 1.15, 1.15, 1.20, 1.20, 1.15, 1.15, 1.30, 1.60, 1.55, 1.30, 1.10, 0.90, 0.70, 0.45] patterns['July'] = [0.40, 0.40, 0.30, 0.30, 0.40, 0.80, 1.20, 1.45, 1.35, 1.25, 1.20, 1.25, 1.20, 1.15, 1.05, 1.15, 1.30, 1.60, 1.50, 1.30, 1.15, 1.05, 0.80, 0.45] patterns['August'] = [0.30, 0.20, 0.15, 0.20, 0.35, 0.70, 1.30, 1.50, 1.45, 1.40, 1.25, 1.25, 1.20, 1.15, 1.05, 1.15, 1.40, 1.70, 1.60, 1.35, 1.15, 1.00, 0.75, 0.45] patterns['September'] = [0.30, 0.20, 0.15, 0.15, 0.30, 0.75, 1.35, 1.55, 1.50, 1.35, 1.25, 1.20, 1.25, 1.25, 1.10, 1.15, 1.40, 1.65, 1.55, 1.30, 1.15, 1.00, 0.75, 0.40] #set monthly demand variation factor month_demand = {} month_demand['January'] = 0.85 month_demand['February'] = 0.95 month_demand['March'] = 1.00 month_demand['April'] = 1.05 month_demand['May'] = 1.20 month_demand['June'] = 1.10 month_demand['July'] = 1.05 month_demand['August'] = 1.00 month_demand['September'] = 1.00 month_demand['October'] = 0.95 month_demand['November'] = 0.95 month_demand['December'] = 0.90 #set monthly spring variation factor month_source = {} month_source['January'] = 0.80 month_source['February'] = 0.75 month_source['March'] = 0.70 month_source['April'] = 0.90 month_source['May'] = 1.15 month_source['June'] = 1.20 month_source['July'] = 1.15 month_source['August'] = 1.15 month_source['September'] = 1.20 month_source['October'] = 1.10 month_source['November'] = 1.00 month_source['December'] = 0.90 #add rainbarrels to epanet file and change year: f = open(original_epanet_file) #read in success, val = read_write_swmm.swmm_input_read(f) if not success: print(val) sys.exit(1) val, house_to_node = modify_epanet_input.implement_irrigation_to_node(val, water_demand_supply, classification, hours) f = open(epanet_file,'w') read_write_swmm.swmm_input_write(f,val) f.close() #set initial values node_with_rainbarrel = {} #for node with rainbarrels demand_pattern_name = 'Demand' #pattern for water demand water_source_name = 'spring' #node name for water source #open Epanet Toolkit en.ENopen(epanet_file, epanet_report_file) #, epanet_bin_file) #open Epanet Toolkit with files #initiate epanet simulation en.ENopenH() #open hydraulic solver en.ENinitH(en.EN_SAVE) #save hydraulic results to bin file t = start_irrigation #set start time #set rainbarrel patterns peak_demand_hour = 17 #get rain barrel control parameters for key, (junction) in house_to_node.items(): patternid_node = en.ENgetpatternindex('Demand_{}'.format(junction)) node_id = en.ENgetnodeindex(junction) node_with_rainbarrel[key] = patternid_node, node_id #get water source index water_source = en.ENgetnodeindex(water_source_name) #node index water_source_abstraction = en.ENgetnodevalue(water_source, en.EN_BASEDEMAND) # get base demand #get Demand pattern index demand = en.ENgetpatternindex(demand_pattern_name) #create dictonaries for results number_nodes = en.ENgetcount(en.EN_NODECOUNT) water_age = {} for index in range(1, number_nodes+1): key = en.ENgetnodeid(index).decode('utf-8') water_age[key] = {} pressure_nodes = copy.deepcopy(water_age) pressure_nodes_peak = copy.deepcopy(water_age) day = 0 total_demand = 0 while t < end_irrigation: #important that t is as long as duration to read hydraulic results file en.ENrunH() #run time step timedelta = en.ENsimtime() #get current simulation time t = start_irrigation + pd.Timedelta(days = timedelta.days, seconds = timedelta.seconds) #combine it with real date if t.hour == 23 and t.minute == 0 and t < end_irrigation: #check if new day, 23 because changes will be updated next time step at 0:00 date = t + pd.Timedelta(seconds = 3600) #to get beginning of day month_name = date.month_name() #get month name #get daily demand factors month_factor_demand = month_demand[month_name] #get monthly factor daily_factor_demand, daily_factor_irrigation = calculate_daily_demand_spring.calculate_demand(daily_weather.loc[date,'Tmean'], daily_weather.loc[date,'Rain']) #calculate daily demand factor based on temperature demand_factor = month_factor_demand * daily_factor_demand #calculate demand factor for changing pattern irrigation_factor = month_factor_demand * daily_factor_irrigation #calculate irrigation factor for changing pattern #get daily source factors month_factor_source = month_source[month_name] #get monthly factor daily_factor_source = calculate_daily_demand_spring.calculate_spring(daily_weather.loc[date,'Tmean'],daily_weather.loc[date,'Rain']) #calculate daily source factor based on temperature source_factor = month_factor_source * daily_factor_source #calculate month factor for changing base source #set daily demand pattern demand_pattern = patterns[t.month_name()] #get daily pattern depending on month daily_demand_pattern = [i * demand_factor for i in demand_pattern] #change pattern en.ENsetpattern(demand, daily_demand_pattern) #set pattern #set daily water source pouring daily_source_abstraction = source_factor * water_source_abstraction #change -demand en.ENsetnodevalue(water_source, 1, daily_source_abstraction) #set demand #reset demand patterns for node with rain barrel - necessary for multiple rain barrels at one node for key, (pattern_node_id, node_id) in node_with_rainbarrel.items(): en.ENsetpattern(pattern_node_id, daily_demand_pattern) #set individual rain barrel pattern for key, (pattern_node_id, node_id) in node_with_rainbarrel.items(): water_demand = water_demand_supply[key][str(date)] #get irrigation demand for rain barrels m3 water_harvested = water_harvesting[key][str(date)] #get saved water m3 #set filling time rain barrel pattern_time = 23 #get base demand for node base_demand = en.ENgetnodevalue(node_id,en.EN_BASEDEMAND) #get actual pattern for node with rain barrel actual_pattern_value_filling = en.ENgetpatternvalue(pattern_node_id, pattern_time) actual_pattern_value_peak = en.ENgetpatternvalue(pattern_node_id, peak_demand_hour+1) #set filling of rain barrel water_abstraction_filling = actual_pattern_value_filling * base_demand water_abstraction_filling_new = water_abstraction_filling + water_demand / (60*60) * 1000 #calculate l/s water_abstraction_filling_new_pattern = water_abstraction_filling_new / base_demand en.ENsetpatternvalue(pattern_node_id, pattern_time, water_abstraction_filling_new_pattern) #change pattern #set reduction at peak hour water_abstraction_peak = actual_pattern_value_peak * base_demand * 3600 water_abstraction_peak_without = daily_demand_pattern[peak_demand_hour] * base_demand * 3600 water_abstraction_irrigation_total = sum([i*base_demand for i in daily_demand_pattern]) * 3600 * irrigation_factor water_reduction_irrigation_poss = (water_demand + water_harvested) * 1000 #calculate l/s water_reduction_irrigation = min(water_reduction_irrigation_poss, 0.4*water_abstraction_irrigation_total) water_reduction_total = max(water_abstraction_peak - water_reduction_irrigation, water_abstraction_peak_without * 0.6) / 3600 water_redcution_new_pattern = water_reduction_total / base_demand en.ENsetpatternvalue(pattern_node_id, peak_demand_hour+1, water_redcution_new_pattern) #change pattern if day == 0: total_demand += base_demand day += 1 #get pressure results at peak demand (17h -> reducing irrigation demand) if t.hour == 17: for index in range(1, number_nodes+1): key = en.ENgetnodeid(index).decode('utf-8') #get key (nodeid) pressure_nodes_peak[key].update({str(t): en.ENgetnodevalue(index, en.EN_PRESSURE)}) #get pressure for node #get pressure results at filling time rainbarrels (22-23h -> because at 23 irrigation starts) if t.hour == 22: for index in range(1, number_nodes+1): key = en.ENgetnodeid(index).decode('utf-8') #get key (nodeid) pressure_nodes[key].update({str(t): en.ENgetnodevalue(index, en.EN_PRESSURE)}) #get pressure for node en.ENnextH() #next time step en.ENcloseH() #close hydraulic solver en.ENopenQ() #open quality solver en.ENinitQ(en.EN_SAVE) #save quality results to bin file t = start_irrigation #set start time while t < end_irrigation: #t should be lower than from hydraulic results (< instead of <=) en.ENrunQ() #run quality time step timedelta = en.ENsimtime() #get current simulation time t = start_irrigation + pd.Timedelta(days = timedelta.days, seconds = timedelta.seconds) #combine it with real date #get water age results at end of the day if t.hour == 23: for index in range(1, number_nodes+1): key = en.ENgetnodeid(index).decode('utf-8') #get key (nodeid) water_age[key].update({str(t): en.ENgetnodevalue(index, en.EN_QUALITY)}) #get pressure for node en.ENstepQ() #next quality time step en.ENcloseQ() #close quality solver en.ENclose() #close epanet toolkit and delete files total_water_results = {} total_water_results['pressure'] = [pressure_nodes] total_water_results['pressure_peak'] = [pressure_nodes_peak] total_water_results['water_age'] = [water_age] results_json = json.dumps(total_water_results) f = open('results/{}'.format(json_file),"w") f.write(results_json) f.close() os.remove(epanet_report_file) #delete report file os.remove(epanet_file) #delete epanet file
em.ENopen(inpName + '.inp', inpName + '.rpt') #print(inpName) demMult = em.ENgetoption(em.EN_DEMANDMULT) ### get avg pressure nnodes = em.ENgetcount(em.EN_NODECOUNT) junInds = [] for index in range(1, nnodes + 1): if em.ENgetnodetype(index) == em.EN_JUNCTION: junInds.append(index) junPres = [[] for q in range(len(junInds))] time = [] ## RUN SIM em.ENopenH() em.ENinitH(0) while True: em.ENrunH() t = em.ENsimtime() time.append( datetime.timedelta.total_seconds(t)) #convert time delta to seconds # Retrieve hydraulic results for time t # #Tank heights # for i in range(0,len(tankInds)): # p=em.ENgetnodevalue(tankInds[i], em.EN_PRESSURE ) # tankLvls[i].append(p) #