def checkNtw(individual, DHN_network_list, DCN_network_list, locator, gv, config, building_names): """ This function calls the distribution routine if necessary :param individual: network configuration considered :param ntwList: list of DHN configurations previously encounterd in the master :param locator: path to the folder :type individual: list :type ntwList: list :type locator: string :return: None :rtype: Nonetype """ DHN_barcode, DCN_barcode, DHN_configuration, DCN_configuration = supportFn.individual_to_barcode( individual, building_names) if not (DHN_barcode in DHN_network_list) and DHN_barcode.count("1") > 0: DHN_network_list.append(DHN_barcode) total_demand = supportFn.createTotalNtwCsv(DHN_barcode, locator) building_names = total_demand.Name.values # Run the substation and distribution routines substation.substation_main(locator, total_demand, building_names, DHN_configuration, DCN_configuration, Flag=True) summarize_network.network_main(locator, total_demand, building_names, config, gv, DHN_barcode) if not (DCN_barcode in DCN_network_list) and DCN_barcode.count("1") > 0: DCN_network_list.append(DCN_barcode) total_demand = supportFn.createTotalNtwCsv(DCN_barcode, locator) building_names = total_demand.Name.values # Run the substation and distribution routines substation.substation_main(locator, total_demand, building_names, DHN_configuration, DCN_configuration, Flag=True) summarize_network.network_main(locator, total_demand, building_names, config, gv, DCN_barcode)
def checkNtw(individual, ntwList, locator, gv): """ This function calls the distribution routine if necessary :param individual: network configuration considered :param ntwList: list of DHN configurations previously encounterd in the master :param locator: path to the folder :type individual: list :type ntwList: list :type locator: string :return: None :rtype: Nonetype """ indCombi = sFn.individual_to_barcode(individual, gv) print indCombi, 2 if not (indCombi in ntwList) and indCombi.count("1") > 0: ntwList.append(indCombi) if indCombi.count("1") == 1: total_demand = pd.read_csv( os.path.join(locator.get_optimization_network_results_folder(), "Total_%(indCombi)s.csv" % locals())) building_names = total_demand.Name.values print "Direct launch of distribution summary routine for", indCombi nM.network_main(locator, total_demand, building_names, gv, indCombi) else: total_demand = sFn.createTotalNtwCsv(indCombi, locator) building_names = total_demand.Name.values # Run the substation and distribution routines print "Re-run the substation routine for new distribution configuration", indCombi sMain.substation_main(locator, total_demand, building_names, gv, indCombi) print "Launch distribution summary routine" nM.network_main(locator, total_demand, building_names, gv, indCombi)
def evaluation_main(individual, building_names, locator, solar_features, network_features, gv, config, prices, lca, ind_num, gen): """ This function evaluates an individual :param individual: list with values of the individual :param building_names: list with names of buildings :param locator: locator class :param solar_features: solar features call to class :param network_features: network features call to class :param gv: global variables class :param optimization_constants: class containing constants used in optimization :param config: configuration file :param prices: class of prices used in optimization :type individual: list :type building_names: list :type locator: string :type solar_features: class :type network_features: class :type gv: class :type optimization_constants: class :type config: class :type prices: class :return: Resulting values of the objective function. costs, CO2, prim :rtype: tuple """ # Check the consistency of the individual or create a new one individual = check_invalid(individual, len(building_names), config) # Initialize objective functions costs, CO2 and primary energy costs_USD = 0 GHG_tonCO2 = 0 PEN_MJoil = 0 Q_heating_uncovered_design_W = 0 Q_heating_uncovered_annual_W = 0 # Create the string representation of the individual DHN_barcode, DCN_barcode, DHN_configuration, DCN_configuration = supportFn.individual_to_barcode( individual, building_names) if DHN_barcode.count("1") == gv.num_tot_buildings: network_file_name_heating = "Network_summary_result_all.csv" Q_DHNf_W = pd.read_csv( locator.get_optimization_network_all_results_summary('all'), usecols=["Q_DHNf_W"]).values Q_heating_max_W = Q_DHNf_W.max() elif DHN_barcode.count("1") == 0: network_file_name_heating = "Network_summary_result_all.csv" Q_heating_max_W = 0 else: network_file_name_heating = "Network_summary_result_" + hex( int(str(DHN_barcode), 2)) + ".csv" if not os.path.exists( locator.get_optimization_network_results_summary(DHN_barcode)): total_demand = supportFn.createTotalNtwCsv(DHN_barcode, locator) building_names = total_demand.Name.values # Run the substation and distribution routines substation.substation_main(locator, total_demand, building_names, DHN_configuration, DCN_configuration, Flag=True) summarize_network.network_main(locator, total_demand, building_names, config, gv, DHN_barcode) Q_DHNf_W = pd.read_csv( locator.get_optimization_network_results_summary(DHN_barcode), usecols=["Q_DHNf_W"]).values Q_heating_max_W = Q_DHNf_W.max() if DCN_barcode.count("1") == gv.num_tot_buildings: network_file_name_cooling = "Network_summary_result_all.csv" if individual[ N_HEAT * 2] == 1: # if heat recovery is ON, then only need to satisfy cooling load of space cooling and refrigeration Q_DCNf_W = pd.read_csv( locator.get_optimization_network_all_results_summary('all'), usecols=["Q_DCNf_space_cooling_and_refrigeration_W"]).values else: Q_DCNf_W = pd.read_csv( locator.get_optimization_network_all_results_summary('all'), usecols=[ "Q_DCNf_space_cooling_data_center_and_refrigeration_W" ]).values Q_cooling_max_W = Q_DCNf_W.max() elif DCN_barcode.count("1") == 0: network_file_name_cooling = "Network_summary_result_all.csv" Q_cooling_max_W = 0 else: network_file_name_cooling = "Network_summary_result_" + hex( int(str(DCN_barcode), 2)) + ".csv" if not os.path.exists( locator.get_optimization_network_results_summary(DCN_barcode)): total_demand = supportFn.createTotalNtwCsv(DCN_barcode, locator) building_names = total_demand.Name.values # Run the substation and distribution routines substation.substation_main(locator, total_demand, building_names, DHN_configuration, DCN_configuration, Flag=True) summarize_network.network_main(locator, total_demand, building_names, config, gv, DCN_barcode) if individual[ N_HEAT * 2] == 1: # if heat recovery is ON, then only need to satisfy cooling load of space cooling and refrigeration Q_DCNf_W = pd.read_csv( locator.get_optimization_network_results_summary(DCN_barcode), usecols=["Q_DCNf_space_cooling_and_refrigeration_W"]).values else: Q_DCNf_W = pd.read_csv( locator.get_optimization_network_results_summary(DCN_barcode), usecols=[ "Q_DCNf_space_cooling_data_center_and_refrigeration_W" ]).values Q_cooling_max_W = Q_DCNf_W.max() Q_heating_nom_W = Q_heating_max_W * (1 + Q_MARGIN_FOR_NETWORK) Q_cooling_nom_W = Q_cooling_max_W * (1 + Q_MARGIN_FOR_NETWORK) # Modify the individual with the extra GHP constraint try: check.GHPCheck(individual, locator, Q_heating_nom_W, gv) except: print "No GHP constraint check possible \n" # Export to context master_to_slave_vars = calc_master_to_slave_variables( individual, Q_heating_max_W, Q_cooling_max_W, building_names, ind_num, gen) master_to_slave_vars.network_data_file_heating = network_file_name_heating master_to_slave_vars.network_data_file_cooling = network_file_name_cooling master_to_slave_vars.total_buildings = len(building_names) master_to_slave_vars.DHN_barcode = DHN_barcode master_to_slave_vars.DCN_barcode = DCN_barcode if master_to_slave_vars.number_of_buildings_connected_heating > 1: if DHN_barcode.count("0") == 0: master_to_slave_vars.fNameTotalCSV = locator.get_total_demand() else: master_to_slave_vars.fNameTotalCSV = os.path.join( locator.get_optimization_network_totals_folder(), "Total_%(DHN_barcode)s.csv" % locals()) else: master_to_slave_vars.fNameTotalCSV = locator.get_optimization_substations_total_file( DHN_barcode) if master_to_slave_vars.number_of_buildings_connected_cooling > 1: if DCN_barcode.count("0") == 0: master_to_slave_vars.fNameTotalCSV = locator.get_total_demand() else: master_to_slave_vars.fNameTotalCSV = os.path.join( locator.get_optimization_network_totals_folder(), "Total_%(DCN_barcode)s.csv" % locals()) else: master_to_slave_vars.fNameTotalCSV = locator.get_optimization_substations_total_file( DCN_barcode) # Thermal Storage Calculations; Run storage optimization costs_storage_USD, GHG_storage_tonCO2, PEN_storage_MJoil = storage_main.storage_optimization( locator, master_to_slave_vars, lca, prices, config) costs_USD += costs_storage_USD GHG_tonCO2 += GHG_storage_tonCO2 PEN_MJoil += PEN_storage_MJoil # District Heating Calculations if config.district_heating_network: if DHN_barcode.count("1") > 0: (PEN_heating_MJoil, GHG_heating_tonCO2, costs_heating_USD, Q_heating_uncovered_design_W, Q_heating_uncovered_annual_W ) = heating_main.heating_calculations_of_DH_buildings( locator, master_to_slave_vars, gv, config, prices, lca) else: GHG_heating_tonCO2 = 0 costs_heating_USD = 0 PEN_heating_MJoil = 0 else: GHG_heating_tonCO2 = 0 costs_heating_USD = 0 PEN_heating_MJoil = 0 costs_USD += costs_heating_USD GHG_tonCO2 += GHG_heating_tonCO2 PEN_MJoil += PEN_heating_MJoil # District Cooling Calculations if gv.ZernezFlag == 1: costs_cooling_USD, GHG_cooling_tonCO2, PEN_cooling_MJoil = 0, 0, 0 elif config.district_cooling_network: reduced_timesteps_flag = False (costs_cooling_USD, GHG_cooling_tonCO2, PEN_cooling_MJoil ) = cooling_main.cooling_calculations_of_DC_buildings( locator, master_to_slave_vars, network_features, gv, prices, lca, config, reduced_timesteps_flag) else: costs_cooling_USD, GHG_cooling_tonCO2, PEN_cooling_MJoil = 0, 0, 0 costs_USD += costs_cooling_USD GHG_tonCO2 += GHG_cooling_tonCO2 PEN_MJoil += PEN_cooling_MJoil # District Electricity Calculations (costs_electricity_USD, GHG_electricity_tonCO2, PEN_electricity_MJoil ) = electricity_main.electricity_calculations_of_all_buildings( DHN_barcode, DCN_barcode, locator, master_to_slave_vars, network_features, gv, prices, lca, config) costs_USD += costs_electricity_USD GHG_tonCO2 += GHG_electricity_tonCO2 PEN_MJoil += PEN_electricity_MJoil # Natural Gas Import Calculations. Prices, GHG and PEN are already included in the various sections. # This is to save the files for further processing and plots natural_gas_main.natural_gas_imports(master_to_slave_vars, locator, config) # Capex Calculations print "Add extra costs" (costs_additional_USD, GHG_additional_tonCO2, PEN_additional_MJoil) = cost_model.addCosts( building_names, locator, master_to_slave_vars, Q_heating_uncovered_design_W, Q_heating_uncovered_annual_W, solar_features, network_features, gv, config, prices, lca) costs_USD += costs_additional_USD GHG_tonCO2 += GHG_additional_tonCO2 PEN_MJoil += PEN_additional_MJoil summarize_individual.summarize_individual_main(master_to_slave_vars, building_names, individual, solar_features, locator, config) # Converting costs into float64 to avoid longer values costs_USD = np.float64(costs_USD) GHG_tonCO2 = np.float64(GHG_tonCO2) PEN_MJoil = np.float64(PEN_MJoil) print('Total costs = ' + str(costs_USD)) print('Total CO2 = ' + str(GHG_tonCO2)) print('Total prim = ' + str(PEN_MJoil)) # Saving capacity details of the individual return costs_USD, GHG_tonCO2, PEN_MJoil, master_to_slave_vars, individual
def preproccessing(locator, total_demand, building_names, weather_file, gv): """ This function aims at preprocessing all data for the optimization. :param locator: path to locator function :param total_demand: dataframe with total demand and names of all building in the area :param building_names: dataframe with names of all buildings in the area :param weather_file: path to wather file :param gv: path to global variables class :type locator: class :type total_demand: list :type building_names: list :type weather_file: string :type gv: class :return: extraCosts: extra pareto optimal costs due to electricity and process heat ( these are treated separately and not considered inside the optimization) extraCO2: extra pareto optimal emissions due to electricity and process heat ( these are treated separately and not considered inside the optimization) extraPrim: extra pareto optimal primary energy due to electricity and process heat ( these are treated separately and not considered inside the optimization) solar_features: extraction of solar features form the results of the solar technologies calculation. :rtype: float, float, float, float """ # GET ENERGY POTENTIALS # geothermal T_ambient = epwreader.epw_reader(weather_file)['drybulb_C'] gv.ground_temperature = geothermal.calc_ground_temperature( T_ambient.values, gv) # solar print "Solar features extraction" solar_features = SolarFeatures(locator) # GET LOADS IN SUBSTATIONS # prepocess space heating, domestic hot water and space cooling to substation. print "Run substation model for each building separately" substation.substation_main( locator, total_demand, building_names, gv, Flag=True) # True if disconected buildings are calculated # GET COMPETITIVE ALTERNATIVES TO A NETWORK # estimate what would be the operation of single buildings only for heating. # For cooling all buildings are assumed to be connected to the cooling distribution on site. print "Run decentralized model for buildings" #decentralized_buildings.decentralized_main(locator, building_names, gv) # GET DH NETWORK # at first estimate a distribution with all the buildings connected at it. print "Create distribution file with all buildings connected" summarize_network.network_main(locator, total_demand, building_names, gv, "all") #"_all" key for all buildings # GET EXTRAS # estimate the extra costs, emissions and primary energy of electricity. print "electricity" elecCosts, elecCO2, elecPrim = electricity.calc_pareto_electricity( locator, gv) # estimate the extra costs, emissions and primary energy for process heat print "Process-heat" hpCosts, hpCO2, hpPrim = process_heat.calc_pareto_Qhp( locator, total_demand, gv) extraCosts = elecCosts + hpCosts extraCO2 = elecCO2 + hpCO2 extraPrim = elecPrim + hpPrim return extraCosts, extraCO2, extraPrim, solar_features
def disconnected_buildings_heating_main(locator, building_names, config, prices, lca): """ Computes the parameters for the operation of disconnected buildings output results in csv files. There is no optimization at this point. The different technologies are calculated and compared 1 to 1 to each technology. it is a classical combinatorial problem. :param locator: locator class :param building_names: list with names of buildings :type locator: class :type building_names: list :return: results of operation of buildings located in locator.get_optimization_disconnected_folder :rtype: Nonetype """ t0 = time.clock() prop_geometry = Gdf.from_file(locator.get_zone_geometry()) restrictions = Gdf.from_file(locator.get_building_restrictions()) geometry = pd.DataFrame({ 'Name': prop_geometry.Name, 'Area': prop_geometry.area }) geothermal_potential_data = dbf.dbf_to_dataframe( locator.get_building_supply()) geothermal_potential_data = pd.merge(geothermal_potential_data, geometry, on='Name').merge(restrictions, on='Name') geothermal_potential_data['Area_geo'] = ( 1 - geothermal_potential_data['GEOTHERMAL'] ) * geothermal_potential_data['Area'] weather_data = epwreader.epw_reader(config.weather)[[ 'year', 'drybulb_C', 'wetbulb_C', 'relhum_percent', 'windspd_ms', 'skytemp_C' ]] ground_temp = calc_ground_temperature(locator, weather_data['drybulb_C'], depth_m=10) BestData = {} total_demand = pd.read_csv(locator.get_total_demand()) def calc_new_load(mdot, TsupDH, Tret): """ This function calculates the load distribution side of the district heating distribution. :param mdot: mass flow :param TsupDH: supply temeperature :param Tret: return temperature :param gv: global variables class :type mdot: float :type TsupDH: float :type Tret: float :type gv: class :return: Qload: load of the distribution :rtype: float """ Qload = mdot * HEAT_CAPACITY_OF_WATER_JPERKGK * (TsupDH - Tret) * ( 1 + Q_LOSS_DISCONNECTED) if Qload < 0: Qload = 0 return Qload for building_name in building_names: print building_name substation.substation_main(locator, total_demand, building_names=[building_name], heating_configuration=7, cooling_configuration=7, Flag=False) loads = pd.read_csv( locator.get_optimization_substations_results_file(building_name), usecols=[ "T_supply_DH_result_K", "T_return_DH_result_K", "mdot_DH_result_kgpers" ]) Qload = np.vectorize(calc_new_load)(loads["mdot_DH_result_kgpers"], loads["T_supply_DH_result_K"], loads["T_return_DH_result_K"]) Qannual = Qload.sum() Qnom = Qload.max() * (1 + SIZING_MARGIN ) # 1% reliability margin on installed capacity # Create empty matrices result = np.zeros((13, 7)) result[0][0] = 1 result[1][1] = 1 result[2][2] = 1 InvCosts = np.zeros((13, 1)) resourcesRes = np.zeros((13, 4)) QannualB_GHP = np.zeros( (10, 1)) # For the investment costs of the boiler used with GHP Wel_GHP = np.zeros((10, 1)) # For the investment costs of the GHP # Supply with the Boiler / FC / GHP Tret = loads["T_return_DH_result_K"].values TsupDH = loads["T_supply_DH_result_K"].values mdot = loads["mdot_DH_result_kgpers"].values for hour in range(8760): if Tret[hour] == 0: Tret[hour] = TsupDH[hour] # Boiler NG BoilerEff = Boiler.calc_Cop_boiler(Qload[hour], Qnom, Tret[hour]) Qgas = Qload[hour] / BoilerEff result[0][4] += prices.NG_PRICE * Qgas # CHF result[0][ 5] += lca.NG_BACKUPBOILER_TO_CO2_STD * Qgas * 3600E-6 # kgCO2 result[0][ 6] += lca.NG_BACKUPBOILER_TO_OIL_STD * Qgas * 3600E-6 # MJ-oil-eq resourcesRes[0][0] += Qload[hour] if DISC_BIOGAS_FLAG == 1: result[0][4] += prices.BG_PRICE * Qgas # CHF result[0][ 5] += lca.BG_BACKUPBOILER_TO_CO2_STD * Qgas * 3600E-6 # kgCO2 result[0][ 6] += lca.BG_BACKUPBOILER_TO_OIL_STD * Qgas * 3600E-6 # MJ-oil-eq # Boiler BG result[1][4] += prices.BG_PRICE * Qgas # CHF result[1][ 5] += lca.BG_BACKUPBOILER_TO_CO2_STD * Qgas * 3600E-6 # kgCO2 result[1][ 6] += lca.BG_BACKUPBOILER_TO_OIL_STD * Qgas * 3600E-6 # MJ-oil-eq resourcesRes[1][1] += Qload[hour] # FC (FC_Effel, FC_Effth) = FC.calc_eta_FC(Qload[hour], Qnom, 1, "B") Qgas = Qload[hour] / (FC_Effth + FC_Effel) Qelec = Qgas * FC_Effel result[2][ 4] += prices.NG_PRICE * Qgas - lca.ELEC_PRICE * Qelec # CHF, extra electricity sold to grid result[2][ 5] += 0.0874 * Qgas * 3600E-6 + 773 * 0.45 * Qelec * 1E-6 - lca.EL_TO_CO2 * Qelec * 3600E-6 # kgCO2 # Bloom box emissions within the FC: 773 lbs / MWh_el (and 1 lbs = 0.45 kg) # http://www.carbonlighthouse.com/2011/09/16/bloom-box/ result[2][ 6] += 1.51 * Qgas * 3600E-6 - lca.EL_TO_OIL_EQ * Qelec * 3600E-6 # MJ-oil-eq resourcesRes[2][0] += Qload[hour] resourcesRes[2][2] += Qelec # GHP for i in range(10): QnomBoiler = i / 10 * Qnom QnomGHP = Qnom - QnomBoiler if Qload[hour] <= QnomGHP: (wdot_el, qcolddot, qhotdot_missing, tsup2) = HP.calc_Cop_GHP(ground_temp[hour], mdot[hour], TsupDH[hour], Tret[hour]) if Wel_GHP[i][0] < wdot_el: Wel_GHP[i][0] = wdot_el result[3 + i][4] += lca.ELEC_PRICE * wdot_el # CHF result[3 + i][ 5] += lca.SMALL_GHP_TO_CO2_STD * wdot_el * 3600E-6 # kgCO2 result[3 + i][ 6] += lca.SMALL_GHP_TO_OIL_STD * wdot_el * 3600E-6 # MJ-oil-eq resourcesRes[3 + i][2] -= wdot_el resourcesRes[3 + i][3] += Qload[hour] - qhotdot_missing if qhotdot_missing > 0: print "GHP unable to cover the whole demand, boiler activated!" BoilerEff = Boiler.calc_Cop_boiler( qhotdot_missing, QnomBoiler, tsup2) Qgas = qhotdot_missing / BoilerEff result[3 + i][4] += prices.NG_PRICE * Qgas # CHF result[3 + i][ 5] += lca.NG_BACKUPBOILER_TO_CO2_STD * Qgas * 3600E-6 # kgCO2 result[3 + i][ 6] += lca.NG_BACKUPBOILER_TO_OIL_STD * Qgas * 3600E-6 # MJ-oil-eq QannualB_GHP[i][0] += qhotdot_missing resourcesRes[3 + i][0] += qhotdot_missing else: # print "Boiler activated to compensate GHP", i # if gv.DiscGHPFlag == 0: # print QnomGHP # QnomGHP = 0 # print "GHP not allowed 2, set QnomGHP to zero" TexitGHP = QnomGHP / ( mdot[hour] * HEAT_CAPACITY_OF_WATER_JPERKGK) + Tret[hour] (wdot_el, qcolddot, qhotdot_missing, tsup2) = HP.calc_Cop_GHP(ground_temp[hour], mdot[hour], TexitGHP, Tret[hour]) if Wel_GHP[i][0] < wdot_el: Wel_GHP[i][0] = wdot_el result[3 + i][4] += lca.ELEC_PRICE * wdot_el # CHF result[3 + i][ 5] += lca.SMALL_GHP_TO_CO2_STD * wdot_el * 3600E-6 # kgCO2 result[3 + i][ 6] += lca.SMALL_GHP_TO_OIL_STD * wdot_el * 3600E-6 # MJ-oil-eq resourcesRes[3 + i][2] -= wdot_el resourcesRes[3 + i][3] += QnomGHP - qhotdot_missing if qhotdot_missing > 0: print "GHP unable to cover the whole demand, boiler activated!" BoilerEff = Boiler.calc_Cop_boiler( qhotdot_missing, QnomBoiler, tsup2) Qgas = qhotdot_missing / BoilerEff result[3 + i][4] += prices.NG_PRICE * Qgas # CHF result[3 + i][ 5] += lca.NG_BACKUPBOILER_TO_CO2_STD * Qgas * 3600E-6 # kgCO2 result[3 + i][ 6] += lca.NG_BACKUPBOILER_TO_OIL_STD * Qgas * 3600E-6 # MJ-oil-eq QannualB_GHP[i][0] += qhotdot_missing resourcesRes[3 + i][0] += qhotdot_missing QtoBoiler = Qload[hour] - QnomGHP QannualB_GHP[i][0] += QtoBoiler BoilerEff = Boiler.calc_Cop_boiler(QtoBoiler, QnomBoiler, TexitGHP) Qgas = QtoBoiler / BoilerEff result[3 + i][4] += prices.NG_PRICE * Qgas # CHF result[3 + i][ 5] += lca.NG_BACKUPBOILER_TO_CO2_STD * Qgas * 3600E-6 # kgCO2 result[3 + i][ 6] += lca.NG_BACKUPBOILER_TO_OIL_STD * Qgas * 3600E-6 # MJ-oil-eq resourcesRes[3 + i][0] += QtoBoiler # Investment Costs / CO2 / Prim Capex_a_Boiler, Opex_Boiler = Boiler.calc_Cinv_boiler( Qnom, locator, config, 'BO1') InvCosts[0][0] = Capex_a_Boiler + Opex_Boiler InvCosts[1][0] = Capex_a_Boiler + Opex_Boiler Capex_a_FC, Opex_FC = FC.calc_Cinv_FC(Qnom, locator, config) InvCosts[2][0] = Capex_a_FC + Opex_FC for i in range(10): result[3 + i][0] = i / 10 result[3 + i][3] = 1 - i / 10 QnomBoiler = i / 10 * Qnom Capex_a_Boiler, Opex_Boiler = Boiler.calc_Cinv_boiler( QnomBoiler, locator, config, 'BO1') InvCosts[3 + i][0] = Capex_a_Boiler + Opex_Boiler Capex_a_GHP, Opex_GHP = HP.calc_Cinv_GHP(Wel_GHP[i][0], locator, config) InvCaGHP = Capex_a_GHP + Opex_GHP InvCosts[3 + i][0] += InvCaGHP * prices.EURO_TO_CHF # Best configuration Best = np.zeros((13, 1)) indexBest = 0 TotalCosts = np.zeros((13, 2)) TotalCO2 = np.zeros((13, 2)) TotalPrim = np.zeros((13, 2)) for i in range(13): TotalCosts[i][0] = TotalCO2[i][0] = TotalPrim[i][0] = i TotalCosts[i][1] = InvCosts[i][0] + result[i][4] TotalCO2[i][1] = result[i][5] TotalPrim[i][1] = result[i][6] CostsS = TotalCosts[np.argsort(TotalCosts[:, 1])] CO2S = TotalCO2[np.argsort(TotalCO2[:, 1])] PrimS = TotalPrim[np.argsort(TotalPrim[:, 1])] el = len(CostsS) rank = 0 Bestfound = False optsearch = np.empty(el) optsearch.fill(3) indexBest = 0 geothermal_potential = geothermal_potential_data.set_index('Name') # Check the GHP area constraint for i in range(10): QGHP = (1 - i / 10) * Qnom areaAvail = geothermal_potential.ix[building_name, 'Area_geo'] Qallowed = np.ceil(areaAvail / GHP_A) * GHP_HMAX_SIZE # [W_th] if Qallowed < QGHP: optsearch[i + 3] += 1 Best[i + 3][0] = -1 while not Bestfound and rank < el: optsearch[int(CostsS[rank][0])] -= 1 optsearch[int(CO2S[rank][0])] -= 1 optsearch[int(PrimS[rank][0])] -= 1 if np.count_nonzero(optsearch) != el: Bestfound = True indexBest = np.where(optsearch == 0)[0][0] rank += 1 # get the best option according to the ranking. Best[indexBest][0] = 1 Qnom_array = np.ones(len(Best[:, 0])) * Qnom # Save results in csv file dico = {} dico["BoilerNG Share"] = result[:, 0] dico["BoilerBG Share"] = result[:, 1] dico["FC Share"] = result[:, 2] dico["GHP Share"] = result[:, 3] dico["Operation Costs [CHF]"] = result[:, 4] dico["CO2 Emissions [kgCO2-eq]"] = result[:, 5] dico["Primary Energy Needs [MJoil-eq]"] = result[:, 6] dico["Annualized Investment Costs [CHF]"] = InvCosts[:, 0] dico["Total Costs [CHF]"] = TotalCosts[:, 1] dico["Best configuration"] = Best[:, 0] dico["Nominal Power"] = Qnom_array dico["QfromNG"] = resourcesRes[:, 0] dico["QfromBG"] = resourcesRes[:, 1] dico["EforGHP"] = resourcesRes[:, 2] dico["QfromGHP"] = resourcesRes[:, 3] results_to_csv = pd.DataFrame(dico) fName_result = locator.get_optimization_disconnected_folder_building_result_heating( building_name) results_to_csv.to_csv(fName_result, sep=',') BestComb = {} BestComb["BoilerNG Share"] = result[indexBest, 0] BestComb["BoilerBG Share"] = result[indexBest, 1] BestComb["FC Share"] = result[indexBest, 2] BestComb["GHP Share"] = result[indexBest, 3] BestComb["Operation Costs [CHF]"] = result[indexBest, 4] BestComb["CO2 Emissions [kgCO2-eq]"] = result[indexBest, 5] BestComb["Primary Energy Needs [MJoil-eq]"] = result[indexBest, 6] BestComb["Annualized Investment Costs [CHF]"] = InvCosts[indexBest, 0] BestComb["Total Costs [CHF]"] = TotalCosts[indexBest, 1] BestComb["Best configuration"] = Best[indexBest, 0] BestComb["Nominal Power"] = Qnom BestData[building_name] = BestComb if 0: fName = locator.get_optimization_disconnected_folder_disc_op_summary_heating( ) results_to_csv = pd.DataFrame(BestData) results_to_csv.to_csv(fName, sep=',') print time.clock( ) - t0, "seconds process time for the Disconnected Building Routine \n"
def supply_calculation(individual, building_names, total_demand, locator, extra_costs, extra_CO2, extra_primary_energy, solar_features, network_features, gv, config, prices, lca): """ This function evaluates one supply system configuration of the case study. :param individual: a list that indicates the supply system configuration :type individual: list :param building_names: names of all building in the district :type building_names: ndarray :param locator: :param extra_costs: cost of decentralized supply systems :param extra_CO2: CO2 emission of decentralized supply systems :param extra_primary_energy: Primary energy of decentralized supply systems :param solar_features: Energy production potentials of solar technologies, including area of installed panels and annual production :type solar_features: dict :param network_features: hourly network operating conditions (thermal/pressure losses) and capital costs :type network_features: dict :param gv: :param config: :param prices: :return: """ individual = evaluation.check_invalid(individual, len(building_names), config) # Initialize objective functions costs, CO2 and primary energy costs_USD = 0.0 GHG_tonCO2 = extra_CO2 PEN_MJoil = extra_primary_energy Q_uncovered_design_W = 0.0 Q_uncovered_annual_W = 0.0 # Create the string representation of the individual DHN_barcode, DCN_barcode, DHN_configuration, DCN_configuration = supportFn.individual_to_barcode( individual, building_names) # read the total loads from buildings connected to thermal networks if DHN_barcode.count("1") == gv.num_tot_buildings: network_file_name_heating = "Network_summary_result_all.csv" Q_DHNf_W = pd.read_csv( locator.get_optimization_network_all_results_summary('all'), usecols=["Q_DHNf_W"]).values Q_heating_max_W = Q_DHNf_W.max() elif DHN_barcode.count("1") == 0: network_file_name_heating = "Network_summary_result_all.csv" Q_heating_max_W = 0.0 else: # Run the substation and distribution routines substation.substation_main(locator, total_demand, building_names, DHN_configuration, DCN_configuration, Flag=True) summarize_network.network_main(locator, total_demand, building_names, config, gv, DHN_barcode) network_file_name_heating = "Network_summary_result_" + hex( int(str(DHN_barcode), 2)) + ".csv" Q_DHNf_W = pd.read_csv( locator.get_optimization_network_results_summary(DHN_barcode), usecols=["Q_DHNf_W"]).values Q_heating_max_W = Q_DHNf_W.max() if DCN_barcode.count("1") == gv.num_tot_buildings: network_file_name_cooling = "Network_summary_result_all.csv" if individual[ N_HEAT * 2] == 1: # if heat recovery is ON, then only need to satisfy cooling load of space cooling and refrigeration Q_DCNf_W = pd.read_csv( locator.get_optimization_network_all_results_summary('all'), usecols=["Q_DCNf_space_cooling_and_refrigeration_W"]).values else: Q_DCNf_W = pd.read_csv( locator.get_optimization_network_all_results_summary('all'), usecols=[ "Q_DCNf_space_cooling_data_center_and_refrigeration_W" ]).values Q_cooling_max_W = Q_DCNf_W.max() elif DCN_barcode.count("1") == 0: network_file_name_cooling = "Network_summary_result_none.csv" Q_cooling_max_W = 0 else: # Run the substation and distribution routines substation.substation_main(locator, total_demand, building_names, DHN_configuration, DCN_configuration, Flag=True) summarize_network.network_main(locator, total_demand, building_names, config, gv, DCN_barcode) network_file_name_cooling = "Network_summary_result_" + hex( int(str(DCN_barcode), 2)) + ".csv" if individual[ N_HEAT * 2] == 1: # if heat recovery is ON, then only need to satisfy cooling load of space cooling and refrigeration Q_DCNf_W = pd.read_csv( locator.get_optimization_network_results_summary(DCN_barcode), usecols=["Q_DCNf_space_cooling_and_refrigeration_W"]).values else: Q_DCNf_W = pd.read_csv( locator.get_optimization_network_results_summary(DCN_barcode), usecols=[ "Q_DCNf_space_cooling_data_center_and_refrigeration_W" ]).values Q_cooling_max_W = Q_DCNf_W.max() Q_heating_nom_W = Q_heating_max_W * (1 + Q_MARGIN_FOR_NETWORK) Q_cooling_nom_W = Q_cooling_max_W * (1 + Q_MARGIN_FOR_NETWORK) # Modify the individual with the extra GHP constraint try: check.GHPCheck(individual, locator, Q_heating_nom_W, gv) except: print "No GHP constraint check possible \n" # Export to context individual_number = calc_individual_number(locator) master_to_slave_vars = evaluation.calc_master_to_slave_variables( individual, Q_heating_max_W, Q_cooling_max_W, building_names, individual_number, GENERATION_NUMBER) master_to_slave_vars.network_data_file_heating = network_file_name_heating master_to_slave_vars.network_data_file_cooling = network_file_name_cooling master_to_slave_vars.total_buildings = len(building_names) if master_to_slave_vars.number_of_buildings_connected_heating > 1: if DHN_barcode.count("0") == 0: master_to_slave_vars.fNameTotalCSV = locator.get_total_demand() else: master_to_slave_vars.fNameTotalCSV = os.path.join( locator.get_optimization_network_totals_folder(), "Total_%(DHN_barcode)s.csv" % locals()) else: master_to_slave_vars.fNameTotalCSV = locator.get_optimization_substations_total_file( DHN_barcode) if master_to_slave_vars.number_of_buildings_connected_cooling > 1: if DCN_barcode.count("0") == 0: master_to_slave_vars.fNameTotalCSV = locator.get_total_demand() else: master_to_slave_vars.fNameTotalCSV = os.path.join( locator.get_optimization_network_totals_folder(), "Total_%(DCN_barcode)s.csv" % locals()) else: master_to_slave_vars.fNameTotalCSV = locator.get_optimization_substations_total_file( DCN_barcode) costs_storage_USD, GHG_storage_tonCO2, PEN_storage_MJoil = storage_main.storage_optimization( locator, master_to_slave_vars, lca, prices, config) costs_USD += costs_storage_USD GHG_tonCO2 += GHG_storage_tonCO2 PEN_MJoil += PEN_storage_MJoil # slave optimization of heating networks if config.district_heating_network: if DHN_barcode.count("1") > 0: (PEN_heating_MJoil, GHG_heating_tonCO2, costs_heating_USD, Q_uncovered_design_W, Q_uncovered_annual_W ) = heating_main.heating_calculations_of_DH_buildings( locator, master_to_slave_vars, gv, config, prices, lca) else: GHG_heating_tonCO2 = 0.0 costs_heating_USD = 0.0 PEN_heating_MJoil = 0.0 else: GHG_heating_tonCO2 = 0.0 costs_heating_USD = 0.0 PEN_heating_MJoil = 0.0 costs_USD += costs_heating_USD GHG_tonCO2 += GHG_heating_tonCO2 PEN_MJoil += PEN_heating_MJoil # slave optimization of cooling networks if gv.ZernezFlag == 1: costs_cooling_USD, GHG_cooling_tonCO2, PEN_cooling_MJoil = 0.0, 0.0, 0.0 elif config.district_cooling_network and DCN_barcode.count("1") > 0: reduced_timesteps_flag = config.supply_system_simulation.reduced_timesteps (costs_cooling_USD, GHG_cooling_tonCO2, PEN_cooling_MJoil ) = cooling_main.cooling_calculations_of_DC_buildings( locator, master_to_slave_vars, network_features, gv, prices, lca, config, reduced_timesteps_flag) # if reduced_timesteps_flag: # # reduced timesteps simulation for a month (May) # coolCosts = coolCosts * (8760/(3624/2880)) # coolCO2 = coolCO2 * (8760/(3624/2880)) # coolPrim = coolPrim * (8760/(3624/2880)) # # FIXME: check results else: costs_cooling_USD, GHG_cooling_tonCO2, PEN_cooling_MJoil = 0.0, 0.0, 0.0 # District Electricity Calculations costs_electricity_USD, GHG_electricity_tonCO2, PEN_electricity_MJoil = electricity_main.electricity_calculations_of_all_buildings( DHN_barcode, DCN_barcode, locator, master_to_slave_vars, network_features, gv, prices, lca, config) costs_USD += costs_electricity_USD GHG_tonCO2 += GHG_electricity_tonCO2 PEN_MJoil += PEN_electricity_MJoil natural_gas_main.natural_gas_imports(master_to_slave_vars, locator, config) # print "Add extra costs" # add costs of disconnected buildings (best configuration) (costs_additional_USD, GHG_additional_tonCO2, PEN_additional_MJoil) = cost_model.addCosts( building_names, locator, master_to_slave_vars, Q_uncovered_design_W, Q_uncovered_annual_W, solar_features, network_features, gv, config, prices, lca) costs_USD += costs_additional_USD GHG_tonCO2 += GHG_additional_tonCO2 PEN_MJoil += PEN_additional_MJoil costs_USD = (np.float64(costs_USD) / 1e6).round(2) # $ to Mio$ GHG_tonCO2 = (np.float64(GHG_tonCO2) / 1e6).round(2) # kg to kilo-ton PEN_MJoil = (np.float64(PEN_MJoil) / 1e6).round(2) # MJ to TJ # add electricity costs corresponding to # print ('Additional costs = ' + str(addCosts)) # print ('Additional CO2 = ' + str(addCO2)) # print ('Additional prim = ' + str(addPrim)) print('Total annualized costs [USD$(2015) Mio/yr] = ' + str(costs_USD)) print('Green house gas emission [kton-CO2/yr] = ' + str(GHG_tonCO2)) print('Primary energy [TJ-oil-eq/yr] = ' + str(PEN_MJoil)) results = { 'TAC_Mio_per_yr': [costs_USD.round(2)], 'CO2_kton_per_yr': [GHG_tonCO2.round(2)], 'Primary_Energy_TJ_per_yr': [PEN_MJoil.round(2)] } results_df = pd.DataFrame(results) results_path = os.path.join( locator.get_optimization_slave_results_folder(GENERATION_NUMBER), 'ind_' + str(individual_number) + '_results.csv') results_df.to_csv(results_path) with open(locator.get_optimization_checkpoint_initial(), "wb") as fp: pop = [] g = GENERATION_NUMBER epsInd = [] invalid_ind = [] fitnesses = [] capacities = [] disconnected_capacities = [] halloffame = [] halloffame_fitness = [] euclidean_distance = [] spread = [] cp = dict(population=pop, generation=g, epsIndicator=epsInd, testedPop=invalid_ind, population_fitness=fitnesses, capacities=capacities, disconnected_capacities=disconnected_capacities, halloffame=halloffame, halloffame_fitness=halloffame_fitness, euclidean_distance=euclidean_distance, spread=spread) json.dump(cp, fp) return costs_USD, GHG_tonCO2, PEN_MJoil, master_to_slave_vars, individual
def supply_calculation(individual, building_names, total_demand, locator, extra_costs, extra_CO2, extra_primary_energy, solar_features, network_features, gv, config, prices, lca): """ This function evaluates one supply system configuration of the case study. :param individual: a list that indicates the supply system configuration :type individual: list :param building_names: names of all building in the district :type building_names: ndarray :param locator: :param extra_costs: cost of decentralized supply systems :param extra_CO2: CO2 emission of decentralized supply systems :param extra_primary_energy: Primary energy of decentralized supply systems :param solar_features: Energy production potentials of solar technologies, including area of installed panels and annual production :type solar_features: dict :param network_features: hourly network operating conditions (thermal/pressure losses) and capital costs :type network_features: dict :param gv: :param config: :param prices: :return: """ individual = evaluation.check_invalid(individual, len(building_names), config) # Initialize objective functions costs, CO2 and primary energy costs = 0 CO2 = extra_CO2 prim = extra_primary_energy QUncoveredDesign = 0 QUncoveredAnnual = 0 # Create the string representation of the individual DHN_barcode, DCN_barcode, DHN_configuration, DCN_configuration = sFn.individual_to_barcode( individual, building_names) # read the total loads from buildings connected to thermal networks if DHN_barcode.count("1") == gv.num_tot_buildings: network_file_name_heating = "Network_summary_result_all.csv" Q_DHNf_W = pd.read_csv( locator.get_optimization_network_all_results_summary('all'), usecols=["Q_DHNf_W"]).values Q_heating_max_W = Q_DHNf_W.max() elif DHN_barcode.count("1") == 0: network_file_name_heating = "Network_summary_result_all.csv" Q_heating_max_W = 0 else: # Run the substation and distribution routines sMain.substation_main(locator, total_demand, building_names, DHN_configuration, DCN_configuration, Flag=True) nM.network_main(locator, total_demand, building_names, config, gv, DHN_barcode) network_file_name_heating = "Network_summary_result_" + hex( int(str(DHN_barcode), 2)) + ".csv" Q_DHNf_W = pd.read_csv( locator.get_optimization_network_results_summary(DHN_barcode), usecols=["Q_DHNf_W"]).values Q_heating_max_W = Q_DHNf_W.max() if DCN_barcode.count("1") == gv.num_tot_buildings: network_file_name_cooling = "Network_summary_result_all.csv" if individual[ N_HEAT * 2] == 1: # if heat recovery is ON, then only need to satisfy cooling load of space cooling and refrigeration Q_DCNf_W = pd.read_csv( locator.get_optimization_network_all_results_summary('all'), usecols=["Q_DCNf_space_cooling_and_refrigeration_W"]).values else: Q_DCNf_W = pd.read_csv( locator.get_optimization_network_all_results_summary('all'), usecols=[ "Q_DCNf_space_cooling_data_center_and_refrigeration_W" ]).values Q_cooling_max_W = Q_DCNf_W.max() elif DCN_barcode.count("1") == 0: network_file_name_cooling = "Network_summary_result_none.csv" Q_cooling_max_W = 0 else: # Run the substation and distribution routines sMain.substation_main(locator, total_demand, building_names, DHN_configuration, DCN_configuration, Flag=True) nM.network_main(locator, total_demand, building_names, config, gv, DCN_barcode) network_file_name_cooling = "Network_summary_result_" + hex( int(str(DCN_barcode), 2)) + ".csv" if individual[ N_HEAT * 2] == 1: # if heat recovery is ON, then only need to satisfy cooling load of space cooling and refrigeration Q_DCNf_W = pd.read_csv( locator.get_optimization_network_results_summary(DCN_barcode), usecols=["Q_DCNf_space_cooling_and_refrigeration_W"]).values else: Q_DCNf_W = pd.read_csv( locator.get_optimization_network_results_summary(DCN_barcode), usecols=[ "Q_DCNf_space_cooling_data_center_and_refrigeration_W" ]).values Q_cooling_max_W = Q_DCNf_W.max() Q_heating_nom_W = Q_heating_max_W * (1 + Q_MARGIN_FOR_NETWORK) Q_cooling_nom_W = Q_cooling_max_W * (1 + Q_MARGIN_FOR_NETWORK) # Modify the individual with the extra GHP constraint try: cCheck.GHPCheck(individual, locator, Q_heating_nom_W, gv) except: print "No GHP constraint check possible \n" # Export to context individual_number = calc_individual_number(locator) master_to_slave_vars = evaluation.calc_master_to_slave_variables( individual, Q_heating_max_W, Q_cooling_max_W, building_names, individual_number, GENERATION_NUMBER) master_to_slave_vars.network_data_file_heating = network_file_name_heating master_to_slave_vars.network_data_file_cooling = network_file_name_cooling master_to_slave_vars.total_buildings = len(building_names) if master_to_slave_vars.number_of_buildings_connected_heating > 1: if DHN_barcode.count("0") == 0: master_to_slave_vars.fNameTotalCSV = locator.get_total_demand() else: master_to_slave_vars.fNameTotalCSV = os.path.join( locator.get_optimization_network_totals_folder(), "Total_%(DHN_barcode)s.csv" % locals()) else: master_to_slave_vars.fNameTotalCSV = locator.get_optimization_substations_total_file( DHN_barcode) if master_to_slave_vars.number_of_buildings_connected_cooling > 1: if DCN_barcode.count("0") == 0: master_to_slave_vars.fNameTotalCSV = locator.get_total_demand() else: master_to_slave_vars.fNameTotalCSV = os.path.join( locator.get_optimization_network_totals_folder(), "Total_%(DCN_barcode)s.csv" % locals()) else: master_to_slave_vars.fNameTotalCSV = locator.get_optimization_substations_total_file( DCN_barcode) # slave optimization of heating networks if config.optimization.isheating: if DHN_barcode.count("1") > 0: (slavePrim, slaveCO2, slaveCosts, QUncoveredDesign, QUncoveredAnnual) = sM.slave_main(locator, master_to_slave_vars, solar_features, gv, config, prices) else: slaveCO2 = 0 slaveCosts = 0 slavePrim = 0 else: slaveCO2 = 0 slaveCosts = 0 slavePrim = 0 costs += slaveCosts CO2 += slaveCO2 prim += slavePrim # slave optimization of cooling networks if gv.ZernezFlag == 1: coolCosts, coolCO2, coolPrim = 0, 0, 0 elif config.optimization.iscooling and DCN_barcode.count("1") > 0: reduced_timesteps_flag = config.supply_system_simulation.reduced_timesteps (coolCosts, coolCO2, coolPrim) = coolMain.coolingMain(locator, master_to_slave_vars, network_features, gv, prices, lca, config, reduced_timesteps_flag) # if reduced_timesteps_flag: # # reduced timesteps simulation for a month (May) # coolCosts = coolCosts * (8760/(3624/2880)) # coolCO2 = coolCO2 * (8760/(3624/2880)) # coolPrim = coolPrim * (8760/(3624/2880)) # # FIXME: check results else: coolCosts, coolCO2, coolPrim = 0, 0, 0 # print "Add extra costs" # add costs of disconnected buildings (best configuration) (addCosts, addCO2, addPrim) = eM.addCosts(DHN_barcode, DCN_barcode, building_names, locator, master_to_slave_vars, QUncoveredDesign, QUncoveredAnnual, solar_features, network_features, gv, config, prices, lca) # recalculate the addCosts by substracting the decentralized costs and add back to corresponding supply system Cost_diff, CO2_diff, Prim_diff = calc_decentralized_building_costs( config, locator, master_to_slave_vars, DHN_barcode, DCN_barcode, building_names) addCosts = addCosts + Cost_diff addCO2 = addCO2 + CO2_diff addPrim = addPrim + Prim_diff # add Capex and Opex of PV data_electricity = pd.read_csv( os.path.join( locator. get_optimization_slave_electricity_activation_pattern_cooling( individual_number, GENERATION_NUMBER))) total_area_for_pv = data_electricity['Area_PV_m2'].max() # remove the area installed with solar collectors sc_installed_area = 0 if config.supply_system_simulation.decentralized_systems == 'Single-effect Absorption Chiller': for (index, building_name) in zip(DCN_barcode, building_names): if index == "0": sc_installed_area = sc_installed_area + pd.read_csv( locator.PV_results(building_name))['Area_PV_m2'].max() pv_installed_area = total_area_for_pv - sc_installed_area Capex_a_PV, Opex_fixed_PV = calc_Cinv_pv(pv_installed_area, locator, config) pv_annual_production_kWh = (data_electricity['E_PV_W'].sum()) / 1000 # electricity calculations data_network_electricity = pd.read_csv( os.path.join( locator. get_optimization_slave_electricity_activation_pattern_cooling( individual_number, GENERATION_NUMBER))) data_cooling = pd.read_csv( os.path.join( locator.get_optimization_slave_cooling_activation_pattern( individual_number, GENERATION_NUMBER))) total_demand = pd.read_csv(locator.get_total_demand()) building_names = total_demand.Name.values total_electricity_demand_W = data_network_electricity['E_total_req_W'] E_decentralized_appliances_W = np.zeros(8760) for i, name in zip( DCN_barcode, building_names ): # adding the electricity demand from the decentralized buildings if i is '0': building_demand = pd.read_csv(locator.get_demand_results_folder() + '//' + name + ".csv", usecols=['E_sys_kWh']) E_decentralized_appliances_W += building_demand['E_sys_kWh'] * 1000 total_electricity_demand_W = total_electricity_demand_W.add( E_decentralized_appliances_W) E_for_hot_water_demand_W = np.zeros(8760) for i, name in zip( DCN_barcode, building_names ): # adding the electricity demand for hot water from all buildings building_demand = pd.read_csv(locator.get_demand_results_folder() + '//' + name + ".csv", usecols=['E_ww_kWh']) E_for_hot_water_demand_W += building_demand['E_ww_kWh'] * 1000 total_electricity_demand_W = total_electricity_demand_W.add( E_for_hot_water_demand_W) # Electricity of Energy Systems lca = lca_calculations(locator, config) E_VCC_W = data_cooling['Opex_var_VCC'] / lca.ELEC_PRICE E_VCC_backup_W = data_cooling['Opex_var_VCC_backup'] / lca.ELEC_PRICE E_ACH_W = data_cooling['Opex_var_ACH'] / lca.ELEC_PRICE E_CT_W = abs(data_cooling['Opex_var_CT']) / lca.ELEC_PRICE total_electricity_demand_W = total_electricity_demand_W.add(E_VCC_W) total_electricity_demand_W = total_electricity_demand_W.add(E_VCC_backup_W) total_electricity_demand_W = total_electricity_demand_W.add(E_ACH_W) total_electricity_demand_W = total_electricity_demand_W.add(E_CT_W) E_from_CHP_W = data_network_electricity[ 'E_CHP_to_directload_W'] + data_network_electricity['E_CHP_to_grid_W'] E_from_PV_W = data_network_electricity[ 'E_PV_to_directload_W'] + data_network_electricity['E_PV_to_grid_W'] E_CHP_to_directload_W = np.zeros(8760) E_CHP_to_grid_W = np.zeros(8760) E_PV_to_directload_W = np.zeros(8760) E_PV_to_grid_W = np.zeros(8760) E_from_grid_W = np.zeros(8760) # modify simulation timesteps if reduced_timesteps_flag == False: start_t = 0 stop_t = 8760 else: # timesteps in May start_t = 2880 stop_t = 3624 timesteps = range(start_t, stop_t) for hour in timesteps: E_hour_W = total_electricity_demand_W[hour] if E_hour_W > 0: if E_from_PV_W[hour] > E_hour_W: E_PV_to_directload_W[hour] = E_hour_W E_PV_to_grid_W[hour] = E_from_PV_W[ hour] - total_electricity_demand_W[hour] E_hour_W = 0 else: E_hour_W = E_hour_W - E_from_PV_W[hour] E_PV_to_directload_W[hour] = E_from_PV_W[hour] if E_from_CHP_W[hour] > E_hour_W: E_CHP_to_directload_W[hour] = E_hour_W E_CHP_to_grid_W[hour] = E_from_CHP_W[hour] - E_hour_W E_hour_W = 0 else: E_hour_W = E_hour_W - E_from_CHP_W[hour] E_CHP_to_directload_W[hour] = E_from_CHP_W[hour] E_from_grid_W[hour] = E_hour_W date = data_network_electricity.DATE.values results = pd.DataFrame( { "DATE": date, "E_total_req_W": total_electricity_demand_W, "E_from_grid_W": E_from_grid_W, "E_VCC_W": E_VCC_W, "E_VCC_backup_W": E_VCC_backup_W, "E_ACH_W": E_ACH_W, "E_CT_W": E_CT_W, "E_PV_to_directload_W": E_PV_to_directload_W, "E_CHP_to_directload_W": E_CHP_to_directload_W, "E_CHP_to_grid_W": E_CHP_to_grid_W, "E_PV_to_grid_W": E_PV_to_grid_W, "E_for_hot_water_demand_W": E_for_hot_water_demand_W, "E_decentralized_appliances_W": E_decentralized_appliances_W, "E_total_to_grid_W_negative": -E_PV_to_grid_W - E_CHP_to_grid_W } ) # let's keep this negative so it is something exported, we can use it in the graphs of likelihood if reduced_timesteps_flag: reduced_el_costs = ((results['E_from_grid_W'].sum() + results['E_total_to_grid_W_negative'].sum()) * lca.ELEC_PRICE) electricity_costs = reduced_el_costs * (8760 / (stop_t - start_t)) else: electricity_costs = ((results['E_from_grid_W'].sum() + results['E_total_to_grid_W_negative'].sum()) * lca.ELEC_PRICE) # emission from data data_emissions = pd.read_csv( os.path.join( locator.get_optimization_slave_investment_cost_detailed( individual_number, GENERATION_NUMBER))) update_PV_emission = abs( 2 * data_emissions['CO2_PV_disconnected']).values[0] # kg-CO2 update_PV_primary = abs( 2 * data_emissions['Eprim_PV_disconnected']).values[0] # MJ oil-eq costs += addCosts + coolCosts + electricity_costs + Capex_a_PV + Opex_fixed_PV CO2 = CO2 + addCO2 + coolCO2 - update_PV_emission prim = prim + addPrim + coolPrim - update_PV_primary # Converting costs into float64 to avoid longer values costs = (np.float64(costs) / 1e6).round(2) # $ to Mio$ CO2 = (np.float64(CO2) / 1e6).round(2) # kg to kilo-ton prim = (np.float64(prim) / 1e6).round(2) # MJ to TJ # add electricity costs corresponding to # print ('Additional costs = ' + str(addCosts)) # print ('Additional CO2 = ' + str(addCO2)) # print ('Additional prim = ' + str(addPrim)) print('Total annualized costs [USD$(2015) Mio/yr] = ' + str(costs)) print('Green house gas emission [kton-CO2/yr] = ' + str(CO2)) print('Primary energy [TJ-oil-eq/yr] = ' + str(prim)) results = { 'TAC_Mio_per_yr': [costs.round(2)], 'CO2_kton_per_yr': [CO2.round(2)], 'Primary_Energy_TJ_per_yr': [prim.round(2)] } results_df = pd.DataFrame(results) results_path = os.path.join( locator.get_optimization_slave_results_folder(GENERATION_NUMBER), 'ind_' + str(individual_number) + '_results.csv') results_df.to_csv(results_path) with open(locator.get_optimization_checkpoint_initial(), "wb") as fp: pop = [] g = GENERATION_NUMBER epsInd = [] invalid_ind = [] fitnesses = [] capacities = [] disconnected_capacities = [] halloffame = [] halloffame_fitness = [] euclidean_distance = [] spread = [] cp = dict(population=pop, generation=g, epsIndicator=epsInd, testedPop=invalid_ind, population_fitness=fitnesses, capacities=capacities, disconnected_capacities=disconnected_capacities, halloffame=halloffame, halloffame_fitness=halloffame_fitness, euclidean_distance=euclidean_distance, spread=spread) json.dump(cp, fp) return costs, CO2, prim, master_to_slave_vars, individual
def evaluation_main(individual, building_names, locator, extraCosts, extraCO2, extraPrim, solar_features, network_features, gv, config, prices, lca, ind_num, gen): """ This function evaluates an individual :param individual: list with values of the individual :param building_names: list with names of buildings :param locator: locator class :param extraCosts: costs calculated before optimization of specific energy services (process heat and electricity) :param extraCO2: green house gas emissions calculated before optimization of specific energy services (process heat and electricity) :param extraPrim: primary energy calculated before optimization ofr specific energy services (process heat and electricity) :param solar_features: solar features call to class :param network_features: network features call to class :param gv: global variables class :param optimization_constants: class containing constants used in optimization :param config: configuration file :param prices: class of prices used in optimization :type individual: list :type building_names: list :type locator: string :type extraCosts: float :type extraCO2: float :type extraPrim: float :type solar_features: class :type network_features: class :type gv: class :type optimization_constants: class :type config: class :type prices: class :return: Resulting values of the objective function. costs, CO2, prim :rtype: tuple """ # Check the consistency of the individual or create a new one individual = check_invalid(individual, len(building_names), config) # Initialize objective functions costs, CO2 and primary energy costs = extraCosts CO2 = extraCO2 prim = extraPrim QUncoveredDesign = 0 QUncoveredAnnual = 0 # Create the string representation of the individual DHN_barcode, DCN_barcode, DHN_configuration, DCN_configuration = sFn.individual_to_barcode( individual, building_names) if DHN_barcode.count("1") == gv.num_tot_buildings: network_file_name_heating = "Network_summary_result_all.csv" Q_DHNf_W = pd.read_csv( locator.get_optimization_network_all_results_summary('all'), usecols=["Q_DHNf_W"]).values Q_heating_max_W = Q_DHNf_W.max() elif DHN_barcode.count("1") == 0: network_file_name_heating = "Network_summary_result_all.csv" Q_heating_max_W = 0 else: network_file_name_heating = "Network_summary_result_" + hex( int(str(DHN_barcode), 2)) + ".csv" if not os.path.exists( locator.get_optimization_network_results_summary(DHN_barcode)): total_demand = sFn.createTotalNtwCsv(DHN_barcode, locator) building_names = total_demand.Name.values # Run the substation and distribution routines sMain.substation_main(locator, total_demand, building_names, DHN_configuration, DCN_configuration, Flag=True) nM.network_main(locator, total_demand, building_names, config, gv, DHN_barcode) Q_DHNf_W = pd.read_csv( locator.get_optimization_network_results_summary(DHN_barcode), usecols=["Q_DHNf_W"]).values Q_heating_max_W = Q_DHNf_W.max() if DCN_barcode.count("1") == gv.num_tot_buildings: network_file_name_cooling = "Network_summary_result_all.csv" if individual[ N_HEAT * 2] == 1: # if heat recovery is ON, then only need to satisfy cooling load of space cooling and refrigeration Q_DCNf_W = pd.read_csv( locator.get_optimization_network_all_results_summary('all'), usecols=["Q_DCNf_space_cooling_and_refrigeration_W"]).values else: Q_DCNf_W = pd.read_csv( locator.get_optimization_network_all_results_summary('all'), usecols=[ "Q_DCNf_space_cooling_data_center_and_refrigeration_W" ]).values Q_cooling_max_W = Q_DCNf_W.max() elif DCN_barcode.count("1") == 0: network_file_name_cooling = "Network_summary_result_all.csv" Q_cooling_max_W = 0 else: network_file_name_cooling = "Network_summary_result_" + hex( int(str(DCN_barcode), 2)) + ".csv" if not os.path.exists( locator.get_optimization_network_results_summary(DCN_barcode)): total_demand = sFn.createTotalNtwCsv(DCN_barcode, locator) building_names = total_demand.Name.values # Run the substation and distribution routines sMain.substation_main(locator, total_demand, building_names, DHN_configuration, DCN_configuration, Flag=True) nM.network_main(locator, total_demand, building_names, config, gv, DCN_barcode) if individual[ N_HEAT * 2] == 1: # if heat recovery is ON, then only need to satisfy cooling load of space cooling and refrigeration Q_DCNf_W = pd.read_csv( locator.get_optimization_network_results_summary(DCN_barcode), usecols=["Q_DCNf_space_cooling_and_refrigeration_W"]).values else: Q_DCNf_W = pd.read_csv( locator.get_optimization_network_results_summary(DCN_barcode), usecols=[ "Q_DCNf_space_cooling_data_center_and_refrigeration_W" ]).values Q_cooling_max_W = Q_DCNf_W.max() Q_heating_nom_W = Q_heating_max_W * (1 + Q_MARGIN_FOR_NETWORK) Q_cooling_nom_W = Q_cooling_max_W * (1 + Q_MARGIN_FOR_NETWORK) # Modify the individual with the extra GHP constraint try: cCheck.GHPCheck(individual, locator, Q_heating_nom_W, gv) except: print "No GHP constraint check possible \n" # Export to context master_to_slave_vars = calc_master_to_slave_variables( individual, Q_heating_max_W, Q_cooling_max_W, building_names, ind_num, gen) master_to_slave_vars.network_data_file_heating = network_file_name_heating master_to_slave_vars.network_data_file_cooling = network_file_name_cooling master_to_slave_vars.total_buildings = len(building_names) if master_to_slave_vars.number_of_buildings_connected_heating > 1: if DHN_barcode.count("0") == 0: master_to_slave_vars.fNameTotalCSV = locator.get_total_demand() else: master_to_slave_vars.fNameTotalCSV = os.path.join( locator.get_optimization_network_totals_folder(), "Total_%(DHN_barcode)s.csv" % locals()) else: master_to_slave_vars.fNameTotalCSV = locator.get_optimization_substations_total_file( DHN_barcode) if master_to_slave_vars.number_of_buildings_connected_cooling > 1: if DCN_barcode.count("0") == 0: master_to_slave_vars.fNameTotalCSV = locator.get_total_demand() else: master_to_slave_vars.fNameTotalCSV = os.path.join( locator.get_optimization_network_totals_folder(), "Total_%(DCN_barcode)s.csv" % locals()) else: master_to_slave_vars.fNameTotalCSV = locator.get_optimization_substations_total_file( DCN_barcode) if config.optimization.isheating: if DHN_barcode.count("1") > 0: (slavePrim, slaveCO2, slaveCosts, QUncoveredDesign, QUncoveredAnnual) = sM.slave_main(locator, master_to_slave_vars, solar_features, gv, config, prices, lca) else: slaveCO2 = 0 slaveCosts = 0 slavePrim = 0 else: slaveCO2 = 0 slaveCosts = 0 slavePrim = 0 costs += slaveCosts CO2 += slaveCO2 prim += slavePrim if gv.ZernezFlag == 1: coolCosts, coolCO2, coolPrim = 0, 0, 0 elif config.optimization.iscooling: reduced_timesteps_flag = False (coolCosts, coolCO2, coolPrim) = coolMain.coolingMain(locator, master_to_slave_vars, network_features, gv, prices, lca, config, reduced_timesteps_flag) else: coolCosts, coolCO2, coolPrim = 0, 0, 0 print "Add extra costs" (addCosts, addCO2, addPrim) = eM.addCosts(DHN_barcode, DCN_barcode, building_names, locator, master_to_slave_vars, QUncoveredDesign, QUncoveredAnnual, solar_features, network_features, gv, config, prices, lca) costs += addCosts + coolCosts CO2 += addCO2 + coolCO2 prim += addPrim + coolPrim # Converting costs into float64 to avoid longer values costs = np.float64(costs) CO2 = np.float64(CO2) prim = np.float64(prim) print('Total costs = ' + str(costs)) print('Total CO2 = ' + str(CO2)) print('Total prim = ' + str(prim)) return costs, CO2, prim, master_to_slave_vars, individual