def calc_pareto_Qhp(locator, total_demand, prices, lca): """ This function calculates the contribution to the pareto optimal results of process heating, :param locator: locator class :param total_demand: dataframe with building demand :type locator: class :type total_demand: class :return: hpCosts, hpCO2, hpPrim :rtype: tuple """ hpCosts = 0 hpCO2 = 0 hpPrim = 0 boiler_cost_data = pd.read_excel(locator.get_database_conversion_systems(), sheet_name="Boiler") if total_demand["Qhpro_sys_MWhyr"].sum() > 0: df = total_demand[total_demand.Qhpro_sys_MWhyr != 0] for name in df.Name: # Extract process heat needs Qhpro_sys_kWh = pd.read_csv(locator.get_demand_results_file(name), usecols=["Qhpro_sys_kWh" ]).Qhpro_sys_kWh.values Qnom_Wh = 0 Qannual_Wh = 0 # Operation costs / CO2 / Prim for i in range(HOURS_IN_YEAR): Qgas_Wh = Qhpro_sys_kWh[ i] * 1E3 / BOILER_ETA_HP # [Wh] Assumed 0.9 efficiency if Qgas_Wh < Qnom_Wh: Qnom_Wh = Qgas_Wh Qannual_Wh += Qgas_Wh hpCosts += Qgas_Wh * prices.NG_PRICE # [CHF] hpCO2 += Qgas_Wh * WH_TO_J / 1.0E6 * lca.NG_BACKUPBOILER_TO_CO2_STD / 1E3 # [ton CO2] hpPrim += Qgas_Wh * WH_TO_J / 1.0E6 * lca.NG_BACKUPBOILER_TO_OIL_STD # [MJ-oil-eq] # Investment costs Capex_a_hp_USD, Opex_fixed_hp_USD, Capex_hp_USD = boiler.calc_Cinv_boiler( Qnom_Wh, 'BO1', boiler_cost_data) hpCosts += (Capex_a_hp_USD + Opex_fixed_hp_USD) else: hpCosts = hpCO2 = hpPrim = 0 return hpCosts, hpCO2, hpPrim
def calc_pareto_Qhp(locator, total_demand, prices, lca, config): """ This function calculates the contribution to the pareto optimal results of process heating, :param locator: locator class :param total_demand: dataframe with building demand :param gv: global variables :type locator: class :type total_demand: class :type gv: class :return: hpCosts, hpCO2, hpPrim :rtype: tuple """ hpCosts = 0 hpCO2 = 0 hpPrim = 0 if total_demand["Qhpro_sys_MWhyr"].sum() > 0: df = total_demand[total_demand.Qhpro_sys_MWhyr != 0] for name in df.Name: # Extract process heat needs Qhpro_sys = pd.read_csv(locator.get_demand_results_file(name), usecols=["Qhpro_sys_kWh" ]).Qhpro_sys_kWh.values Qnom = 0 Qannual = 0 # Operation costs / CO2 / Prim for i in range(8760): Qgas = Qhpro_sys[ i] * 1E3 / BOILER_ETA_HP # [Wh] Assumed 0.9 efficiency if Qgas < Qnom: Qnom = Qgas * (1 + SIZING_MARGIN) Qannual += Qgas hpCosts += Qgas * prices.NG_PRICE # [CHF] hpCO2 += Qgas * 3600E-6 * lca.NG_BACKUPBOILER_TO_CO2_STD # [kg CO2] hpPrim += Qgas * 3600E-6 * lca.NG_BACKUPBOILER_TO_OIL_STD # [MJ-oil-eq] # Investment costs Capex_a_hp, Opex_fixed_hp = boiler.calc_Cinv_boiler( Qnom, locator, config, 'BO1') hpCosts += (Capex_a_hp + Opex_fixed_hp) else: hpCosts = hpCO2 = hpPrim = 0 return hpCosts, hpCO2, hpPrim
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 disconnected_heating_for_building(building_name, supply_systems, T_ground_K, geothermal_potential_data, lca, locator, prices): print('{building_name} disconnected heating supply system simulations...'. format(building_name=building_name)) GHP_cost_data = supply_systems.HP BH_cost_data = supply_systems.BH boiler_cost_data = supply_systems.Boiler # run substation model to derive temperatures of the building substation_results = pd.read_csv( locator.get_optimization_substations_results_file( building_name, "DH", "")) q_load_Wh = np.vectorize(calc_new_load)( substation_results["mdot_DH_result_kgpers"], substation_results["T_supply_DH_result_K"], substation_results["T_return_DH_result_K"]) Qnom_W = q_load_Wh.max() # Create empty matrices Opex_a_var_USD = np.zeros((13, 7)) Capex_total_USD = np.zeros((13, 7)) Capex_a_USD = np.zeros((13, 7)) Opex_a_fixed_USD = np.zeros((13, 7)) Capex_opex_a_fixed_only_USD = np.zeros((13, 7)) Opex_a_USD = np.zeros((13, 7)) GHG_tonCO2 = np.zeros((13, 7)) # indicate supply technologies for each configuration Opex_a_var_USD[0][0] = 1 # Boiler NG Opex_a_var_USD[1][1] = 1 # Boiler BG Opex_a_var_USD[2][2] = 1 # Fuel Cell resourcesRes = np.zeros((13, 4)) Q_Boiler_for_GHP_W = np.zeros( (10, 1)) # Save peak capacity of GHP Backup Boilers GHP_el_size_W = np.zeros((10, 1)) # Save peak capacity of GHP # save supply system activation of all supply configurations heating_dispatch = {} # Supply with the Boiler / FC / GHP Tret_K = substation_results["T_return_DH_result_K"].values Tsup_K = substation_results["T_supply_DH_result_K"].values mdot_kgpers = substation_results["mdot_DH_result_kgpers"].values ## Start Hourly calculation print(building_name, ' decentralized heating supply systems simulations...') Tret_K = np.where(Tret_K > 0.0, Tret_K, Tsup_K) ## 0: Boiler NG BoilerEff = np.vectorize(Boiler.calc_Cop_boiler)(q_load_Wh, Qnom_W, Tret_K) Qgas_to_Boiler_Wh = np.divide(q_load_Wh, BoilerEff, out=np.zeros_like(q_load_Wh), where=BoilerEff != 0.0) Boiler_Status = np.where(Qgas_to_Boiler_Wh > 0.0, 1, 0) # add costs Opex_a_var_USD[0][4] += sum(prices.NG_PRICE * Qgas_to_Boiler_Wh) # CHF GHG_tonCO2[0][5] += sum( calc_emissions_Whyr_to_tonCO2yr(Qgas_to_Boiler_Wh, lca.NG_TO_CO2_EQ)) # ton CO2 # add activation resourcesRes[0][0] += sum(q_load_Wh) # q from NG heating_dispatch[0] = { 'Q_Boiler_gen_directload_W': q_load_Wh, 'Boiler_Status': Boiler_Status, 'NG_Boiler_req_W': Qgas_to_Boiler_Wh, 'E_hs_ww_req_W': np.zeros(8760) } ## 1: Boiler BG # add costs Opex_a_var_USD[1][4] += sum(prices.BG_PRICE * Qgas_to_Boiler_Wh) # CHF GHG_tonCO2[1][5] += sum( calc_emissions_Whyr_to_tonCO2yr(Qgas_to_Boiler_Wh, lca.NG_TO_CO2_EQ)) # ton CO2 # add activation resourcesRes[1][1] += sum(q_load_Wh) # q from BG heating_dispatch[1] = { 'Q_Boiler_gen_directload_W': q_load_Wh, 'Boiler_Status': Boiler_Status, 'BG_Boiler_req_W': Qgas_to_Boiler_Wh, 'E_hs_ww_req_W': np.zeros(8760) } ## 2: Fuel Cell (FC_Effel, FC_Effth) = np.vectorize(FC.calc_eta_FC)(q_load_Wh, Qnom_W, 1, "B") Qgas_to_FC_Wh = q_load_Wh / (FC_Effth + FC_Effel ) # FIXME: should be q_load_Wh/FC_Effth? el_from_FC_Wh = Qgas_to_FC_Wh * FC_Effel FC_Status = np.where(Qgas_to_FC_Wh > 0.0, 1, 0) # add variable costs, emissions and primary energy Opex_a_var_USD[2][4] += sum( prices.NG_PRICE * Qgas_to_FC_Wh - prices.ELEC_PRICE_EXPORT * el_from_FC_Wh) # CHF, extra electricity sold to grid GHG_tonCO2_from_FC = (0.0874 * Qgas_to_FC_Wh * 3600E-6 + 773 * 0.45 * el_from_FC_Wh * 1E-6 - lca.EL_TO_CO2_EQ * el_from_FC_Wh * 3600E-6) / 1E3 GHG_tonCO2[2][5] += sum(GHG_tonCO2_from_FC) # tonCO2 # 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/ # add activation resourcesRes[2][0] = sum(q_load_Wh) # q from NG resourcesRes[2][2] = sum(el_from_FC_Wh) # el for GHP # FIXME: el from FC heating_dispatch[2] = { 'Q_Fuelcell_gen_directload_W': q_load_Wh, 'Fuelcell_Status': FC_Status, 'NG_FuelCell_req_W': Qgas_to_FC_Wh, 'E_Fuelcell_gen_export_W': el_from_FC_Wh, 'E_hs_ww_req_W': np.zeros(8760) } # 3-13: Boiler NG + GHP for i in range(10): # set nominal size for Boiler and GHP QnomBoiler_W = i / 10.0 * Qnom_W QnomGHP_W = Qnom_W - QnomBoiler_W # GHP operation Texit_GHP_nom_K = QnomGHP_W / (mdot_kgpers * HEAT_CAPACITY_OF_WATER_JPERKGK) + Tret_K el_GHP_Wh, q_load_NG_Boiler_Wh, \ qhot_missing_Wh, \ Texit_GHP_K, q_from_GHP_Wh = np.vectorize(calc_GHP_operation)(QnomGHP_W, T_ground_K, Texit_GHP_nom_K, Tret_K, Tsup_K, mdot_kgpers, q_load_Wh) GHP_el_size_W[i][0] = max(el_GHP_Wh) GHP_Status = np.where(q_from_GHP_Wh > 0.0, 1, 0) # GHP Backup Boiler operation if max(qhot_missing_Wh) > 0.0: print("GHP unable to cover the whole demand, boiler activated!") Qnom_GHP_Backup_Boiler_W = max(qhot_missing_Wh) BoilerEff = np.vectorize(Boiler.calc_Cop_boiler)( qhot_missing_Wh, Qnom_GHP_Backup_Boiler_W, Texit_GHP_K) Qgas_to_GHPBoiler_Wh = np.divide( qhot_missing_Wh, BoilerEff, out=np.zeros_like(qhot_missing_Wh), where=BoilerEff != 0.0) else: Qgas_to_GHPBoiler_Wh = np.zeros(q_load_Wh.shape[0]) Qnom_GHP_Backup_Boiler_W = 0.0 Q_Boiler_for_GHP_W[i][0] = Qnom_GHP_Backup_Boiler_W GHPbackupBoiler_Status = np.where(qhot_missing_Wh > 0.0, 1, 0) # NG Boiler operation BoilerEff = np.vectorize(Boiler.calc_Cop_boiler)(q_load_NG_Boiler_Wh, QnomBoiler_W, Texit_GHP_K) Qgas_to_Boiler_Wh = np.divide(q_load_NG_Boiler_Wh, BoilerEff, out=np.zeros_like(q_load_NG_Boiler_Wh), where=BoilerEff != 0.0) Boiler_Status = np.where(q_load_NG_Boiler_Wh > 0.0, 1, 0) # add costs # electricity el_total_Wh = el_GHP_Wh Opex_a_var_USD[3 + i][4] += sum(prices.ELEC_PRICE * el_total_Wh) # CHF GHG_tonCO2[3 + i][5] += sum( calc_emissions_Whyr_to_tonCO2yr(el_total_Wh, lca.EL_TO_CO2_EQ)) # ton CO2 # gas Q_gas_total_Wh = Qgas_to_GHPBoiler_Wh + Qgas_to_Boiler_Wh Opex_a_var_USD[3 + i][4] += sum(prices.NG_PRICE * Q_gas_total_Wh) # CHF GHG_tonCO2[3 + i][5] += sum( calc_emissions_Whyr_to_tonCO2yr(Q_gas_total_Wh, lca.NG_TO_CO2_EQ)) # ton CO2 # add activation resourcesRes[3 + i][0] = sum(qhot_missing_Wh + q_load_NG_Boiler_Wh) resourcesRes[3 + i][2] = sum(el_GHP_Wh) resourcesRes[3 + i][3] = sum(q_from_GHP_Wh) heating_dispatch[3 + i] = { 'Q_GHP_gen_directload_W': q_from_GHP_Wh, 'Q_BackupBoiler_gen_directload_W': qhot_missing_Wh, 'Q_Boiler_gen_directload_W': q_load_NG_Boiler_Wh, 'GHP_Status': GHP_Status, 'BackupBoiler_Status': GHPbackupBoiler_Status, 'Boiler_Status': Boiler_Status, 'NG_BackupBoiler_req_Wh': Qgas_to_GHPBoiler_Wh, 'NG_Boiler_req_Wh': Qgas_to_Boiler_Wh, 'E_hs_ww_req_W': el_GHP_Wh } # Add all costs # 0: Boiler NG Capex_a_Boiler_USD, Opex_a_fixed_Boiler_USD, Capex_Boiler_USD = Boiler.calc_Cinv_boiler( Qnom_W, 'BO1', boiler_cost_data) Capex_total_USD[0][0] = Capex_Boiler_USD Capex_a_USD[0][0] = Capex_a_Boiler_USD Opex_a_fixed_USD[0][0] = Opex_a_fixed_Boiler_USD Capex_opex_a_fixed_only_USD[0][ 0] = Capex_a_Boiler_USD + Opex_a_fixed_Boiler_USD # TODO:variable price? # 1: Boiler BG Capex_total_USD[1][0] = Capex_Boiler_USD Capex_a_USD[1][0] = Capex_a_Boiler_USD Opex_a_fixed_USD[1][0] = Opex_a_fixed_Boiler_USD Capex_opex_a_fixed_only_USD[1][ 0] = Capex_a_Boiler_USD + Opex_a_fixed_Boiler_USD # TODO:variable price? # 2: Fuel Cell Capex_a_FC_USD, Opex_fixed_FC_USD, Capex_FC_USD = FC.calc_Cinv_FC( Qnom_W, supply_systems.FC) Capex_total_USD[2][0] = Capex_FC_USD Capex_a_USD[2][0] = Capex_a_FC_USD Opex_a_fixed_USD[2][0] = Opex_fixed_FC_USD Capex_opex_a_fixed_only_USD[2][ 0] = Capex_a_FC_USD + Opex_fixed_FC_USD # TODO:variable price? # 3-13: BOILER + GHP for i in range(10): Opex_a_var_USD[3 + i][0] = i / 10.0 # Boiler share Opex_a_var_USD[3 + i][3] = 1 - i / 10.0 # GHP share # Get boiler costs QnomBoiler_W = i / 10.0 * Qnom_W Capex_a_Boiler_USD, Opex_a_fixed_Boiler_USD, Capex_Boiler_USD = Boiler.calc_Cinv_boiler( QnomBoiler_W, 'BO1', boiler_cost_data) Capex_total_USD[3 + i][0] += Capex_Boiler_USD Capex_a_USD[3 + i][0] += Capex_a_Boiler_USD Opex_a_fixed_USD[3 + i][0] += Opex_a_fixed_Boiler_USD Capex_opex_a_fixed_only_USD[3 + i][ 0] += Capex_a_Boiler_USD + Opex_a_fixed_Boiler_USD # TODO:variable price? # Get back up boiler costs Qnom_Backup_Boiler_W = Q_Boiler_for_GHP_W[i][0] Capex_a_GHPBoiler_USD, Opex_a_fixed_GHPBoiler_USD, Capex_GHPBoiler_USD = Boiler.calc_Cinv_boiler( Qnom_Backup_Boiler_W, 'BO1', boiler_cost_data) Capex_total_USD[3 + i][0] += Capex_GHPBoiler_USD Capex_a_USD[3 + i][0] += Capex_a_GHPBoiler_USD Opex_a_fixed_USD[3 + i][0] += Opex_a_fixed_GHPBoiler_USD Capex_opex_a_fixed_only_USD[3 + i][ 0] += Capex_a_GHPBoiler_USD + Opex_a_fixed_GHPBoiler_USD # TODO:variable price? # Get ground source heat pump costs Capex_a_GHP_USD, Opex_a_fixed_GHP_USD, Capex_GHP_USD = HP.calc_Cinv_GHP( GHP_el_size_W[i][0], GHP_cost_data, BH_cost_data) Capex_total_USD[3 + i][0] += Capex_GHP_USD Capex_a_USD[3 + i][0] += Capex_a_GHP_USD Opex_a_fixed_USD[3 + i][0] += Opex_a_fixed_GHP_USD Capex_opex_a_fixed_only_USD[3 + i][ 0] += Capex_a_GHP_USD + Opex_a_fixed_GHP_USD # TODO:variable price? # Best configuration Best = np.zeros((13, 1)) indexBest = 0 TAC_USD = np.zeros((13, 2)) TotalCO2 = np.zeros((13, 2)) for i in range(13): TAC_USD[i][0] = TotalCO2[i][0] = i Opex_a_USD[i][1] = Opex_a_fixed_USD[i][0] + +Opex_a_var_USD[i][4] TAC_USD[i][ 1] = Capex_opex_a_fixed_only_USD[i][0] + Opex_a_var_USD[i][4] TotalCO2[i][1] = GHG_tonCO2[i][5] CostsS = TAC_USD[np.argsort(TAC_USD[:, 1])] CO2S = TotalCO2[np.argsort(TotalCO2[:, 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.0) * Qnom_W areaAvail = geothermal_potential.loc[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 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 # Save results in csv file performance_results = { "Nominal heating load": Qnom_W, "Capacity_BaseBoiler_NG_W": Qnom_W * Opex_a_var_USD[:, 0], "Capacity_FC_NG_W": Qnom_W * Opex_a_var_USD[:, 2], "Capacity_GS_HP_W": Qnom_W * Opex_a_var_USD[:, 3], "TAC_USD": TAC_USD[:, 1], "Capex_a_USD": Capex_a_USD[:, 0], "Capex_total_USD": Capex_total_USD[:, 0], "Opex_fixed_USD": Opex_a_fixed_USD[:, 0], "Opex_var_USD": Opex_a_var_USD[:, 4], "GHG_tonCO2": GHG_tonCO2[:, 5], "Best configuration": Best[:, 0] } results_to_csv = pd.DataFrame(performance_results) fName_result = locator.get_optimization_decentralized_folder_building_result_heating( building_name) results_to_csv.to_csv(fName_result, sep=',', index=False) # save activation for the best supply system configuration best_activation_df = pd.DataFrame.from_dict(heating_dispatch[indexBest]) # best_activation_df.to_csv( locator. get_optimization_decentralized_folder_building_result_heating_activation( building_name), index=False)
def disconnected_buildings_heating_main(locator, total_demand, 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_decentralized_folder :rtype: Nonetype """ t0 = time.clock() prop_geometry = Gdf.from_file(locator.get_zone_geometry()) 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') geothermal_potential_data['Area_geo'] = geothermal_potential_data['Area'] weather_path = locator.get_weather_file() weather_data = epwreader.epw_reader(weather_path)[['year', 'drybulb_C', 'wetbulb_C', 'relhum_percent', 'windspd_ms', 'skytemp_C']] T_ground_K = calc_ground_temperature(locator, weather_data['drybulb_C'], depth_m=10) # This will calculate the substation state if all buildings where connected(this is how we study this) substation.substation_main_heating(locator, total_demand, building_names) for building_name in building_names: print('running for building %s') %(building_name) # run substation model to derive temperatures of the building substation_results = pd.read_csv(locator.get_optimization_substations_results_file(building_name, "DH", "")) q_load_Wh = np.vectorize(calc_new_load)(substation_results["mdot_DH_result_kgpers"], substation_results["T_supply_DH_result_K"], substation_results["T_return_DH_result_K"]) Qnom_W = q_load_Wh.max() # Create empty matrices Opex_a_var_USD = np.zeros((13, 7)) Capex_total_USD = np.zeros((13, 7)) Capex_a_USD = np.zeros((13, 7)) Opex_a_fixed_USD = np.zeros((13, 7)) Capex_opex_a_fixed_only_USD = np.zeros((13, 7)) Opex_a_USD = np.zeros((13, 7)) GHG_tonCO2 = np.zeros((13, 7)) PEN_MJoil = np.zeros((13, 7)) # indicate supply technologies for each configuration Opex_a_var_USD[0][0] = 1 # Boiler NG Opex_a_var_USD[1][1] = 1 # Boiler BG Opex_a_var_USD[2][2] = 1 # Fuel Cell resourcesRes = np.zeros((13, 4)) Q_Boiler_for_GHP_W = np.zeros((10, 1)) # Save peak capacity of GHP Backup Boilers GHP_el_size_W = np.zeros((10, 1)) # Save peak capacity of GHP # save supply system activation of all supply configurations heating_dispatch = {} # Supply with the Boiler / FC / GHP Tret_K = substation_results["T_return_DH_result_K"].values Tsup_K = substation_results["T_supply_DH_result_K"].values mdot_kgpers = substation_results["mdot_DH_result_kgpers"].values ## Start Hourly calculation print building_name, ' decentralized heating supply systems simulations...' Tret_K = np.where(Tret_K > 0.0, Tret_K, Tsup_K) ## 0: Boiler NG BoilerEff = np.vectorize(Boiler.calc_Cop_boiler)(q_load_Wh, Qnom_W, Tret_K) Qgas_to_Boiler_Wh = np.divide(q_load_Wh, BoilerEff, out=np.zeros_like(q_load_Wh), where=BoilerEff != 0.0) Boiler_Status = np.where(Qgas_to_Boiler_Wh > 0.0, 1, 0) # add costs Opex_a_var_USD[0][4] += sum(prices.NG_PRICE * Qgas_to_Boiler_Wh) # CHF GHG_tonCO2[0][5] += calc_emissions_Whyr_to_tonCO2yr(sum(Qgas_to_Boiler_Wh), lca.NG_TO_CO2_EQ) # ton CO2 PEN_MJoil[0][6] += calc_pen_Whyr_to_MJoilyr(sum(Qgas_to_Boiler_Wh), lca.NG_TO_OIL_EQ) # MJ-oil-eq # add activation resourcesRes[0][0] += sum(q_load_Wh) # q from NG heating_dispatch[0] = {'Q_Boiler_gen_directload_W': q_load_Wh, 'Boiler_Status': Boiler_Status, 'NG_Boiler_req_W': Qgas_to_Boiler_Wh, 'E_hs_ww_req_W': np.zeros(8760)} ## 1: Boiler BG # add costs Opex_a_var_USD[1][4] += sum(prices.BG_PRICE * Qgas_to_Boiler_Wh) # CHF GHG_tonCO2[1][5] += calc_emissions_Whyr_to_tonCO2yr(sum(Qgas_to_Boiler_Wh), lca.NG_TO_CO2_EQ) # ton CO2 PEN_MJoil[1][6] += calc_pen_Whyr_to_MJoilyr(sum(Qgas_to_Boiler_Wh), lca.NG_TO_OIL_EQ) # MJ-oil-eq # add activation resourcesRes[1][1] += sum(q_load_Wh) # q from BG heating_dispatch[1] = {'Q_Boiler_gen_directload_W': q_load_Wh, 'Boiler_Status': Boiler_Status, 'BG_Boiler_req_W': Qgas_to_Boiler_Wh, 'E_hs_ww_req_W': np.zeros(8760)} ## 2: Fuel Cell (FC_Effel, FC_Effth) = np.vectorize(FC.calc_eta_FC)(q_load_Wh, Qnom_W, 1, "B") Qgas_to_FC_Wh = q_load_Wh / (FC_Effth + FC_Effel) # FIXME: should be q_load_Wh/FC_Effth? el_from_FC_Wh = Qgas_to_FC_Wh * FC_Effel FC_Status = np.where(Qgas_to_FC_Wh > 0.0, 1, 0) # add variable costs, emissions and primary energy Opex_a_var_USD[2][4] += sum(prices.NG_PRICE * Qgas_to_FC_Wh - prices.ELEC_PRICE_EXPORT * el_from_FC_Wh) # CHF, extra electricity sold to grid GHG_tonCO2_from_FC = (0.0874 * Qgas_to_FC_Wh * 3600E-6 + 773 * 0.45 * el_from_FC_Wh * 1E-6 - lca.EL_TO_CO2_EQ * el_from_FC_Wh * 3600E-6) / 1E3 GHG_tonCO2[2][5] += sum(GHG_tonCO2_from_FC) # tonCO2 # 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/ PEN_MJoil_from_FC = 1.51 * Qgas_to_FC_Wh * 3600E-6 - lca.EL_TO_OIL_EQ * el_from_FC_Wh * 3600E-6 PEN_MJoil[2][6] += sum(PEN_MJoil_from_FC) # MJ-oil-eq # add activation resourcesRes[2][0] = sum(q_load_Wh) # q from NG resourcesRes[2][2] = sum(el_from_FC_Wh) # el for GHP # FIXME: el from FC heating_dispatch[2] = {'Q_Fuelcell_gen_directload_W': q_load_Wh, 'Fuelcell_Status': FC_Status, 'NG_FuelCell_req_W': Qgas_to_FC_Wh, 'E_Fuelcell_gen_export_W': el_from_FC_Wh, 'E_hs_ww_req_W': np.zeros(8760)} # 3-13: Boiler NG + GHP for i in range(10): # set nominal size for Boiler and GHP QnomBoiler_W = i / 10.0 * Qnom_W mdot_kgpers_Boiler = i / 10.0 * mdot_kgpers QnomGHP_W = Qnom_W - QnomBoiler_W # GHP operation Texit_GHP_nom_K = QnomGHP_W / (mdot_kgpers * HEAT_CAPACITY_OF_WATER_JPERKGK) + Tret_K el_GHP_Wh, q_load_NG_Boiler_Wh, \ qhot_missing_Wh, \ Texit_GHP_K, q_from_GHP_Wh = np.vectorize(calc_GHP_operation)(QnomGHP_W, T_ground_K, Texit_GHP_nom_K, Tret_K, Tsup_K, mdot_kgpers, q_load_Wh) GHP_el_size_W[i][0] = max(el_GHP_Wh) GHP_Status = np.where(q_from_GHP_Wh > 0.0, 1, 0) # GHP Backup Boiler operation if max(qhot_missing_Wh) > 0.0: print "GHP unable to cover the whole demand, boiler activated!" Qnom_GHP_Backup_Boiler_W = max(qhot_missing_Wh) BoilerEff = np.vectorize(Boiler.calc_Cop_boiler)(qhot_missing_Wh, Qnom_GHP_Backup_Boiler_W, Texit_GHP_K) Qgas_to_GHPBoiler_Wh = np.divide(qhot_missing_Wh, BoilerEff, out=np.zeros_like(qhot_missing_Wh), where=BoilerEff != 0.0) else: Qgas_to_GHPBoiler_Wh = np.zeros(q_load_Wh.shape[0]) Qnom_GHP_Backup_Boiler_W = 0.0 Q_Boiler_for_GHP_W[i][0] = Qnom_GHP_Backup_Boiler_W GHPbackupBoiler_Status = np.where(qhot_missing_Wh > 0.0, 1, 0) # NG Boiler operation BoilerEff = np.vectorize(Boiler.calc_Cop_boiler)(q_load_NG_Boiler_Wh, QnomBoiler_W, Texit_GHP_K) Qgas_to_Boiler_Wh = np.divide(q_load_NG_Boiler_Wh, BoilerEff, out=np.zeros_like(q_load_NG_Boiler_Wh), where=BoilerEff != 0.0) Boiler_Status = np.where(q_load_NG_Boiler_Wh > 0.0, 1, 0) # add costs # electricity el_total_Wh = el_GHP_Wh Opex_a_var_USD[3 + i][4] += sum(prices.ELEC_PRICE * el_total_Wh) # CHF GHG_tonCO2[3 + i][5] += calc_emissions_Whyr_to_tonCO2yr(sum(el_total_Wh), lca.EL_TO_CO2_EQ) # ton CO2 PEN_MJoil[3 + i][6] += calc_pen_Whyr_to_MJoilyr(sum(el_total_Wh), lca.EL_TO_OIL_EQ) # MJ-oil-eq # gas Q_gas_total_Wh = Qgas_to_GHPBoiler_Wh + Qgas_to_Boiler_Wh Opex_a_var_USD[3 + i][4] += sum(prices.NG_PRICE * Q_gas_total_Wh) # CHF GHG_tonCO2[3 + i][5] += calc_emissions_Whyr_to_tonCO2yr(sum(Q_gas_total_Wh), lca.NG_TO_CO2_EQ) # ton CO2 PEN_MJoil[3 + i][6] += calc_pen_Whyr_to_MJoilyr(sum(Q_gas_total_Wh), lca.NG_TO_OIL_EQ) # MJ-oil-eq # add activation resourcesRes[3 + i][0] = sum(qhot_missing_Wh + q_load_NG_Boiler_Wh) resourcesRes[3 + i][2] = sum(el_GHP_Wh) resourcesRes[3 + i][3] = sum(q_from_GHP_Wh) heating_dispatch[3 + i] = {'Q_GHP_gen_directload_W': q_from_GHP_Wh, 'Q_BackupBoiler_gen_directload_W': qhot_missing_Wh, 'Q_Boiler_gen_directload_W': q_load_NG_Boiler_Wh, 'GHP_Status': GHP_Status, 'BackupBoiler_Status': GHPbackupBoiler_Status, 'Boiler_Status': Boiler_Status, 'NG_BackupBoiler_req_Wh': Qgas_to_GHPBoiler_Wh, 'NG_Boiler_req_Wh': Qgas_to_Boiler_Wh, 'E_hs_ww_req_W': el_GHP_Wh} # Add all costs # 0: Boiler NG Capex_a_Boiler_USD, Opex_a_fixed_Boiler_USD, Capex_Boiler_USD = Boiler.calc_Cinv_boiler(Qnom_W, locator, config, 'BO1') Capex_total_USD[0][0] = Capex_Boiler_USD Capex_a_USD[0][0] = Capex_a_Boiler_USD Opex_a_fixed_USD[0][0] = Opex_a_fixed_Boiler_USD Capex_opex_a_fixed_only_USD[0][0] = Capex_a_Boiler_USD + Opex_a_fixed_Boiler_USD # TODO:variable price? # 1: Boiler BG Capex_total_USD[1][0] = Capex_Boiler_USD Capex_a_USD[1][0] = Capex_a_Boiler_USD Opex_a_fixed_USD[1][0] = Opex_a_fixed_Boiler_USD Capex_opex_a_fixed_only_USD[1][0] = Capex_a_Boiler_USD + Opex_a_fixed_Boiler_USD # TODO:variable price? # 2: Fuel Cell Capex_a_FC_USD, Opex_fixed_FC_USD, Capex_FC_USD = FC.calc_Cinv_FC(Qnom_W, locator, config) Capex_total_USD[2][0] = Capex_FC_USD Capex_a_USD[2][0] = Capex_a_FC_USD Opex_a_fixed_USD[2][0] = Opex_fixed_FC_USD Capex_opex_a_fixed_only_USD[2][0] = Capex_a_FC_USD + Opex_fixed_FC_USD # TODO:variable price? # 3-13: BOILER + GHP for i in range(10): Opex_a_var_USD[3 + i][0] = i / 10.0 # Boiler share Opex_a_var_USD[3 + i][3] = 1 - i / 10.0 # GHP share # Get boiler costs QnomBoiler_W = i / 10.0 * Qnom_W Capex_a_Boiler_USD, Opex_a_fixed_Boiler_USD, Capex_Boiler_USD = Boiler.calc_Cinv_boiler(QnomBoiler_W, locator, config, 'BO1') Capex_total_USD[3 + i][0] += Capex_Boiler_USD Capex_a_USD[3 + i][0] += Capex_a_Boiler_USD Opex_a_fixed_USD[3 + i][0] += Opex_a_fixed_Boiler_USD Capex_opex_a_fixed_only_USD[3 + i][ 0] += Capex_a_Boiler_USD + Opex_a_fixed_Boiler_USD # TODO:variable price? # Get back up boiler costs Qnom_Backup_Boiler_W = Q_Boiler_for_GHP_W[i][0] Capex_a_GHPBoiler_USD, Opex_a_fixed_GHPBoiler_USD, Capex_GHPBoiler_USD = Boiler.calc_Cinv_boiler( Qnom_Backup_Boiler_W, locator, config, 'BO1') Capex_total_USD[3 + i][0] += Capex_GHPBoiler_USD Capex_a_USD[3 + i][0] += Capex_a_GHPBoiler_USD Opex_a_fixed_USD[3 + i][0] += Opex_a_fixed_GHPBoiler_USD Capex_opex_a_fixed_only_USD[3 + i][ 0] += Capex_a_GHPBoiler_USD + Opex_a_fixed_GHPBoiler_USD # TODO:variable price? # Get ground source heat pump costs Capex_a_GHP_USD, Opex_a_fixed_GHP_USD, Capex_GHP_USD = HP.calc_Cinv_GHP(GHP_el_size_W[i][0], locator, config) Capex_total_USD[3 + i][0] += Capex_GHP_USD Capex_a_USD[3 + i][0] += Capex_a_GHP_USD Opex_a_fixed_USD[3 + i][0] += Opex_a_fixed_GHP_USD Capex_opex_a_fixed_only_USD[3 + i][0] += Capex_a_GHP_USD + Opex_a_fixed_GHP_USD # TODO:variable price? # Best configuration Best = np.zeros((13, 1)) indexBest = 0 TAC_USD = np.zeros((13, 2)) TotalCO2 = np.zeros((13, 2)) TotalPrim = np.zeros((13, 2)) for i in range(13): TAC_USD[i][0] = TotalCO2[i][0] = TotalPrim[i][0] = i Opex_a_USD[i][1] = Opex_a_fixed_USD[i][0] + + Opex_a_var_USD[i][4] TAC_USD[i][1] = Capex_opex_a_fixed_only_USD[i][0] + Opex_a_var_USD[i][4] TotalCO2[i][1] = GHG_tonCO2[i][5] TotalPrim[i][1] = PEN_MJoil[i][6] CostsS = TAC_USD[np.argsort(TAC_USD[:, 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.0) * Qnom_W 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 # Save results in csv file performance_results = { "Nominal heating load": Qnom_W, "Capacity_BaseBoiler_NG_W": Qnom_W * Opex_a_var_USD[:, 0], "Capacity_FC_NG_W": Qnom_W * Opex_a_var_USD[:, 2], "Capacity_GS_HP_W": Qnom_W * Opex_a_var_USD[:, 3], "TAC_USD": TAC_USD[:, 1], "Capex_a_USD": Capex_a_USD[:, 0], "Capex_total_USD": Capex_total_USD[:, 0], "Opex_fixed_USD": Opex_a_fixed_USD[:, 0], "Opex_var_USD": Opex_a_var_USD[:, 4], "GHG_tonCO2": GHG_tonCO2[:, 5], "PEN_MJoil": PEN_MJoil[:, 6], "Best configuration": Best[:, 0]} results_to_csv = pd.DataFrame(performance_results) fName_result = locator.get_optimization_decentralized_folder_building_result_heating(building_name) results_to_csv.to_csv(fName_result, sep=',') # save activation for the best supply system configuration best_activation_df = pd.DataFrame.from_dict(heating_dispatch[indexBest]) # best_activation_df.to_csv( locator.get_optimization_decentralized_folder_building_result_heating_activation(building_name)) print time.clock() - t0, "seconds process time for the Disconnected Building Routine \n"
def disconnected_cooling_for_building(building_name, supply_systems, lca, locator, prices, total_demand): chiller_prop = supply_systems.Absorption_chiller boiler_cost_data = supply_systems.Boiler scale = 'BUILDING' VCC_chiller = chiller_vapor_compression.VaporCompressionChiller( locator, scale) ## Calculate cooling loads for different combinations # SENSIBLE COOLING UNIT Qc_nom_SCU_W, \ T_re_SCU_K, \ T_sup_SCU_K, \ mdot_SCU_kgpers = calc_combined_cooling_loads(building_name, locator, total_demand, cooling_configuration=['scu']) # AIR HANDLING UNIT + AIR RECIRCULATION UNIT Qc_nom_AHU_ARU_W, \ T_re_AHU_ARU_K, \ T_sup_AHU_ARU_K, \ mdot_AHU_ARU_kgpers = calc_combined_cooling_loads(building_name, locator, total_demand, cooling_configuration=['ahu', 'aru']) # SENSIBLE COOLING UNIT + AIR HANDLING UNIT + AIR RECIRCULATION UNIT Qc_nom_AHU_ARU_SCU_W, \ T_re_AHU_ARU_SCU_K, \ T_sup_AHU_ARU_SCU_K, \ mdot_AHU_ARU_SCU_kgpers = calc_combined_cooling_loads(building_name, locator, total_demand, cooling_configuration=['ahu', 'aru', 'scu']) ## Get hourly hot water supply condition of Solar Collectors (SC) # Flate Plate Solar Collectors SC_FP_data, T_hw_in_FP_C, el_aux_SC_FP_Wh, q_sc_gen_FP_Wh = get_SC_data( building_name, locator, panel_type="FP") Capex_a_SC_FP_USD, Opex_SC_FP_USD, Capex_SC_FP_USD = solar_collector.calc_Cinv_SC( SC_FP_data['Area_SC_m2'][0], locator, panel_type="FP") # Evacuated Tube Solar Collectors SC_ET_data, T_hw_in_ET_C, el_aux_SC_ET_Wh, q_sc_gen_ET_Wh = get_SC_data( building_name, locator, panel_type="ET") Capex_a_SC_ET_USD, Opex_SC_ET_USD, Capex_SC_ET_USD = solar_collector.calc_Cinv_SC( SC_ET_data['Area_SC_m2'][0], locator, panel_type="ET") ## Calculate ground temperatures to estimate cold water supply temperatures for absorption chiller T_ground_K = calculate_ground_temperature( locator) # FIXME: change to outlet temperature from the cooling towers ## Initialize table to save results # save costs of all supply configurations operation_results = initialize_result_tables_for_supply_configurations( Qc_nom_SCU_W) # save supply system activation of all supply configurations cooling_dispatch = {} ## HOURLY OPERATION print('{building_name} decentralized cooling supply system simulations...'. format(building_name=building_name)) T_re_AHU_ARU_SCU_K = np.where(T_re_AHU_ARU_SCU_K > 0.0, T_re_AHU_ARU_SCU_K, T_sup_AHU_ARU_SCU_K) ## 0. DX operation print('{building_name} Config 0: Direct Expansion Units -> AHU,ARU,SCU'. format(building_name=building_name)) el_DX_hourly_Wh, \ q_DX_chw_Wh = np.vectorize(dx.calc_DX)(mdot_AHU_ARU_SCU_kgpers, T_sup_AHU_ARU_SCU_K, T_re_AHU_ARU_SCU_K) DX_Status = np.where(q_DX_chw_Wh > 0.0, 1, 0) # add electricity costs, CO2, PE operation_results[0][7] += sum(prices.ELEC_PRICE * el_DX_hourly_Wh) operation_results[0][8] += sum( calc_emissions_Whyr_to_tonCO2yr(el_DX_hourly_Wh, lca.EL_TO_CO2_EQ)) # ton CO2 # activation cooling_dispatch[0] = { 'Q_DX_AS_gen_directload_W': q_DX_chw_Wh, 'E_DX_AS_req_W': el_DX_hourly_Wh, 'E_cs_cre_cdata_req_W': el_DX_hourly_Wh, } # capacity of cooling technologies operation_results[0][0] = Qc_nom_AHU_ARU_SCU_W operation_results[0][1] = Qc_nom_AHU_ARU_SCU_W # 1: DX_AS system_COP = np.nanmedian( np.divide(q_DX_chw_Wh[None, :], el_DX_hourly_Wh[None, :]).flatten()) operation_results[0][9] += system_COP ## 1. VCC (AHU + ARU + SCU) + CT print( '{building_name} Config 1: Vapor Compression Chillers -> AHU,ARU,SCU'. format(building_name=building_name)) # VCC operation el_VCC_Wh, q_VCC_cw_Wh, q_VCC_chw_Wh = calc_VCC_operation( T_re_AHU_ARU_SCU_K, T_sup_AHU_ARU_SCU_K, mdot_AHU_ARU_SCU_kgpers, VCC_chiller) VCC_Status = np.where(q_VCC_chw_Wh > 0.0, 1, 0) # CT operation q_CT_VCC_to_AHU_ARU_SCU_Wh = q_VCC_cw_Wh Q_nom_CT_VCC_to_AHU_ARU_SCU_W, el_CT_Wh = calc_CT_operation( q_CT_VCC_to_AHU_ARU_SCU_Wh) # add costs el_total_Wh = el_VCC_Wh + el_CT_Wh operation_results[1][7] += sum(prices.ELEC_PRICE * el_total_Wh) # CHF operation_results[1][8] += sum( calc_emissions_Whyr_to_tonCO2yr(el_total_Wh, lca.EL_TO_CO2_EQ)) # ton CO2 system_COP_list = np.divide(q_VCC_chw_Wh[None, :], el_total_Wh[None, :]).flatten() system_COP = np.nansum( q_VCC_chw_Wh[None, :] * system_COP_list) / np.nansum( q_VCC_chw_Wh[None, :]) # weighted average of the system efficiency operation_results[1][9] += system_COP cooling_dispatch[1] = { 'Q_BaseVCC_AS_gen_directload_W': q_VCC_chw_Wh, 'E_BaseVCC_AS_req_W': el_VCC_Wh, 'E_CT_req_W': el_CT_Wh, 'E_cs_cre_cdata_req_W': el_total_Wh, } # capacity of cooling technologies operation_results[1][0] = Qc_nom_AHU_ARU_SCU_W operation_results[1][2] = Qc_nom_AHU_ARU_SCU_W # 2: BaseVCC_AS ## 2: SC_FP + single-effect ACH (AHU + ARU + SCU) + CT + Boiler + SC_FP print( '{building_name} Config 2: Flat-plate Solar Collectors + Single-effect Absorption chillers -> AHU,ARU,SCU' .format(building_name=building_name)) # ACH operation T_hw_out_single_ACH_K, \ el_single_ACH_Wh, \ q_cw_single_ACH_Wh, \ q_hw_single_ACH_Wh, \ q_chw_single_ACH_Wh = calc_ACH_operation(T_ground_K, T_hw_in_FP_C, T_re_AHU_ARU_SCU_K, T_sup_AHU_ARU_SCU_K, chiller_prop, mdot_AHU_ARU_SCU_kgpers, ACH_TYPE_SINGLE) ACH_Status = np.where(q_chw_single_ACH_Wh > 0.0, 1, 0) # CT operation q_CT_FP_to_single_ACH_to_AHU_ARU_SCU_Wh = q_cw_single_ACH_Wh Q_nom_CT_FP_to_single_ACH_to_AHU_ARU_SCU_W, el_CT_Wh = calc_CT_operation( q_CT_FP_to_single_ACH_to_AHU_ARU_SCU_Wh) # boiler operation q_gas_Boiler_FP_to_single_ACH_to_AHU_ARU_SCU_Wh, \ Q_nom_Boiler_FP_to_single_ACH_to_AHU_ARU_SCU_W, \ q_load_Boiler_FP_to_single_ACH_to_AHU_ARU_SCU_Wh = calc_boiler_operation(Qc_nom_AHU_ARU_SCU_W, T_hw_out_single_ACH_K, q_hw_single_ACH_Wh, q_sc_gen_FP_Wh) # add electricity costs el_total_Wh = el_single_ACH_Wh + el_aux_SC_FP_Wh + el_CT_Wh operation_results[2][7] += sum(prices.ELEC_PRICE * el_total_Wh) # CHF operation_results[2][8] += sum( calc_emissions_Whyr_to_tonCO2yr(el_total_Wh, lca.EL_TO_CO2_EQ)) # ton CO2 # add gas costs q_gas_total_Wh = q_gas_Boiler_FP_to_single_ACH_to_AHU_ARU_SCU_Wh operation_results[2][7] += sum(prices.NG_PRICE * q_gas_total_Wh) # CHF operation_results[2][8] += sum( calc_emissions_Whyr_to_tonCO2yr(q_gas_total_Wh, lca.NG_TO_CO2_EQ)) # ton CO2 # add activation cooling_dispatch[2] = { 'Q_ACH_gen_directload_W': q_chw_single_ACH_Wh, 'Q_Boiler_NG_ACH_W': q_load_Boiler_FP_to_single_ACH_to_AHU_ARU_SCU_Wh, 'Q_SC_FP_ACH_W': q_sc_gen_FP_Wh, 'E_ACH_req_W': el_single_ACH_Wh, 'E_CT_req_W': el_CT_Wh, 'E_SC_FP_req_W': el_aux_SC_FP_Wh, 'E_cs_cre_cdata_req_W': el_total_Wh, 'NG_Boiler_req': q_gas_Boiler_FP_to_single_ACH_to_AHU_ARU_SCU_Wh, } # capacity of cooling technologies operation_results[2][0] = Qc_nom_AHU_ARU_SCU_W operation_results[2][4] = Qc_nom_AHU_ARU_SCU_W # 4: ACH_SC_FP q_total_load = q_chw_single_ACH_Wh[None, :] + q_sc_gen_FP_Wh[ None, :] + q_load_Boiler_FP_to_single_ACH_to_AHU_ARU_SCU_Wh[None, :] system_COP_list = np.divide( q_total_load, (el_total_Wh[None, :] + q_gas_Boiler_FP_to_single_ACH_to_AHU_ARU_SCU_Wh[None, :])).flatten() system_COP = np.nansum(q_total_load * system_COP_list) / np.nansum( q_total_load) # weighted average of the system efficiency operation_results[2][9] += system_COP # 3: SC_ET + single-effect ACH (AHU + ARU + SCU) + CT + Boiler + SC_ET print( '{building_name} Config 3: Evacuated Tube Solar Collectors + Single-effect Absorption chillers -> AHU,ARU,SCU' .format(building_name=building_name)) # ACH operation T_hw_out_single_ACH_K, \ el_single_ACH_Wh, \ q_cw_single_ACH_Wh, \ q_hw_single_ACH_Wh, \ q_chw_single_ACH_Wh = calc_ACH_operation(T_ground_K, T_hw_in_ET_C, T_re_AHU_ARU_SCU_K, T_sup_AHU_ARU_SCU_K, chiller_prop, mdot_AHU_ARU_SCU_kgpers, ACH_TYPE_SINGLE) # CT operation q_CT_ET_to_single_ACH_to_AHU_ARU_SCU_W = q_cw_single_ACH_Wh Q_nom_CT_ET_to_single_ACH_to_AHU_ARU_SCU_W, el_CT_Wh = calc_CT_operation( q_CT_ET_to_single_ACH_to_AHU_ARU_SCU_W) # burner operation q_gas_for_burner_Wh, \ Q_nom_Burner_ET_to_single_ACH_to_AHU_ARU_SCU_W, \ q_burner_load_Wh = calc_burner_operation(Qc_nom_AHU_ARU_SCU_W, q_hw_single_ACH_Wh, q_sc_gen_ET_Wh) # add electricity costs el_total_Wh = el_single_ACH_Wh + el_aux_SC_ET_Wh + el_CT_Wh operation_results[3][7] += sum(prices.ELEC_PRICE * el_total_Wh) # CHF operation_results[3][8] += sum( calc_emissions_Whyr_to_tonCO2yr(el_total_Wh, lca.EL_TO_CO2_EQ)) # ton CO2 # add gas costs operation_results[3][7] += sum(prices.NG_PRICE * q_gas_for_burner_Wh) # CHF operation_results[3][8] += sum( calc_emissions_Whyr_to_tonCO2yr(q_gas_for_burner_Wh, lca.NG_TO_CO2_EQ)) # ton CO2 # add activation cooling_dispatch[3] = { 'Q_ACH_gen_directload_W': q_chw_single_ACH_Wh, 'Q_Burner_NG_ACH_W': q_burner_load_Wh, 'Q_SC_ET_ACH_W': q_sc_gen_ET_Wh, 'E_ACH_req_W': el_single_ACH_Wh, 'E_CT_req_W': el_CT_Wh, 'E_SC_ET_req_W': el_aux_SC_ET_Wh, 'E_cs_cre_cdata_req_W': el_total_Wh, 'NG_Burner_req': q_gas_for_burner_Wh, } # capacity of cooling technologies operation_results[3][0] = Qc_nom_AHU_ARU_SCU_W operation_results[3][5] = Qc_nom_AHU_ARU_SCU_W q_total_load = (q_burner_load_Wh[None, :] + q_chw_single_ACH_Wh[None, :] + q_sc_gen_ET_Wh[None, :]) system_COP_list = np.divide( q_total_load, (el_total_Wh[None, :] + q_gas_for_burner_Wh[None, :])).flatten() system_COP = np.nansum(q_total_load * system_COP_list) / np.nansum( q_total_load) # weighted average of the system efficiency operation_results[3][9] += system_COP # these two configurations are only activated when SCU is in use if Qc_nom_SCU_W > 0.0: # 4: VCC (AHU + ARU) + VCC (SCU) + CT print( '{building_name} Config 4: Vapor Compression Chillers(HT) -> SCU & Vapor Compression Chillers(LT) -> AHU,ARU' .format(building_name=building_name)) # VCC (AHU + ARU) operation el_VCC_to_AHU_ARU_Wh, \ q_cw_VCC_to_AHU_ARU_Wh, \ q_chw_VCC_to_AHU_ARU_Wh = calc_VCC_operation(T_re_AHU_ARU_K, T_sup_AHU_ARU_K, mdot_AHU_ARU_kgpers, VCC_chiller) VCC_LT_Status = np.where(q_chw_VCC_to_AHU_ARU_Wh > 0.0, 1, 0) # VCC(SCU) operation el_VCC_to_SCU_Wh, \ q_cw_VCC_to_SCU_Wh, \ q_chw_VCC_to_SCU_Wh = calc_VCC_operation(T_re_SCU_K, T_sup_SCU_K, mdot_SCU_kgpers, VCC_chiller) VCC_HT_Status = np.where(q_chw_VCC_to_AHU_ARU_Wh > 0.0, 1, 0) # CT operation q_CT_VCC_to_AHU_ARU_and_VCC_to_SCU_W = q_cw_VCC_to_AHU_ARU_Wh + q_cw_VCC_to_SCU_Wh Q_nom_CT_VCC_to_AHU_ARU_and_VCC_to_SCU_W, el_CT_Wh = calc_CT_operation( q_CT_VCC_to_AHU_ARU_and_VCC_to_SCU_W) # add el costs el_total_Wh = el_VCC_to_AHU_ARU_Wh + el_VCC_to_SCU_Wh + el_CT_Wh operation_results[4][7] += sum(prices.ELEC_PRICE * el_total_Wh) # CHF operation_results[4][8] += sum( calc_emissions_Whyr_to_tonCO2yr(el_total_Wh, lca.EL_TO_CO2_EQ)) # ton CO2 # add activation cooling_dispatch[4] = { 'Q_BaseVCC_AS_gen_directload_W': q_chw_VCC_to_AHU_ARU_Wh, 'Q_BaseVCCHT_AS_gen_directload_W': q_chw_VCC_to_SCU_Wh, 'E_BaseVCC_req_W': el_VCC_to_AHU_ARU_Wh, 'E_VCC_HT_req_W': el_VCC_to_SCU_Wh, 'E_CT_req_W': el_CT_Wh, 'E_cs_cre_cdata_req_W': el_total_Wh } # capacity of cooling technologies operation_results[4][0] = Qc_nom_AHU_ARU_SCU_W operation_results[4][2] = Qc_nom_AHU_ARU_W # 2: BaseVCC_AS operation_results[4][3] = Qc_nom_SCU_W # 3: VCCHT_AS system_COP_list = np.divide( q_CT_VCC_to_AHU_ARU_and_VCC_to_SCU_W[None, :], el_total_Wh[None, :]).flatten() system_COP = np.nansum( q_CT_VCC_to_AHU_ARU_and_VCC_to_SCU_W[None, :] * system_COP_list) / np.nansum(q_CT_VCC_to_AHU_ARU_and_VCC_to_SCU_W[ None, :]) # weighted average of the system efficiency operation_results[4][9] += system_COP # 5: VCC (AHU + ARU) + ACH (SCU) + CT print( '{building_name} Config 5: Vapor Compression Chillers(LT) -> AHU,ARU & Flate-place SC + Absorption Chillers(HT) -> SCU' .format(building_name=building_name)) # ACH (SCU) operation T_hw_FP_ACH_to_SCU_K, \ el_FP_ACH_to_SCU_Wh, \ q_cw_FP_ACH_to_SCU_Wh, \ q_hw_FP_ACH_to_SCU_Wh, \ q_chw_FP_ACH_to_SCU_Wh = calc_ACH_operation(T_ground_K, T_hw_in_FP_C, T_re_SCU_K, T_sup_SCU_K, chiller_prop, mdot_SCU_kgpers, ACH_TYPE_SINGLE) ACH_HT_Status = np.where(q_chw_FP_ACH_to_SCU_Wh > 0.0, 1, 0) # boiler operation q_gas_for_boiler_Wh, \ Q_nom_boiler_VCC_to_AHU_ARU_and_FP_to_single_ACH_to_SCU_W, \ q_load_from_boiler_Wh = calc_boiler_operation(Qc_nom_SCU_W, T_hw_FP_ACH_to_SCU_K, q_hw_FP_ACH_to_SCU_Wh, q_sc_gen_FP_Wh) # CT operation q_CT_VCC_to_AHU_ARU_and_single_ACH_to_SCU_Wh = q_cw_VCC_to_AHU_ARU_Wh + q_cw_FP_ACH_to_SCU_Wh Q_nom_CT_VCC_to_AHU_ARU_and_FP_to_single_ACH_to_SCU_W, \ el_CT_Wh = calc_CT_operation(q_CT_VCC_to_AHU_ARU_and_single_ACH_to_SCU_Wh) # add electricity costs el_total_Wh = el_VCC_to_AHU_ARU_Wh + el_FP_ACH_to_SCU_Wh + el_aux_SC_FP_Wh + el_CT_Wh operation_results[5][7] += sum(prices.ELEC_PRICE * el_total_Wh) # CHF operation_results[5][8] += sum( calc_emissions_Whyr_to_tonCO2yr(el_total_Wh, lca.EL_TO_CO2_EQ)) # ton CO2 # add gas costs q_gas_total_Wh = q_gas_for_boiler_Wh operation_results[5][7] += sum(prices.NG_PRICE * q_gas_total_Wh) # CHF operation_results[5][8] += sum( calc_emissions_Whyr_to_tonCO2yr(q_gas_total_Wh, lca.NG_TO_CO2_EQ)) # ton CO2 # add activation cooling_dispatch[5] = { 'Q_BaseVCC_AS_gen_directload_W': q_chw_VCC_to_AHU_ARU_Wh, 'Q_ACHHT_AS_gen_directload_W': q_chw_FP_ACH_to_SCU_Wh, 'E_BaseVCC_req_W': el_VCC_to_AHU_ARU_Wh, 'E_ACHHT_req_W': el_FP_ACH_to_SCU_Wh, 'E_SC_FP_ACH_req_W': el_aux_SC_FP_Wh, 'E_CT_req_W': el_CT_Wh, 'E_cs_cre_cdata_req_W': el_total_Wh, 'Q_BaseBoiler_NG_req': q_gas_for_boiler_Wh, } # capacity of cooling technologies operation_results[5][0] = Qc_nom_AHU_ARU_SCU_W operation_results[5][2] = Qc_nom_AHU_ARU_W # 2: BaseVCC_AS operation_results[5][6] = Qc_nom_SCU_W # 6: ACHHT_SC_FP q_total_load = q_CT_VCC_to_AHU_ARU_and_single_ACH_to_SCU_Wh[ None, :] + q_gas_for_boiler_Wh[None, :] system_COP_list = np.divide(q_total_load, el_total_Wh[None, :]).flatten() system_COP = np.nansum(q_total_load * system_COP_list) / np.nansum( q_total_load) # weighted average of the system efficiency operation_results[5][9] += system_COP ## Calculate Capex/Opex # Initialize arrays number_of_configurations = len(operation_results) Capex_a_USD = np.zeros((number_of_configurations, 1)) Capex_total_USD = np.zeros((number_of_configurations, 1)) Opex_a_fixed_USD = np.zeros((number_of_configurations, 1)) print('{building_name} Cost calculation...'.format( building_name=building_name)) # 0: DX Capex_a_DX_USD, Opex_fixed_DX_USD, Capex_DX_USD = dx.calc_Cinv_DX( Qc_nom_AHU_ARU_SCU_W) # add costs Capex_a_USD[0][0] = Capex_a_DX_USD Capex_total_USD[0][0] = Capex_DX_USD Opex_a_fixed_USD[0][0] = Opex_fixed_DX_USD # 1: VCC + CT Capex_a_VCC_USD, Opex_fixed_VCC_USD, Capex_VCC_USD = chiller_vapor_compression.calc_Cinv_VCC( Qc_nom_AHU_ARU_SCU_W, locator, 'CH3') Capex_a_CT_USD, Opex_fixed_CT_USD, Capex_CT_USD = cooling_tower.calc_Cinv_CT( Q_nom_CT_VCC_to_AHU_ARU_SCU_W, locator, 'CT1') # add costs Capex_a_USD[1][0] = Capex_a_CT_USD + Capex_a_VCC_USD Capex_total_USD[1][0] = Capex_CT_USD + Capex_VCC_USD Opex_a_fixed_USD[1][0] = Opex_fixed_CT_USD + Opex_fixed_VCC_USD # 2: single effect ACH + CT + Boiler + SC_FP Capex_a_ACH_USD, Opex_fixed_ACH_USD, Capex_ACH_USD = chiller_absorption.calc_Cinv_ACH( Qc_nom_AHU_ARU_SCU_W, supply_systems.Absorption_chiller, ACH_TYPE_SINGLE) Capex_a_CT_USD, Opex_fixed_CT_USD, Capex_CT_USD = cooling_tower.calc_Cinv_CT( Q_nom_CT_FP_to_single_ACH_to_AHU_ARU_SCU_W, locator, 'CT1') Capex_a_boiler_USD, Opex_fixed_boiler_USD, Capex_boiler_USD = boiler.calc_Cinv_boiler( Q_nom_Boiler_FP_to_single_ACH_to_AHU_ARU_SCU_W, 'BO1', boiler_cost_data) Capex_a_USD[2][ 0] = Capex_a_CT_USD + Capex_a_ACH_USD + Capex_a_boiler_USD + Capex_a_SC_FP_USD Capex_total_USD[2][ 0] = Capex_CT_USD + Capex_ACH_USD + Capex_boiler_USD + Capex_SC_FP_USD Opex_a_fixed_USD[2][ 0] = Opex_fixed_CT_USD + Opex_fixed_ACH_USD + Opex_fixed_boiler_USD + Opex_SC_FP_USD # 3: double effect ACH + CT + Boiler + SC_ET Capex_a_ACH_USD, Opex_fixed_ACH_USD, Capex_ACH_USD = chiller_absorption.calc_Cinv_ACH( Qc_nom_AHU_ARU_SCU_W, supply_systems.Absorption_chiller, ACH_TYPE_SINGLE) Capex_a_CT_USD, Opex_fixed_CT_USD, Capex_CT_USD = cooling_tower.calc_Cinv_CT( Q_nom_CT_ET_to_single_ACH_to_AHU_ARU_SCU_W, locator, 'CT1') Capex_a_burner_USD, Opex_fixed_burner_USD, Capex_burner_USD = burner.calc_Cinv_burner( Q_nom_Burner_ET_to_single_ACH_to_AHU_ARU_SCU_W, boiler_cost_data, 'BO1') Capex_a_USD[3][ 0] = Capex_a_CT_USD + Capex_a_ACH_USD + Capex_a_burner_USD + Capex_a_SC_ET_USD Capex_total_USD[3][ 0] = Capex_CT_USD + Capex_ACH_USD + Capex_burner_USD + Capex_SC_ET_USD Opex_a_fixed_USD[3][ 0] = Opex_fixed_CT_USD + Opex_fixed_ACH_USD + Opex_fixed_burner_USD + Opex_SC_ET_USD # these two configurations are only activated when SCU is in use if Qc_nom_SCU_W > 0.0: # 4: VCC (AHU + ARU) + VCC (SCU) + CT Capex_a_VCC_AA_USD, Opex_VCC_AA_USD, Capex_VCC_AA_USD = chiller_vapor_compression.calc_Cinv_VCC( Qc_nom_AHU_ARU_W, locator, 'CH3') Capex_a_VCC_S_USD, Opex_VCC_S_USD, Capex_VCC_S_USD = chiller_vapor_compression.calc_Cinv_VCC( Qc_nom_SCU_W, locator, 'CH3') Capex_a_CT_USD, Opex_fixed_CT_USD, Capex_CT_USD = cooling_tower.calc_Cinv_CT( Q_nom_CT_VCC_to_AHU_ARU_and_VCC_to_SCU_W, locator, 'CT1') Capex_a_USD[4][ 0] = Capex_a_CT_USD + Capex_a_VCC_AA_USD + Capex_a_VCC_S_USD Capex_total_USD[4][ 0] = Capex_CT_USD + Capex_VCC_AA_USD + Capex_VCC_S_USD Opex_a_fixed_USD[4][ 0] = Opex_fixed_CT_USD + Opex_VCC_AA_USD + Opex_VCC_S_USD # 5: VCC (AHU + ARU) + ACH (SCU) + CT + Boiler + SC_FP Capex_a_ACH_S_USD, Opex_fixed_ACH_S_USD, Capex_ACH_S_USD = chiller_absorption.calc_Cinv_ACH( Qc_nom_SCU_W, supply_systems.Absorption_chiller, ACH_TYPE_SINGLE) Capex_a_CT_USD, Opex_fixed_CT_USD, Capex_CT_USD = cooling_tower.calc_Cinv_CT( Q_nom_CT_VCC_to_AHU_ARU_and_FP_to_single_ACH_to_SCU_W, locator, 'CT1') Capex_a_boiler_USD, Opex_fixed_boiler_USD, Capex_boiler_USD = boiler.calc_Cinv_boiler( Q_nom_boiler_VCC_to_AHU_ARU_and_FP_to_single_ACH_to_SCU_W, 'BO1', boiler_cost_data) Capex_a_USD[5][0] = Capex_a_CT_USD + Capex_a_VCC_AA_USD + Capex_a_ACH_S_USD + \ Capex_a_SC_FP_USD + Capex_a_boiler_USD Capex_total_USD[5][0] = Capex_CT_USD + Capex_VCC_AA_USD + Capex_ACH_S_USD + \ Capex_SC_FP_USD + Capex_boiler_USD Opex_a_fixed_USD[5][0] = Opex_fixed_CT_USD + Opex_VCC_AA_USD + Opex_fixed_ACH_S_USD + \ Opex_SC_FP_USD + Opex_fixed_boiler_USD ## write all results from the configurations into TotalCosts, TotalCO2, TotalPrim Opex_a_USD, TAC_USD, TotalCO2, TotalPrim = compile_TAC_CO2_Prim( Capex_a_USD, Opex_a_fixed_USD, number_of_configurations, operation_results) ## Determine the best configuration Best, indexBest = rank_results(TAC_USD, TotalCO2, TotalPrim, number_of_configurations) # Save results in csv file performance_results = { "Nominal heating load": operation_results[:, 0], "Capacity_DX_AS_W": operation_results[:, 1], "Capacity_BaseVCC_AS_W": operation_results[:, 2], "Capacity_VCCHT_AS_W": operation_results[:, 3], "Capacity_ACH_SC_FP_W": operation_results[:, 4], "Capaticy_ACH_SC_ET_W": operation_results[:, 5], "Capacity_ACHHT_FP_W": operation_results[:, 6], "Capex_a_USD": Capex_a_USD[:, 0], "Capex_total_USD": Capex_total_USD[:, 0], "Opex_fixed_USD": Opex_a_fixed_USD[:, 0], "Opex_var_USD": operation_results[:, 7], "GHG_tonCO2": operation_results[:, 8], "TAC_USD": TAC_USD[:, 1], "Best configuration": Best[:, 0], "system_COP": operation_results[:, 9], } performance_results_df = pd.DataFrame(performance_results) performance_results_df.to_csv( locator.get_optimization_decentralized_folder_building_result_cooling( building_name), index=False) # save activation for the best supply system configuration best_activation_df = pd.DataFrame.from_dict(cooling_dispatch[indexBest]) # best_activation_df.to_csv( locator. get_optimization_decentralized_folder_building_cooling_activation( building_name), index=False)
def addCosts(buildList, locator, master_to_slave_vars, Q_uncovered_design_W, Q_uncovered_annual_W, solar_features, network_features, gv, config, prices, lca): """ Computes additional costs / GHG emisions / primary energy needs for the individual addCosts = additional costs addCO2 = GHG emissions addPrm = primary energy needs :param DHN_barcode: parameter indicating if the building is connected or not :param buildList: list of buildings in the district :param locator: input locator set to scenario :param master_to_slave_vars: class containing the features of a specific individual :param Q_uncovered_design_W: hourly max of the heating uncovered demand :param Q_uncovered_annual_W: total heating uncovered :param solar_features: solar features :param network_features: network features :param gv: global variables :type indCombi: string :type buildList: list :type locator: string :type master_to_slave_vars: class :type Q_uncovered_design_W: float :type Q_uncovered_annual_W: float :type solar_features: class :type network_features: class :type gv: class :return: returns the objectives addCosts, addCO2, addPrim :rtype: tuple """ DHN_barcode = master_to_slave_vars.DHN_barcode DCN_barcode = master_to_slave_vars.DCN_barcode addcosts_Capex_a_USD = 0 addcosts_Opex_fixed_USD = 0 addcosts_Capex_USD = 0 addCO2 = 0 addPrim = 0 nBuildinNtw = 0 # Add the features from the disconnected buildings CostDiscBuild = 0 CO2DiscBuild = 0 PrimDiscBuild = 0 Capex_Disconnected = 0 Opex_Disconnected = 0 Capex_a_furnace_USD = 0 Capex_a_CHP_USD = 0 Capex_a_Boiler_USD = 0 Capex_a_Boiler_peak_USD = 0 Capex_a_Lake_USD = 0 Capex_a_Sewage_USD = 0 Capex_a_GHP_USD = 0 Capex_a_PV_USD = 0 Capex_a_SC_ET_USD = 0 Capex_a_SC_FP_USD = 0 Capex_a_PVT_USD = 0 Capex_a_Boiler_backup_USD = 0 Capex_a_HEX = 0 Capex_a_storage_HP = 0 Capex_a_HP_storage_USD = 0 Opex_fixed_SC = 0 Opex_fixed_PVT_USD = 0 Opex_fixed_HP_PVT_USD = 0 Opex_fixed_furnace_USD = 0 Opex_fixed_CHP_USD = 0 Opex_fixed_Boiler_USD = 0 Opex_fixed_Boiler_peak_USD = 0 Opex_fixed_Boiler_backup_USD = 0 Opex_fixed_Lake_USD = 0 Opex_fixed_wasteserver_HEX_USD = 0 Opex_fixed_wasteserver_HP_USD = 0 Opex_fixed_PV_USD = 0 Opex_fixed_GHP_USD = 0 Opex_fixed_storage_USD = 0 Opex_fixed_Sewage_USD = 0 Opex_fixed_HP_storage_USD = 0 StorageInvC = 0 NetworkCost_a_USD = 0 SubstHEXCost_capex = 0 SubstHEXCost_opex = 0 PVTHEXCost_Capex = 0 PVTHEXCost_Opex = 0 SCHEXCost_Capex = 0 SCHEXCost_Opex = 0 pumpCosts = 0 GasConnectionInvCost = 0 cost_PV_disconnected = 0 CO2_PV_disconnected = 0 Eprim_PV_disconnected = 0 Capex_furnace_USD = 0 Capex_CHP_USD = 0 Capex_Boiler_USD = 0 Capex_Boiler_peak_USD = 0 Capex_Lake_USD = 0 Capex_Sewage_USD = 0 Capex_GHP = 0 Capex_PV_USD = 0 Capex_SC = 0 Capex_PVT_USD = 0 Capex_Boiler_backup_USD = 0 Capex_HEX = 0 Capex_storage_HP = 0 Capex_HP_storage = 0 Capex_SC_ET_USD = 0 Capex_SC_FP_USD = 0 Capex_PVT_USD = 0 Capex_Boiler_backup_USD = 0 Capex_HP_storage_USD = 0 Capex_storage_HP = 0 Capex_CHP_USD = 0 Capex_furnace_USD = 0 Capex_Boiler_USD = 0 Capex_Boiler_peak_USD = 0 Capex_Lake_USD = 0 Capex_Sewage_USD = 0 Capex_pump_USD = 0 if config.district_heating_network: for (index, building_name) in zip(DHN_barcode, buildList): if index == "0": df = pd.read_csv( locator. get_optimization_decentralized_folder_building_result_heating( building_name)) dfBest = df[df["Best configuration"] == 1] CostDiscBuild += dfBest["Total Costs [CHF]"].iloc[0] # [CHF] CO2DiscBuild += dfBest["CO2 Emissions [kgCO2-eq]"].iloc[ 0] # [kg CO2] PrimDiscBuild += dfBest[ "Primary Energy Needs [MJoil-eq]"].iloc[0] # [MJ-oil-eq] Capex_Disconnected += dfBest[ "Annualized Investment Costs [CHF]"].iloc[0] Opex_Disconnected += dfBest["Operation Costs [CHF]"].iloc[0] else: nBuildinNtw += 1 if config.district_cooling_network: PV_barcode = '' for (index, building_name) in zip(DCN_barcode, buildList): if index == "0": # choose the best decentralized configuration df = pd.read_csv( locator. get_optimization_decentralized_folder_building_result_cooling( building_name, configuration='AHU_ARU_SCU')) dfBest = df[df["Best configuration"] == 1] CostDiscBuild += dfBest["Total Costs [CHF]"].iloc[0] # [CHF] CO2DiscBuild += dfBest["CO2 Emissions [kgCO2-eq]"].iloc[ 0] # [kg CO2] PrimDiscBuild += dfBest[ "Primary Energy Needs [MJoil-eq]"].iloc[0] # [MJ-oil-eq] Capex_Disconnected += dfBest[ "Annualized Investment Costs [CHF]"].iloc[0] Opex_Disconnected += dfBest["Operation Costs [CHF]"].iloc[0] to_PV = 1 if dfBest["single effect ACH to AHU_ARU_SCU Share (FP)"].iloc[ 0] == 1: to_PV = 0 if dfBest["single effect ACH to AHU_ARU_SCU Share (ET)"].iloc[ 0] == 1: to_PV = 0 if dfBest["single effect ACH to SCU Share (FP)"].iloc[0] == 1: to_PV = 0 else: # adding costs for buildings in which the centralized plant provides a part of the load requirements DCN_unit_configuration = master_to_slave_vars.DCN_supplyunits if DCN_unit_configuration == 1: # corresponds to AHU in the central plant, so remaining load need to be provided by decentralized plant decentralized_configuration = 'ARU_SCU' df = pd.read_csv( locator. get_optimization_decentralized_folder_building_result_cooling( building_name, decentralized_configuration)) dfBest = df[df["Best configuration"] == 1] CostDiscBuild += dfBest["Total Costs [CHF]"].iloc[ 0] # [CHF] CO2DiscBuild += dfBest["CO2 Emissions [kgCO2-eq]"].iloc[ 0] # [kg CO2] PrimDiscBuild += dfBest[ "Primary Energy Needs [MJoil-eq]"].iloc[ 0] # [MJ-oil-eq] Capex_Disconnected += dfBest[ "Annualized Investment Costs [CHF]"].iloc[0] Opex_Disconnected += dfBest["Operation Costs [CHF]"].iloc[ 0] to_PV = 1 if dfBest["single effect ACH to ARU_SCU Share (FP)"].iloc[ 0] == 1: to_PV = 0 if dfBest["single effect ACH to ARU_SCU Share (ET)"].iloc[ 0] == 1: to_PV = 0 if DCN_unit_configuration == 2: # corresponds to ARU in the central plant, so remaining load need to be provided by decentralized plant decentralized_configuration = 'AHU_SCU' df = pd.read_csv( locator. get_optimization_decentralized_folder_building_result_cooling( building_name, decentralized_configuration)) dfBest = df[df["Best configuration"] == 1] CostDiscBuild += dfBest["Total Costs [CHF]"].iloc[ 0] # [CHF] CO2DiscBuild += dfBest["CO2 Emissions [kgCO2-eq]"].iloc[ 0] # [kg CO2] PrimDiscBuild += dfBest[ "Primary Energy Needs [MJoil-eq]"].iloc[ 0] # [MJ-oil-eq] Capex_Disconnected += dfBest[ "Annualized Investment Costs [CHF]"].iloc[0] Opex_Disconnected += dfBest["Operation Costs [CHF]"].iloc[ 0] to_PV = 1 if dfBest["single effect ACH to AHU_SCU Share (FP)"].iloc[ 0] == 1: to_PV = 0 if dfBest["single effect ACH to AHU_SCU Share (ET)"].iloc[ 0] == 1: to_PV = 0 if DCN_unit_configuration == 3: # corresponds to SCU in the central plant, so remaining load need to be provided by decentralized plant decentralized_configuration = 'AHU_ARU' df = pd.read_csv( locator. get_optimization_decentralized_folder_building_result_cooling( building_name, decentralized_configuration)) dfBest = df[df["Best configuration"] == 1] CostDiscBuild += dfBest["Total Costs [CHF]"].iloc[ 0] # [CHF] CO2DiscBuild += dfBest["CO2 Emissions [kgCO2-eq]"].iloc[ 0] # [kg CO2] PrimDiscBuild += dfBest[ "Primary Energy Needs [MJoil-eq]"].iloc[ 0] # [MJ-oil-eq] Capex_Disconnected += dfBest[ "Annualized Investment Costs [CHF]"].iloc[0] Opex_Disconnected += dfBest["Operation Costs [CHF]"].iloc[ 0] to_PV = 1 if dfBest["single effect ACH to AHU_ARU Share (FP)"].iloc[ 0] == 1: to_PV = 0 if dfBest["single effect ACH to AHU_ARU Share (ET)"].iloc[ 0] == 1: to_PV = 0 if DCN_unit_configuration == 4: # corresponds to AHU + ARU in the central plant, so remaining load need to be provided by decentralized plant decentralized_configuration = 'SCU' df = pd.read_csv( locator. get_optimization_decentralized_folder_building_result_cooling( building_name, decentralized_configuration)) dfBest = df[df["Best configuration"] == 1] CostDiscBuild += dfBest["Total Costs [CHF]"].iloc[ 0] # [CHF] CO2DiscBuild += dfBest["CO2 Emissions [kgCO2-eq]"].iloc[ 0] # [kg CO2] PrimDiscBuild += dfBest[ "Primary Energy Needs [MJoil-eq]"].iloc[ 0] # [MJ-oil-eq] Capex_Disconnected += dfBest[ "Annualized Investment Costs [CHF]"].iloc[0] Opex_Disconnected += dfBest["Operation Costs [CHF]"].iloc[ 0] to_PV = 1 if dfBest["single effect ACH to SCU Share (FP)"].iloc[ 0] == 1: to_PV = 0 if dfBest["single effect ACH to SCU Share (ET)"].iloc[ 0] == 1: to_PV = 0 if DCN_unit_configuration == 5: # corresponds to AHU + SCU in the central plant, so remaining load need to be provided by decentralized plant decentralized_configuration = 'ARU' df = pd.read_csv( locator. get_optimization_decentralized_folder_building_result_cooling( building_name, decentralized_configuration)) dfBest = df[df["Best configuration"] == 1] CostDiscBuild += dfBest["Total Costs [CHF]"].iloc[ 0] # [CHF] CO2DiscBuild += dfBest["CO2 Emissions [kgCO2-eq]"].iloc[ 0] # [kg CO2] PrimDiscBuild += dfBest[ "Primary Energy Needs [MJoil-eq]"].iloc[ 0] # [MJ-oil-eq] Capex_Disconnected += dfBest[ "Annualized Investment Costs [CHF]"].iloc[0] Opex_Disconnected += dfBest["Operation Costs [CHF]"].iloc[ 0] to_PV = 1 if dfBest["single effect ACH to ARU Share (FP)"].iloc[ 0] == 1: to_PV = 0 if dfBest["single effect ACH to ARU Share (ET)"].iloc[ 0] == 1: to_PV = 0 if DCN_unit_configuration == 6: # corresponds to ARU + SCU in the central plant, so remaining load need to be provided by decentralized plant decentralized_configuration = 'AHU' df = pd.read_csv( locator. get_optimization_decentralized_folder_building_result_cooling( building_name, decentralized_configuration)) dfBest = df[df["Best configuration"] == 1] CostDiscBuild += dfBest["Total Costs [CHF]"].iloc[ 0] # [CHF] CO2DiscBuild += dfBest["CO2 Emissions [kgCO2-eq]"].iloc[ 0] # [kg CO2] PrimDiscBuild += dfBest[ "Primary Energy Needs [MJoil-eq]"].iloc[ 0] # [MJ-oil-eq] Capex_Disconnected += dfBest[ "Annualized Investment Costs [CHF]"].iloc[0] Opex_Disconnected += dfBest["Operation Costs [CHF]"].iloc[ 0] to_PV = 1 if dfBest["single effect ACH to AHU Share (FP)"].iloc[ 0] == 1: to_PV = 0 if dfBest["single effect ACH to AHU Share (ET)"].iloc[ 0] == 1: to_PV = 0 if DCN_unit_configuration == 7: # corresponds to AHU + ARU + SCU from central plant to_PV = 1 nBuildinNtw += 1 PV_barcode = PV_barcode + str(to_PV) addcosts_Capex_a_USD += CostDiscBuild addCO2 += CO2DiscBuild addPrim += PrimDiscBuild # Solar technologies PV_installed_area_m2 = master_to_slave_vars.SOLAR_PART_PV * solar_features.A_PV_m2 # kW Capex_a_PV_USD, Opex_fixed_PV_USD, Capex_PV_USD = pv.calc_Cinv_pv( PV_installed_area_m2, locator, config) addcosts_Capex_a_USD += Capex_a_PV_USD addcosts_Opex_fixed_USD += Opex_fixed_PV_USD addcosts_Capex_USD += Capex_PV_USD SC_ET_area_m2 = master_to_slave_vars.SOLAR_PART_SC_ET * solar_features.A_SC_ET_m2 Capex_a_SC_ET_USD, Opex_fixed_SC_ET_USD, Capex_SC_ET_USD = stc.calc_Cinv_SC( SC_ET_area_m2, locator, config, 'ET') addcosts_Capex_a_USD += Capex_a_SC_ET_USD addcosts_Opex_fixed_USD += Opex_fixed_SC_ET_USD addcosts_Capex_USD += Capex_SC_ET_USD SC_FP_area_m2 = master_to_slave_vars.SOLAR_PART_SC_FP * solar_features.A_SC_FP_m2 Capex_a_SC_FP_USD, Opex_fixed_SC_FP_USD, Capex_SC_FP_USD = stc.calc_Cinv_SC( SC_FP_area_m2, locator, config, 'FP') addcosts_Capex_a_USD += Capex_a_SC_FP_USD addcosts_Opex_fixed_USD += Opex_fixed_SC_FP_USD addcosts_Capex_USD += Capex_SC_FP_USD PVT_peak_kW = master_to_slave_vars.SOLAR_PART_PVT * solar_features.A_PVT_m2 * N_PVT # kW Capex_a_PVT_USD, Opex_fixed_PVT_USD, Capex_PVT_USD = pvt.calc_Cinv_PVT( PVT_peak_kW, locator, config) addcosts_Capex_a_USD += Capex_a_PVT_USD addcosts_Opex_fixed_USD += Opex_fixed_PVT_USD addcosts_Capex_USD += Capex_PVT_USD # Add the features for the distribution if DHN_barcode.count("1") > 0 and config.district_heating_network: os.chdir( locator.get_optimization_slave_results_folder( master_to_slave_vars.generation_number)) # Add the investment costs of the energy systems # Furnace if master_to_slave_vars.Furnace_on == 1: P_design_W = master_to_slave_vars.Furnace_Q_max_W fNameSlavePP = locator.get_optimization_slave_heating_activation_pattern_heating( master_to_slave_vars.configKey, master_to_slave_vars.individual_number, master_to_slave_vars.generation_number) dfFurnace = pd.read_csv(fNameSlavePP, usecols=["Q_Furnace_W"]) arrayFurnace_W = np.array(dfFurnace) Q_annual_W = 0 for i in range(int(np.shape(arrayFurnace_W)[0])): Q_annual_W += arrayFurnace_W[i][0] Capex_a_furnace_USD, Opex_fixed_furnace_USD, Capex_furnace_USD = furnace.calc_Cinv_furnace( P_design_W, Q_annual_W, config, locator, 'FU1') addcosts_Capex_a_USD += Capex_a_furnace_USD addcosts_Opex_fixed_USD += Opex_fixed_furnace_USD addcosts_Capex_USD += Capex_furnace_USD # CC if master_to_slave_vars.CC_on == 1: CC_size_W = master_to_slave_vars.CC_GT_SIZE_W Capex_a_CHP_USD, Opex_fixed_CHP_USD, Capex_CHP_USD = chp.calc_Cinv_CCGT( CC_size_W, locator, config) addcosts_Capex_a_USD += Capex_a_CHP_USD addcosts_Opex_fixed_USD += Opex_fixed_CHP_USD addcosts_Capex_USD += Capex_CHP_USD # Boiler Base if master_to_slave_vars.Boiler_on == 1: Q_design_W = master_to_slave_vars.Boiler_Q_max_W fNameSlavePP = locator.get_optimization_slave_heating_activation_pattern( master_to_slave_vars.individual_number, master_to_slave_vars.generation_number) dfBoilerBase = pd.read_csv(fNameSlavePP, usecols=["Q_BaseBoiler_W"]) arrayBoilerBase_W = np.array(dfBoilerBase) Q_annual_W = 0 for i in range(int(np.shape(arrayBoilerBase_W)[0])): Q_annual_W += arrayBoilerBase_W[i][0] Capex_a_Boiler_USD, Opex_fixed_Boiler_USD, Capex_Boiler_USD = boiler.calc_Cinv_boiler( Q_design_W, locator, config, 'BO1') addcosts_Capex_a_USD += Capex_a_Boiler_USD addcosts_Opex_fixed_USD += Opex_fixed_Boiler_USD addcosts_Capex_USD += Capex_Boiler_USD # Boiler Peak if master_to_slave_vars.BoilerPeak_on == 1: Q_design_W = master_to_slave_vars.BoilerPeak_Q_max_W fNameSlavePP = locator.get_optimization_slave_heating_activation_pattern( master_to_slave_vars.individual_number, master_to_slave_vars.generation_number) dfBoilerPeak = pd.read_csv(fNameSlavePP, usecols=["Q_PeakBoiler_W"]) arrayBoilerPeak_W = np.array(dfBoilerPeak) Q_annual_W = 0 for i in range(int(np.shape(arrayBoilerPeak_W)[0])): Q_annual_W += arrayBoilerPeak_W[i][0] Capex_a_Boiler_peak_USD, Opex_fixed_Boiler_peak_USD, Capex_Boiler_peak_USD = boiler.calc_Cinv_boiler( Q_design_W, locator, config, 'BO1') addcosts_Capex_a_USD += Capex_a_Boiler_peak_USD addcosts_Opex_fixed_USD += Opex_fixed_Boiler_peak_USD addcosts_Capex_USD += Capex_Boiler_peak_USD # HP Lake if master_to_slave_vars.HP_Lake_on == 1: HP_Size_W = master_to_slave_vars.HPLake_maxSize_W Capex_a_Lake_USD, Opex_fixed_Lake_USD, Capex_Lake_USD = hp.calc_Cinv_HP( HP_Size_W, locator, config, 'HP2') addcosts_Capex_a_USD += Capex_a_Lake_USD addcosts_Opex_fixed_USD += Opex_fixed_Lake_USD addcosts_Capex_USD += Capex_Lake_USD # HP Sewage if master_to_slave_vars.HP_Sew_on == 1: HP_Size_W = master_to_slave_vars.HPSew_maxSize_W Capex_a_Sewage_USD, Opex_fixed_Sewage_USD, Capex_Sewage_USD = hp.calc_Cinv_HP( HP_Size_W, locator, config, 'HP2') addcosts_Capex_a_USD += Capex_a_Sewage_USD addcosts_Opex_fixed_USD += Opex_fixed_Sewage_USD addcosts_Capex_USD += Capex_Sewage_USD # GHP if master_to_slave_vars.GHP_on == 1: fNameSlavePP = locator.get_optimization_slave_electricity_activation_pattern_heating( master_to_slave_vars.individual_number, master_to_slave_vars.generation_number) dfGHP = pd.read_csv(fNameSlavePP, usecols=["E_used_GHP_W"]) arrayGHP_W = np.array(dfGHP) GHP_Enom_W = np.amax(arrayGHP_W) Capex_a_GHP_USD, Opex_fixed_GHP_USD, Capex_GHP_USD = hp.calc_Cinv_GHP( GHP_Enom_W, locator, config) addcosts_Capex_a_USD += Capex_a_GHP_USD * prices.EURO_TO_CHF addcosts_Opex_fixed_USD += Opex_fixed_GHP_USD * prices.EURO_TO_CHF addcosts_Capex_USD += Capex_GHP_USD # Back-up boiler Capex_a_Boiler_backup_USD, Opex_fixed_Boiler_backup_USD, Capex_Boiler_backup_USD = boiler.calc_Cinv_boiler( Q_uncovered_design_W, locator, config, 'BO1') addcosts_Capex_a_USD += Capex_a_Boiler_backup_USD addcosts_Opex_fixed_USD += Opex_fixed_Boiler_backup_USD addcosts_Capex_USD += Capex_Boiler_backup_USD master_to_slave_vars.BoilerBackup_Q_max_W = Q_uncovered_design_W # Hex and HP for Heat recovery if master_to_slave_vars.WasteServersHeatRecovery == 1: df = pd.read_csv(os.path.join( locator.get_optimization_network_results_folder(), master_to_slave_vars.network_data_file_heating), usecols=["Qcdata_netw_total_kWh"]) array = np.array(df) Q_HEX_max_kWh = np.amax(array) Capex_a_wasteserver_HEX_USD, Opex_fixed_wasteserver_HEX_USD, Capex_wasteserver_HEX_USD = hex.calc_Cinv_HEX( Q_HEX_max_kWh, locator, config, 'HEX1') addcosts_Capex_a_USD += (Capex_a_wasteserver_HEX_USD) addcosts_Opex_fixed_USD += Opex_fixed_wasteserver_HEX_USD addcosts_Capex_USD += Capex_wasteserver_HEX_USD df = pd.read_csv( locator.get_optimization_slave_storage_operation_data( master_to_slave_vars.individual_number, master_to_slave_vars.generation_number), usecols=["HPServerHeatDesignArray_kWh"]) array = np.array(df) Q_HP_max_kWh = np.amax(array) Capex_a_wasteserver_HP_USD, Opex_fixed_wasteserver_HP_USD, Capex_wasteserver_HP_USD = hp.calc_Cinv_HP( Q_HP_max_kWh, locator, config, 'HP2') addcosts_Capex_a_USD += (Capex_a_wasteserver_HP_USD) addcosts_Opex_fixed_USD += Opex_fixed_wasteserver_HP_USD addcosts_Capex_USD += Capex_wasteserver_HP_USD # Heat pump from solar to DH df = pd.read_csv( locator.get_optimization_slave_storage_operation_data( master_to_slave_vars.individual_number, master_to_slave_vars.generation_number), usecols=["HPScDesignArray_Wh", "HPpvt_designArray_Wh"]) array = np.array(df) Q_HP_max_PVT_wh = np.amax(array[:, 1]) Q_HP_max_SC_Wh = np.amax(array[:, 0]) Capex_a_HP_PVT_USD, Opex_fixed_HP_PVT_USD, Capex_HP_PVT_USD = hp.calc_Cinv_HP( Q_HP_max_PVT_wh, locator, config, 'HP2') Capex_a_storage_HP += (Capex_a_HP_PVT_USD) addcosts_Opex_fixed_USD += Opex_fixed_HP_PVT_USD addcosts_Capex_USD += Capex_HP_PVT_USD Capex_a_HP_SC_USD, Opex_fixed_HP_SC_USD, Capex_HP_SC_USD = hp.calc_Cinv_HP( Q_HP_max_SC_Wh, locator, config, 'HP2') Capex_a_storage_HP += (Capex_a_HP_SC_USD) addcosts_Opex_fixed_USD += Opex_fixed_HP_SC_USD addcosts_Capex_USD += Capex_HP_SC_USD # HP for storage operation for charging from solar and discharging to DH df = pd.read_csv(locator.get_optimization_slave_storage_operation_data( master_to_slave_vars.individual_number, master_to_slave_vars.generation_number), usecols=[ "E_aux_ch_W", "E_aux_dech_W", "Q_from_storage_used_W", "Q_to_storage_W" ]) array = np.array(df) Q_HP_max_storage_W = 0 for i in range(DAYS_IN_YEAR * HOURS_IN_DAY): if array[i][0] > 0: Q_HP_max_storage_W = max(Q_HP_max_storage_W, array[i][3] + array[i][0]) elif array[i][1] > 0: Q_HP_max_storage_W = max(Q_HP_max_storage_W, array[i][2] + array[i][1]) Capex_a_HP_storage_USD, Opex_fixed_HP_storage_USD, Capex_HP_storage_USD = hp.calc_Cinv_HP( Q_HP_max_storage_W, locator, config, 'HP2') addcosts_Capex_a_USD += (Capex_a_HP_storage_USD) addcosts_Opex_fixed_USD += Opex_fixed_HP_storage_USD addcosts_Capex_USD += Capex_HP_storage_USD # Storage df = pd.read_csv(locator.get_optimization_slave_storage_operation_data( master_to_slave_vars.individual_number, master_to_slave_vars.generation_number), usecols=["Storage_Size_m3"], nrows=1) StorageVol_m3 = np.array(df)[0][0] Capex_a_storage_USD, Opex_fixed_storage_USD, Capex_storage_USD = storage.calc_Cinv_storage( StorageVol_m3, locator, config, 'TES2') addcosts_Capex_a_USD += Capex_a_storage_USD addcosts_Opex_fixed_USD += Opex_fixed_storage_USD addcosts_Capex_USD += Capex_storage_USD # Costs from distribution configuration if gv.ZernezFlag == 1: NetworkCost_a_USD, NetworkCost_USD = network.calc_Cinv_network_linear( gv.NetworkLengthZernez, gv) NetworkCost_a_USD = NetworkCost_a_USD * nBuildinNtw / len( buildList) NetworkCost_USD = NetworkCost_USD * nBuildinNtw / len(buildList) else: NetworkCost_USD = network_features.pipesCosts_DHN_USD NetworkCost_USD = NetworkCost_USD * nBuildinNtw / len(buildList) NetworkCost_a_USD = NetworkCost_USD * gv.PipeInterestRate * ( 1 + gv.PipeInterestRate)**gv.PipeLifeTime / ( (1 + gv.PipeInterestRate)**gv.PipeLifeTime - 1) addcosts_Capex_a_USD += NetworkCost_a_USD addcosts_Capex_USD += NetworkCost_USD # HEX (1 per building in ntw) for (index, building_name) in zip(DHN_barcode, buildList): if index == "1": df = pd.read_csv( locator.get_optimization_substations_results_file( building_name), usecols=["Q_dhw_W", "Q_heating_W"]) subsArray = np.array(df) Q_max_W = np.amax(subsArray[:, 0] + subsArray[:, 1]) Capex_a_HEX_building_USD, Opex_fixed_HEX_building_USD, Capex_HEX_building_USD = hex.calc_Cinv_HEX( Q_max_W, locator, config, 'HEX1') addcosts_Capex_a_USD += Capex_a_HEX_building_USD addcosts_Opex_fixed_USD += Opex_fixed_HEX_building_USD addcosts_Capex_USD += Capex_HEX_building_USD # HEX for solar roof_area_m2 = np.array( pd.read_csv(locator.get_total_demand(), usecols=["Aroof_m2"])) areaAvail = 0 for i in range(len(DHN_barcode)): index = DHN_barcode[i] if index == "1": areaAvail += roof_area_m2[i][0] for i in range(len(DHN_barcode)): index = DHN_barcode[i] if index == "1": share = roof_area_m2[i][0] / areaAvail #print share, "solar area share", buildList[i] Q_max_SC_ET_Wh = solar_features.Q_nom_SC_ET_Wh * master_to_slave_vars.SOLAR_PART_SC_ET * share Capex_a_HEX_SC_ET_USD, Opex_fixed_HEX_SC_ET_USD, Capex_HEX_SC_ET_USD = hex.calc_Cinv_HEX( Q_max_SC_ET_Wh, locator, config, 'HEX1') addcosts_Capex_a_USD += Capex_a_HEX_SC_ET_USD addcosts_Opex_fixed_USD += Opex_fixed_HEX_SC_ET_USD addcosts_Capex_USD += Capex_HEX_SC_ET_USD Q_max_SC_FP_Wh = solar_features.Q_nom_SC_FP_Wh * master_to_slave_vars.SOLAR_PART_SC_FP * share Capex_a_HEX_SC_FP_USD, Opex_fixed_HEX_SC_FP_USD, Capex_HEX_SC_FP_USD = hex.calc_Cinv_HEX( Q_max_SC_FP_Wh, locator, config, 'HEX1') addcosts_Capex_a_USD += Capex_a_HEX_SC_FP_USD addcosts_Opex_fixed_USD += Opex_fixed_HEX_SC_FP_USD addcosts_Capex_USD += Capex_HEX_SC_FP_USD Q_max_PVT_Wh = solar_features.Q_nom_PVT_Wh * master_to_slave_vars.SOLAR_PART_PVT * share Capex_a_HEX_PVT_USD, Opex_fixed_HEX_PVT_USD, Capex_HEX_PVT_USD = hex.calc_Cinv_HEX( Q_max_PVT_Wh, locator, config, 'HEX1') addcosts_Capex_a_USD += Capex_a_HEX_PVT_USD addcosts_Opex_fixed_USD += Opex_fixed_HEX_PVT_USD addcosts_Capex_USD += Capex_HEX_PVT_USD # Pump operation costs Capex_a_pump_USD, Opex_fixed_pump_USD, Opex_var_pump_USD, Capex_pump_USD = pumps.calc_Ctot_pump( master_to_slave_vars, network_features, gv, locator, lca, config) addcosts_Capex_a_USD += Capex_a_pump_USD addcosts_Opex_fixed_USD += Opex_fixed_pump_USD addcosts_Capex_USD += Capex_pump_USD # import gas consumption data from: if DHN_barcode.count("1") > 0 and config.district_heating_network: # import gas consumption data from: EgasPrimaryDataframe_W = pd.read_csv( locator.get_optimization_slave_natural_gas_imports( master_to_slave_vars.individual_number, master_to_slave_vars.generation_number)) E_gas_primary_peak_power_W = np.amax( EgasPrimaryDataframe_W['NG_total_W']) GasConnectionInvCost = ngas.calc_Cinv_gas(E_gas_primary_peak_power_W, gv) elif DCN_barcode.count("1") > 0 and config.district_cooling_network: EgasPrimaryDataframe_W = pd.read_csv( locator.get_optimization_slave_natural_gas_imports( master_to_slave_vars.individual_number, master_to_slave_vars.generation_number)) E_gas_primary_peak_power_W = np.amax( EgasPrimaryDataframe_W['NG_total_W']) GasConnectionInvCost = ngas.calc_Cinv_gas(E_gas_primary_peak_power_W, gv) else: GasConnectionInvCost = 0.0 addcosts_Capex_a_USD += GasConnectionInvCost # Save data results = pd.DataFrame({ "Capex_a_SC_ET_USD": [Capex_a_SC_ET_USD], "Capex_a_SC_FP_USD": [Capex_a_SC_FP_USD], "Opex_fixed_SC": [Opex_fixed_SC], "Capex_a_PVT": [Capex_a_PVT_USD], "Opex_fixed_PVT": [Opex_fixed_PVT_USD], "Capex_a_Boiler_backup": [Capex_a_Boiler_backup_USD], "Opex_fixed_Boiler_backup": [Opex_fixed_Boiler_backup_USD], "Capex_a_storage_HEX": [Capex_a_HP_storage_USD], "Opex_fixed_storage_HEX": [Opex_fixed_HP_storage_USD], "Capex_a_storage_HP": [Capex_a_storage_HP], "Capex_a_CHP": [Capex_a_CHP_USD], "Opex_fixed_CHP": [Opex_fixed_CHP_USD], "StorageInvC": [StorageInvC], "StorageCostSum": [StorageInvC + Capex_a_storage_HP + Capex_a_HEX], "NetworkCost": [NetworkCost_a_USD], "SubstHEXCost": [SubstHEXCost_capex], "DHNInvestCost": [addcosts_Capex_a_USD - CostDiscBuild], "PVTHEXCost_Capex": [PVTHEXCost_Capex], "CostDiscBuild": [CostDiscBuild], "CO2DiscBuild": [CO2DiscBuild], "PrimDiscBuild": [PrimDiscBuild], "Capex_a_furnace": [Capex_a_furnace_USD], "Opex_fixed_furnace": [Opex_fixed_furnace_USD], "Capex_a_Boiler": [Capex_a_Boiler_USD], "Opex_fixed_Boiler": [Opex_fixed_Boiler_USD], "Capex_a_Boiler_peak": [Capex_a_Boiler_peak_USD], "Opex_fixed_Boiler_peak": [Opex_fixed_Boiler_peak_USD], "Capex_Disconnected": [Capex_Disconnected], "Opex_Disconnected": [Opex_Disconnected], "Capex_a_Lake": [Capex_a_Lake_USD], "Opex_fixed_Lake": [Opex_fixed_Lake_USD], "Capex_a_Sewage": [Capex_a_Sewage_USD], "Opex_fixed_Sewage": [Opex_fixed_Sewage_USD], "SCHEXCost_Capex": [SCHEXCost_Capex], "Capex_a_pump": [Capex_a_pump_USD], "Opex_fixed_pump": [Opex_fixed_pump_USD], "Opex_var_pump": [Opex_var_pump_USD], "Sum_CAPEX": [addcosts_Capex_a_USD], "Sum_OPEX_fixed": [addcosts_Opex_fixed_USD], "GasConnectionInvCa": [GasConnectionInvCost], "CO2_PV_disconnected": [CO2_PV_disconnected], "cost_PV_disconnected": [cost_PV_disconnected], "Eprim_PV_disconnected": [Eprim_PV_disconnected], "Capex_SC_ET_USD": [Capex_SC_ET_USD], "Capex_SC_FP_USD": [Capex_SC_FP_USD], "Capex_PVT": [Capex_PVT_USD], "Capex_Boiler_backup": [Capex_Boiler_backup_USD], "Capex_storage_HEX": [Capex_HP_storage_USD], "Capex_storage_HP": [Capex_storage_HP], "Capex_CHP": [Capex_CHP_USD], "Capex_furnace": [Capex_furnace_USD], "Capex_Boiler_base": [Capex_Boiler_USD], "Capex_Boiler_peak": [Capex_Boiler_peak_USD], "Capex_Lake": [Capex_Lake_USD], "Capex_Sewage": [Capex_Sewage_USD], "Capex_pump": [Capex_pump_USD], }) results.to_csv(locator.get_optimization_slave_investment_cost_detailed( master_to_slave_vars.individual_number, master_to_slave_vars.generation_number), sep=',') return (addcosts_Capex_a_USD + addcosts_Opex_fixed_USD, addCO2, addPrim)
def calc_generation_costs_heating( locator, master_to_slave_vars, config, storage_activation_data, ): """ Computes costs / GHG emisions / primary energy needs for the individual addCosts = additional costs addCO2 = GHG emissions addPrm = primary energy needs :param DHN_barcode: parameter indicating if the building is connected or not :param buildList: list of buildings in the district :param locator: input locator set to scenario :param master_to_slave_vars: class containing the features of a specific individual :param Q_uncovered_design_W: hourly max of the heating uncovered demand :param Q_uncovered_annual_W: total heating uncovered :param solar_features: solar features :param thermal_network: network features :type indCombi: string :type buildList: list :type locator: string :type master_to_slave_vars: class :type Q_uncovered_design_W: float :type Q_uncovered_annual_W: float :type solar_features: class :type thermal_network: class :return: returns the objectives addCosts, addCO2, addPrim :rtype: tuple """ thermal_network = pd.read_csv( locator.get_optimization_thermal_network_data_file( master_to_slave_vars.network_data_file_heating)) # CCGT if master_to_slave_vars.CC_on == 1: CC_size_W = master_to_slave_vars.CCGT_SIZE_W Capex_a_CHP_NG_USD, Opex_fixed_CHP_NG_USD, Capex_CHP_NG_USD = chp.calc_Cinv_CCGT( CC_size_W, locator, config) else: Capex_a_CHP_NG_USD = 0.0 Opex_fixed_CHP_NG_USD = 0.0 Capex_CHP_NG_USD = 0.0 # DRY BIOMASS if master_to_slave_vars.Furnace_dry_on == 1: Dry_Furnace_size_W = master_to_slave_vars.DBFurnace_Q_max_W Capex_a_furnace_dry_USD, \ Opex_fixed_furnace_dry_USD, \ Capex_furnace_dry_USD = furnace.calc_Cinv_furnace(Dry_Furnace_size_W, locator, 'FU1') else: Capex_furnace_dry_USD = 0.0 Capex_a_furnace_dry_USD = 0.0 Opex_fixed_furnace_dry_USD = 0.0 # WET BIOMASS if master_to_slave_vars.Furnace_wet_on == 1: Wet_Furnace_size_W = master_to_slave_vars.WBFurnace_Q_max_W Capex_a_furnace_wet_USD, \ Opex_fixed_furnace_wet_USD, \ Capex_furnace_wet_USD = furnace.calc_Cinv_furnace(Wet_Furnace_size_W, locator, 'FU1') else: Capex_a_furnace_wet_USD = 0.0 Opex_fixed_furnace_wet_USD = 0.0 Capex_furnace_wet_USD = 0.0 # BOILER BASE LOAD if master_to_slave_vars.Boiler_on == 1: Q_design_W = master_to_slave_vars.Boiler_Q_max_W Capex_a_BaseBoiler_NG_USD, \ Opex_fixed_BaseBoiler_NG_USD, \ Capex_BaseBoiler_NG_USD = boiler.calc_Cinv_boiler(Q_design_W, locator, config, 'BO1') else: Capex_a_BaseBoiler_NG_USD = 0.0 Opex_fixed_BaseBoiler_NG_USD = 0.0 Capex_BaseBoiler_NG_USD = 0.0 # BOILER PEAK LOAD if master_to_slave_vars.BoilerPeak_on == 1: Q_design_W = master_to_slave_vars.BoilerPeak_Q_max_W Capex_a_PeakBoiler_NG_USD, \ Opex_fixed_PeakBoiler_NG_USD, \ Capex_PeakBoiler_NG_USD = boiler.calc_Cinv_boiler(Q_design_W, locator, config, 'BO1') else: Capex_a_PeakBoiler_NG_USD = 0.0 Opex_fixed_PeakBoiler_NG_USD = 0.0 Capex_PeakBoiler_NG_USD = 0.0 # HEATPUMP LAKE if master_to_slave_vars.HPLake_on == 1: HP_Size_W = master_to_slave_vars.HPLake_maxSize_W Capex_a_Lake_USD, \ Opex_fixed_Lake_USD, \ Capex_Lake_USD = hp.calc_Cinv_HP(HP_Size_W, locator, 'HP2') else: Capex_a_Lake_USD = 0.0 Opex_fixed_Lake_USD = 0.0 Capex_Lake_USD = 0.0 # HEATPUMP_SEWAGE if master_to_slave_vars.HPSew_on == 1: HP_Size_W = master_to_slave_vars.HPSew_maxSize_W Capex_a_Sewage_USD, \ Opex_fixed_Sewage_USD, \ Capex_Sewage_USD = hp.calc_Cinv_HP(HP_Size_W, locator, 'HP2') else: Capex_a_Sewage_USD = 0.0 Opex_fixed_Sewage_USD = 0.0 Capex_Sewage_USD = 0.0 # GROUND HEAT PUMP if master_to_slave_vars.GHP_on == 1: GHP_Enom_W = master_to_slave_vars.GHP_maxSize_W Capex_a_GHP_USD, \ Opex_fixed_GHP_USD, \ Capex_GHP_USD = hp.calc_Cinv_GHP(GHP_Enom_W, locator, config) else: Capex_a_GHP_USD = 0.0 Opex_fixed_GHP_USD = 0.0 Capex_GHP_USD = 0.0 # BACK-UP BOILER if master_to_slave_vars.BackupBoiler_on != 0: Q_backup_W = master_to_slave_vars.BackupBoiler_size_W Capex_a_BackupBoiler_NG_USD, \ Opex_fixed_BackupBoiler_NG_USD, \ Capex_BackupBoiler_NG_USD = boiler.calc_Cinv_boiler(Q_backup_W, locator, config, 'BO1') else: Capex_a_BackupBoiler_NG_USD = 0.0 Opex_fixed_BackupBoiler_NG_USD = 0.0 Capex_BackupBoiler_NG_USD = 0.0 # DATA CENTRE SOURCE HEAT PUMP if master_to_slave_vars.WasteServersHeatRecovery == 1: Q_HEX_max_Wh = thermal_network["Qcdata_netw_total_kWh"].max( ) * 1000 # convert to Wh Capex_a_wasteserver_HEX_USD, Opex_fixed_wasteserver_HEX_USD, Capex_wasteserver_HEX_USD = hex.calc_Cinv_HEX( Q_HEX_max_Wh, locator, config, 'HEX1') Q_HP_max_Wh = storage_activation_data["Q_HP_Server_W"].max() Capex_a_wasteserver_HP_USD, Opex_fixed_wasteserver_HP_USD, Capex_wasteserver_HP_USD = hp.calc_Cinv_HP( Q_HP_max_Wh, locator, 'HP2') else: Capex_a_wasteserver_HEX_USD = 0.0 Opex_fixed_wasteserver_HEX_USD = 0.0 Capex_wasteserver_HEX_USD = 0.0 Capex_a_wasteserver_HP_USD = 0.0 Opex_fixed_wasteserver_HP_USD = 0.0 Capex_wasteserver_HP_USD = 0.0 # SOLAR TECHNOLOGIES # ADD COSTS AND EMISSIONS DUE TO SOLAR TECHNOLOGIES SC_ET_area_m2 = master_to_slave_vars.A_SC_ET_m2 Capex_a_SC_ET_USD, \ Opex_fixed_SC_ET_USD, \ Capex_SC_ET_USD = stc.calc_Cinv_SC(SC_ET_area_m2, locator, 'ET') SC_FP_area_m2 = master_to_slave_vars.A_SC_FP_m2 Capex_a_SC_FP_USD, \ Opex_fixed_SC_FP_USD, \ Capex_SC_FP_USD = stc.calc_Cinv_SC(SC_FP_area_m2, locator, 'FP') PVT_peak_kW = master_to_slave_vars.A_PVT_m2 * N_PVT # kW Capex_a_PVT_USD, \ Opex_fixed_PVT_USD, \ Capex_PVT_USD = pvt.calc_Cinv_PVT(PVT_peak_kW, locator, config) # HEATPUMP FOR SOLAR UPGRADE TO DISTRICT HEATING Q_HP_max_PVT_wh = storage_activation_data["Q_HP_PVT_W"].max() Capex_a_HP_PVT_USD, \ Opex_fixed_HP_PVT_USD, \ Capex_HP_PVT_USD = hp.calc_Cinv_HP(Q_HP_max_PVT_wh, locator, 'HP2') # hack split into two technologies Q_HP_max_SC_ET_Wh = storage_activation_data["Q_HP_SC_ET_W"].max() Capex_a_HP_SC_ET_USD, \ Opex_fixed_HP_SC_ET_USD, \ Capex_HP_SC_ET_USD = hp.calc_Cinv_HP(Q_HP_max_SC_ET_Wh, locator, 'HP2') Q_HP_max_SC_FP_Wh = storage_activation_data["Q_HP_SC_FP_W"].max() Capex_a_HP_SC_FP_USD, \ Opex_fixed_HP_SC_FP_USD, \ Capex_HP_SC_FP_USD = hp.calc_Cinv_HP(Q_HP_max_SC_FP_Wh, locator, 'HP2') # HEAT EXCHANGER FOR SOLAR COLLECTORS Q_max_SC_ET_Wh = (storage_activation_data["Q_SC_ET_gen_directload_W"] + storage_activation_data["Q_SC_ET_gen_storage_W"]).max() Capex_a_HEX_SC_ET_USD, \ Opex_fixed_HEX_SC_ET_USD, \ Capex_HEX_SC_ET_USD = hex.calc_Cinv_HEX(Q_max_SC_ET_Wh, locator, config, 'HEX1') Q_max_SC_FP_Wh = (storage_activation_data["Q_SC_FP_gen_directload_W"] + storage_activation_data["Q_SC_FP_gen_storage_W"]).max() Capex_a_HEX_SC_FP_USD, \ Opex_fixed_HEX_SC_FP_USD, \ Capex_HEX_SC_FP_USD = hex.calc_Cinv_HEX(Q_max_SC_FP_Wh, locator, config, 'HEX1') Q_max_PVT_Wh = (storage_activation_data["Q_PVT_gen_directload_W"] + storage_activation_data["Q_PVT_gen_storage_W"]).max() Capex_a_HEX_PVT_USD, \ Opex_fixed_HEX_PVT_USD, \ Capex_HEX_PVT_USD = hex.calc_Cinv_HEX(Q_max_PVT_Wh, locator, config, 'HEX1') performance_costs = { "Capex_a_SC_ET_connected_USD": Capex_a_SC_ET_USD + Capex_a_HP_SC_ET_USD + Capex_a_HEX_SC_ET_USD, "Capex_a_SC_FP_connected_USD": Capex_a_SC_FP_USD + Capex_a_HP_SC_FP_USD + Capex_a_HEX_SC_FP_USD, "Capex_a_PVT_connected_USD": Capex_a_PVT_USD + Capex_a_HP_PVT_USD + Capex_a_HEX_PVT_USD, "Capex_a_HP_Server_connected_USD": Capex_a_wasteserver_HP_USD + Capex_a_wasteserver_HEX_USD, "Capex_a_HP_Sewage_connected_USD": Capex_a_Sewage_USD, "Capex_a_HP_Lake_connected_USD": Capex_a_Lake_USD, "Capex_a_GHP_connected_USD": Capex_a_GHP_USD, "Capex_a_CHP_NG_connected_USD": Capex_a_CHP_NG_USD, "Capex_a_Furnace_wet_connected_USD": Capex_a_furnace_wet_USD, "Capex_a_Furnace_dry_connected_USD": Capex_a_furnace_dry_USD, "Capex_a_BaseBoiler_NG_connected_USD": Capex_a_BaseBoiler_NG_USD, "Capex_a_PeakBoiler_NG_connected_USD": Capex_a_PeakBoiler_NG_USD, "Capex_a_BackupBoiler_NG_connected_USD": Capex_a_BackupBoiler_NG_USD, # total_capex "Capex_total_SC_ET_connected_USD": Capex_SC_ET_USD + Capex_HP_SC_ET_USD + Capex_HEX_SC_ET_USD, "Capex_total_SC_FP_connected_USD": Capex_SC_FP_USD + Capex_HP_SC_FP_USD + Capex_HEX_SC_FP_USD, "Capex_total_PVT_connected_USD": Capex_PVT_USD + Capex_HP_PVT_USD + Capex_HEX_PVT_USD, "Capex_total_HP_Server_connected_USD": Capex_wasteserver_HP_USD + Capex_wasteserver_HEX_USD, "Capex_total_HP_Sewage_connected_USD": Capex_Sewage_USD, "Capex_total_HP_Lake_connected_USD": Capex_Lake_USD, "Capex_total_GHP_connected_USD": Capex_GHP_USD, "Capex_total_CHP_NG_connected_USD": Capex_CHP_NG_USD, "Capex_total_Furnace_wet_connected_USD": Capex_furnace_wet_USD, "Capex_total_Furnace_dry_connected_USD": Capex_furnace_dry_USD, "Capex_total_BaseBoiler_NG_connected_USD": Capex_BaseBoiler_NG_USD, "Capex_total_PeakBoiler_NG_connected_USD": Capex_PeakBoiler_NG_USD, "Capex_total_BackupBoiler_NG_connected_USD": Capex_BackupBoiler_NG_USD, # opex fixed costs "Opex_fixed_SC_ET_connected_USD": Opex_fixed_SC_ET_USD, "Opex_fixed_SC_FP_connected_USD": Opex_fixed_SC_FP_USD, "Opex_fixed_PVT_connected_USD": Opex_fixed_PVT_USD, "Opex_fixed_HP_Server_connected_USD": Opex_fixed_wasteserver_HP_USD + Opex_fixed_wasteserver_HEX_USD, "Opex_fixed_HP_Sewage_connected_USD": Opex_fixed_Sewage_USD, "Opex_fixed_HP_Lake_connected_USD": Opex_fixed_Lake_USD, "Opex_fixed_GHP_connected_USD": Opex_fixed_GHP_USD, "Opex_fixed_CHP_NG_connected_USD": Opex_fixed_CHP_NG_USD, "Opex_fixed_Furnace_wet_connected_USD": Opex_fixed_furnace_wet_USD, "Opex_fixed_Furnace_dry_connected_USD": Opex_fixed_furnace_dry_USD, "Opex_fixed_BaseBoiler_NG_connected_USD": Opex_fixed_BaseBoiler_NG_USD, "Opex_fixed_PeakBoiler_NG_connected_USD": Opex_fixed_PeakBoiler_NG_USD, "Opex_fixed_BackupBoiler_NG_connected_USD": Opex_fixed_BackupBoiler_NG_USD, } return performance_costs
def disconnected_buildings_cooling_main(locator, building_names, total_demand, 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 cooling energy supply system configurations are calculated and compared 1 to 1 to each other. it is a classical combinatorial problem. The six supply system configurations include: (VCC: Vapor Compression Chiller, ACH: Absorption Chiller, CT: Cooling Tower, Boiler) (AHU: Air Handling Units, ARU: Air Recirculation Units, SCU: Sensible Cooling Units) - config 0: Direct Expansion / Mini-split units (NOTE: this configuration is not fully built yet) - config 1: VCC_to_AAS (AHU + ARU + SCU) + CT - config 2: FP + single-effect ACH_to_AAS (AHU + ARU + SCU) + Boiler + CT - config 3: ET + single-effect ACH_to_AAS (AHU + ARU + SCU) + Boiler + CT - config 4: VCC_to_AA (AHU + ARU) + VCC_to_S (SCU) + CT - config 5: VCC_to_AA (AHU + ARU) + single effect ACH_S (SCU) + CT + Boiler Note: 1. Only cooling supply configurations are compared here. The demand for electricity is supplied from the grid, and the demand for domestic hot water is supplied from electric boilers. 2. Single-effect chillers are coupled with flat-plate solar collectors, and the double-effect chillers are coupled with evacuated tube solar collectors. :param locator: locator class with paths to input/output files :param building_names: list with names of buildings :param config: cea.config :param prices: prices class :return: one .csv file with results of operations of disconnected buildings; one .csv file with operation of the best configuration (Cost, CO2, Primary Energy) """ t0 = time.clock() for building_name in building_names: ## Calculate cooling loads for different combinations # SENSIBLE COOLING UNIT Qc_nom_SCU_W, \ T_re_SCU_K, \ T_sup_SCU_K, \ mdot_SCU_kgpers = calc_combined_cooling_loads(building_name, locator, total_demand, cooling_configuration=['scu']) # AIR HANDLING UNIT + AIR RECIRCULATION UNIT Qc_nom_AHU_ARU_W, \ T_re_AHU_ARU_K, \ T_sup_AHU_ARU_K, \ mdot_AHU_ARU_kgpers = calc_combined_cooling_loads(building_name, locator, total_demand, cooling_configuration=['ahu', 'aru']) # SENSIBLE COOLING UNIT + AIR HANDLING UNIT + AIR RECIRCULATION UNIT Qc_nom_AHU_ARU_SCU_W, \ T_re_AHU_ARU_SCU_K, \ T_sup_AHU_ARU_SCU_K, \ mdot_AHU_ARU_SCU_kgpers = calc_combined_cooling_loads(building_name, locator, total_demand, cooling_configuration=['ahu', 'aru', 'scu']) ## Get hourly hot water supply condition of Solar Collectors (SC) # Flate Plate Solar Collectors SC_FP_data, T_hw_in_FP_C, el_aux_SC_FP_Wh, q_sc_gen_FP_Wh = get_SC_data(building_name, locator, panel_type="FP") Capex_a_SC_FP_USD, Opex_SC_FP_USD, Capex_SC_FP_USD = solar_collector.calc_Cinv_SC(SC_FP_data['Area_SC_m2'][0], locator, panel_type="FP") # Evacuated Tube Solar Collectors SC_ET_data, T_hw_in_ET_C, el_aux_SC_ET_Wh, q_sc_gen_ET_Wh = get_SC_data(building_name, locator, panel_type="ET") Capex_a_SC_ET_USD, Opex_SC_ET_USD, Capex_SC_ET_USD = solar_collector.calc_Cinv_SC(SC_ET_data['Area_SC_m2'][0], locator, panel_type="ET") ## Calculate ground temperatures to estimate cold water supply temperatures for absorption chiller T_ground_K = calculate_ground_temperature(locator, config) # FIXME: change to outlet temperature from the cooling towers ## Initialize table to save results # save costs of all supply configurations operation_results = initialize_result_tables_for_supply_configurations(Qc_nom_SCU_W) # save supply system activation of all supply configurations cooling_dispatch = {} ## HOURLY OPERATION print building_name, ' decentralized cooling supply system simulations...' T_re_AHU_ARU_SCU_K = np.where(T_re_AHU_ARU_SCU_K > 0.0, T_re_AHU_ARU_SCU_K, T_sup_AHU_ARU_SCU_K) ## 0. DX operation print 'Config 0: Direct Expansion Units -> AHU,ARU,SCU' el_DX_hourly_Wh,\ q_DX_chw_Wh = np.vectorize(dx.calc_DX)(mdot_AHU_ARU_SCU_kgpers, T_sup_AHU_ARU_SCU_K, T_re_AHU_ARU_SCU_K) DX_Status = np.where(q_DX_chw_Wh > 0.0, 1, 0) # add electricity costs, CO2, PE operation_results[0][7] += sum(lca.ELEC_PRICE * el_DX_hourly_Wh) operation_results[0][8] += sum(el_DX_hourly_Wh * WH_TO_J / 1E6 * lca.EL_TO_CO2 / 1E3) # ton CO2 operation_results[0][9] += sum(el_DX_hourly_Wh * WH_TO_J / 1E6 * lca.EL_TO_OIL_EQ) # MJ oil # activation cooling_dispatch[0] = {'Q_DX_gen_directload_W': q_DX_chw_Wh, 'E_DX_req_W': el_DX_hourly_Wh, 'DX_Status': DX_Status, 'E_cs_cre_cdata_req_W': el_DX_hourly_Wh, } ## 1. VCC (AHU + ARU + SCU) + CT print 'Config 1: Vapor Compression Chillers -> AHU,ARU,SCU' # VCC operation el_VCC_Wh, q_VCC_cw_Wh, q_VCC_chw_Wh = calc_VCC_operation(T_re_AHU_ARU_SCU_K, T_sup_AHU_ARU_SCU_K, mdot_AHU_ARU_SCU_kgpers) VCC_Status = np.where(q_VCC_chw_Wh > 0.0, 1, 0) # CT operation q_CT_VCC_to_AHU_ARU_SCU_Wh = q_VCC_cw_Wh Q_nom_CT_VCC_to_AHU_ARU_SCU_W, el_CT_Wh = calc_CT_operation(q_CT_VCC_to_AHU_ARU_SCU_Wh) # add costs el_total_Wh = el_VCC_Wh + el_CT_Wh operation_results[1][7] += sum(lca.ELEC_PRICE * el_total_Wh) # CHF operation_results[1][8] += sum(el_total_Wh * WH_TO_J / 1E6 * lca.EL_TO_CO2 / 1E3) # ton CO2 operation_results[1][9] += sum(el_total_Wh * WH_TO_J / 1E6 * lca.EL_TO_OIL_EQ) # MJ-oil-eq cooling_dispatch[1] = {'Q_VCC_gen_directload_W': q_VCC_chw_Wh, 'E_VCC_req_W': el_VCC_Wh, 'E_CT_req_W': el_CT_Wh, 'E_cs_cre_cdata_req_W': el_total_Wh, 'VCC_Status': VCC_Status } ## 2: SC_FP + single-effect ACH (AHU + ARU + SCU) + CT + Boiler + SC_FP print 'Config 2: Flat-plate Solar Collectors + Single-effect Absorption chillers -> AHU,ARU,SCU' # ACH operation T_hw_out_single_ACH_K, \ el_single_ACH_Wh, \ q_cw_single_ACH_Wh, \ q_hw_single_ACH_Wh,\ q_chw_single_ACH_Wh = calc_ACH_operation(T_ground_K, T_hw_in_FP_C, T_re_AHU_ARU_SCU_K, T_sup_AHU_ARU_SCU_K, locator, mdot_AHU_ARU_SCU_kgpers, ACH_TYPE_SINGLE) ACH_Status = np.where(q_chw_single_ACH_Wh > 0.0, 1, 0) # CT operation q_CT_FP_to_single_ACH_to_AHU_ARU_SCU_Wh = q_cw_single_ACH_Wh Q_nom_CT_FP_to_single_ACH_to_AHU_ARU_SCU_W, el_CT_Wh = calc_CT_operation( q_CT_FP_to_single_ACH_to_AHU_ARU_SCU_Wh) # boiler operation q_gas_Boiler_FP_to_single_ACH_to_AHU_ARU_SCU_Wh, \ Q_nom_Boiler_FP_to_single_ACH_to_AHU_ARU_SCU_W, \ q_load_Boiler_FP_to_single_ACH_to_AHU_ARU_SCU_Wh = calc_boiler_operation(Qc_nom_AHU_ARU_SCU_W, T_hw_out_single_ACH_K, q_hw_single_ACH_Wh, q_sc_gen_FP_Wh) # add electricity costs el_total_Wh = el_single_ACH_Wh + el_aux_SC_FP_Wh + el_CT_Wh operation_results[2][7] += sum(lca.ELEC_PRICE * el_total_Wh) # CHF operation_results[2][8] += sum(el_total_Wh * WH_TO_J / 1E6 * lca.EL_TO_CO2 / 1E3) # ton CO2 operation_results[2][9] += sum(el_total_Wh * WH_TO_J / 1E6 * lca.EL_TO_OIL_EQ) # MJ-oil-eq # add gas costs q_gas_total_Wh = q_gas_Boiler_FP_to_single_ACH_to_AHU_ARU_SCU_Wh operation_results[2][7] += sum(prices.NG_PRICE * q_gas_total_Wh) # CHF operation_results[2][8] += sum(q_gas_total_Wh * WH_TO_J / 1E6 * lca.NG_BACKUPBOILER_TO_CO2_STD / 1E3) # ton CO2 operation_results[2][9] += sum(q_gas_total_Wh * WH_TO_J / 1E6 * lca.NG_BACKUPBOILER_TO_OIL_STD) # MJ-oil-eq # add activation cooling_dispatch[2] = {'Q_ACH_gen_directload_W': q_chw_single_ACH_Wh, 'ACH_Status': ACH_Status, 'Q_Boiler_ACH_W': q_load_Boiler_FP_to_single_ACH_to_AHU_ARU_SCU_Wh, 'Q_SC_FP_ACH_W': q_sc_gen_FP_Wh, 'E_ACH_req_W': el_single_ACH_Wh, 'E_CT_req_W': el_CT_Wh, 'E_SC_FP_req_W': el_aux_SC_FP_Wh, 'E_cs_cre_cdata_req_W': el_total_Wh, 'NG_Boiler_req': q_gas_Boiler_FP_to_single_ACH_to_AHU_ARU_SCU_Wh, } # 3: SC_ET + single-effect ACH (AHU + ARU + SCU) + CT + Boiler + SC_ET print 'Config 3: Evacuated Tube Solar Collectors + Single-effect Absorption chillers -> AHU,ARU,SCU' # ACH operation T_hw_out_single_ACH_K, \ el_single_ACH_Wh, \ q_cw_single_ACH_Wh, \ q_hw_single_ACH_Wh,\ q_chw_single_ACH_Wh = calc_ACH_operation(T_ground_K, T_hw_in_ET_C, T_re_AHU_ARU_SCU_K, T_sup_AHU_ARU_SCU_K, locator, mdot_AHU_ARU_SCU_kgpers, ACH_TYPE_SINGLE) # CT operation q_CT_ET_to_single_ACH_to_AHU_ARU_SCU_W = q_cw_single_ACH_Wh Q_nom_CT_ET_to_single_ACH_to_AHU_ARU_SCU_W, el_CT_Wh = calc_CT_operation(q_CT_ET_to_single_ACH_to_AHU_ARU_SCU_W) # burner operation q_gas_for_burner_Wh, \ Q_nom_Burner_ET_to_single_ACH_to_AHU_ARU_SCU_W,\ q_burner_load_Wh = calc_burner_operation(Qc_nom_AHU_ARU_SCU_W, q_hw_single_ACH_Wh, q_sc_gen_ET_Wh) # add electricity costs el_total_Wh = el_single_ACH_Wh + el_aux_SC_ET_Wh + el_CT_Wh operation_results[3][7] += sum(lca.ELEC_PRICE * el_total_Wh) # CHF operation_results[3][8] += sum(el_total_Wh * WH_TO_J / 1E6 * lca.EL_TO_CO2 / 1E3) # ton CO2 operation_results[3][9] += sum(el_total_Wh * WH_TO_J / 1E6 * lca.EL_TO_OIL_EQ) # MJ-oil-eq # add gas costs operation_results[3][7] += sum(prices.NG_PRICE * q_gas_for_burner_Wh) # CHF operation_results[3][8] += sum( q_gas_for_burner_Wh * WH_TO_J / 1E6 * lca.NG_BACKUPBOILER_TO_CO2_STD / 1E3) # ton CO2 operation_results[3][9] += sum( q_gas_for_burner_Wh * WH_TO_J / 1E6 * lca.NG_BACKUPBOILER_TO_OIL_STD) # MJ-oil-eq # add activation cooling_dispatch[3] = {'Q_ACH_gen_directload_W': q_chw_single_ACH_Wh, 'ACH_Status': ACH_Status, 'Q_Burner_ACH_W': q_burner_load_Wh, 'Q_SC_ET_ACH_W': q_sc_gen_ET_Wh, 'E_ACH_req_W': el_single_ACH_Wh, 'E_CT_req_W': el_CT_Wh, 'E_SC_FP_req_W': el_aux_SC_ET_Wh, 'E_cs_cre_cdata_req_W': el_total_Wh, 'NG_Burner_req': q_gas_for_burner_Wh, } # these two configurations are only activated when SCU is in use if Qc_nom_SCU_W > 0.0: # 4: VCC (AHU + ARU) + VCC (SCU) + CT print 'Config 4: Vapor Compression Chillers(HT) -> SCU & Vapor Compression Chillers(LT) -> AHU,ARU' # VCC (AHU + ARU) operation el_VCC_to_AHU_ARU_Wh, \ q_cw_VCC_to_AHU_ARU_Wh,\ q_chw_VCC_to_AHU_ARU_Wh = calc_VCC_operation(T_re_AHU_ARU_K, T_sup_AHU_ARU_K, mdot_AHU_ARU_kgpers) VCC_LT_Status = np.where(q_chw_VCC_to_AHU_ARU_Wh > 0.0, 1, 0) # VCC(SCU) operation el_VCC_to_SCU_Wh, \ q_cw_VCC_to_SCU_Wh,\ q_chw_VCC_to_SCU_Wh = calc_VCC_operation(T_re_SCU_K, T_sup_SCU_K, mdot_SCU_kgpers) VCC_HT_Status = np.where(q_chw_VCC_to_AHU_ARU_Wh > 0.0, 1, 0) # CT operation q_CT_VCC_to_AHU_ARU_and_VCC_to_SCU_W = q_cw_VCC_to_AHU_ARU_Wh + q_cw_VCC_to_SCU_Wh Q_nom_CT_VCC_to_AHU_ARU_and_VCC_to_SCU_W, el_CT_Wh = calc_CT_operation(q_CT_VCC_to_AHU_ARU_and_VCC_to_SCU_W) # add el costs el_total_Wh = el_VCC_to_AHU_ARU_Wh + el_VCC_to_SCU_Wh + el_CT_Wh operation_results[4][7] += sum(lca.ELEC_PRICE * el_total_Wh) # CHF operation_results[4][8] += sum(el_total_Wh * WH_TO_J / 1E6 * lca.EL_TO_CO2 / 1E3) # ton CO2 operation_results[4][9] += sum(el_total_Wh * WH_TO_J / 1E6 * lca.EL_TO_OIL_EQ) # MJ-oil-eq # add activation cooling_dispatch[4] = {'Q_VCC_LT_gen_directload_W': q_chw_VCC_to_AHU_ARU_Wh, 'Q_VCC_HT_gen_directload_W': q_chw_VCC_to_SCU_Wh, 'VCC_LT_Status': VCC_LT_Status, 'VCC_HT_Status': VCC_HT_Status, 'E_VCC_LT_req_W': el_VCC_to_AHU_ARU_Wh, 'E_VCC_HT_req_W': el_VCC_to_SCU_Wh, 'E_CT_req_W': el_CT_Wh, 'E_cs_cre_cdata_req_W': el_total_Wh } # 5: VCC (AHU + ARU) + ACH (SCU) + CT print 'Config 5: Vapor Compression Chillers(LT) -> AHU,ARU & Flate-place SC + Absorption Chillers(HT) -> SCU' # ACH (SCU) operation T_hw_FP_ACH_to_SCU_K, \ el_FP_ACH_to_SCU_Wh, \ q_cw_FP_ACH_to_SCU_Wh, \ q_hw_FP_ACH_to_SCU_Wh,\ q_chw_FP_ACH_to_SCU_Wh = calc_ACH_operation(T_ground_K, T_hw_in_FP_C, T_re_SCU_K, T_sup_SCU_K, locator, mdot_SCU_kgpers, ACH_TYPE_SINGLE) ACH_HT_Status = np.where(q_chw_FP_ACH_to_SCU_Wh > 0.0, 1, 0) # boiler operation q_gas_for_boiler_Wh, \ Q_nom_boiler_VCC_to_AHU_ARU_and_FP_to_single_ACH_to_SCU_W,\ q_load_from_boiler_Wh = calc_boiler_operation(Qc_nom_SCU_W, T_hw_FP_ACH_to_SCU_K, q_hw_FP_ACH_to_SCU_Wh, q_sc_gen_FP_Wh) # CT operation q_CT_VCC_to_AHU_ARU_and_single_ACH_to_SCU_Wh = q_cw_VCC_to_AHU_ARU_Wh + q_cw_FP_ACH_to_SCU_Wh Q_nom_CT_VCC_to_AHU_ARU_and_FP_to_single_ACH_to_SCU_W, \ el_CT_Wh = calc_CT_operation(q_CT_VCC_to_AHU_ARU_and_single_ACH_to_SCU_Wh) # add electricity costs el_total_Wh = el_VCC_to_AHU_ARU_Wh + el_FP_ACH_to_SCU_Wh + el_aux_SC_FP_Wh + el_CT_Wh operation_results[5][7] += sum(lca.ELEC_PRICE * el_total_Wh) # CHF operation_results[5][8] += sum(el_total_Wh * WH_TO_J / 1E6 * lca.EL_TO_CO2 / 1E3) # ton CO2 operation_results[5][9] += sum(el_total_Wh * WH_TO_J / 1E6 * lca.EL_TO_OIL_EQ) # MJ-oil-eq # add gas costs q_gas_total_Wh = q_gas_for_boiler_Wh operation_results[5][7] += sum(prices.NG_PRICE * q_gas_total_Wh) # CHF operation_results[5][8] += sum( q_gas_total_Wh * WH_TO_J / 1E6 * lca.NG_BACKUPBOILER_TO_CO2_STD / 1E3) # ton CO2 operation_results[5][9] += sum(q_gas_total_Wh * WH_TO_J / 1E6 * lca.NG_BACKUPBOILER_TO_OIL_STD) # MJ-oil-eq # add activation cooling_dispatch[5] = {'Q_VCC_LT_gen_directload_W': q_chw_VCC_to_AHU_ARU_Wh, 'Q_ACH_HT_gen_directload_W': q_chw_FP_ACH_to_SCU_Wh, 'VCC_LT_Status': VCC_LT_Status, 'ACH_HT_Status': ACH_HT_Status, 'E_VCC_LT_req_W': el_VCC_to_AHU_ARU_Wh, 'E_ACH_HT_req_W': el_FP_ACH_to_SCU_Wh, 'E_SC_FP_req_W': el_aux_SC_FP_Wh, 'E_CT_req_W': el_CT_Wh, 'E_cs_cre_cdata_req_W': el_total_Wh, 'NG_Boiler_req': q_gas_for_boiler_Wh, } ## Calculate Capex/Opex # Initialize arrays number_of_configurations = len(operation_results) Capex_a_USD = np.zeros((number_of_configurations, 1)) Capex_total_USD = np.zeros((number_of_configurations, 1)) Opex_a_fixed_USD = np.zeros((number_of_configurations, 1)) print 'Cost calculation...' # 0: DX Capex_a_DX_USD, Opex_fixed_DX_USD, Capex_DX_USD = dx.calc_Cinv_DX(Qc_nom_AHU_ARU_SCU_W) # add costs Capex_a_USD[0][0] = Capex_a_DX_USD Capex_total_USD[0][0] = Capex_DX_USD Opex_a_fixed_USD[0][0] = Opex_fixed_DX_USD # 1: VCC + CT Capex_a_VCC_USD, Opex_fixed_VCC_USD, Capex_VCC_USD = chiller_vapor_compression.calc_Cinv_VCC( Qc_nom_AHU_ARU_SCU_W, locator, config, 'CH3') Capex_a_CT_USD, Opex_fixed_CT_USD, Capex_CT_USD = cooling_tower.calc_Cinv_CT( Q_nom_CT_VCC_to_AHU_ARU_SCU_W, locator, 'CT1') # add costs Capex_a_USD[1][0] = Capex_a_CT_USD + Capex_a_VCC_USD Capex_total_USD[1][0] = Capex_CT_USD + Capex_VCC_USD Opex_a_fixed_USD[1][0] = Opex_fixed_CT_USD + Opex_fixed_VCC_USD # 2: single effect ACH + CT + Boiler + SC_FP Capex_a_ACH_USD, Opex_fixed_ACH_USD, Capex_ACH_USD = chiller_absorption.calc_Cinv_ACH( Qc_nom_AHU_ARU_SCU_W, locator, ACH_TYPE_SINGLE) Capex_a_CT_USD, Opex_fixed_CT_USD, Capex_CT_USD = cooling_tower.calc_Cinv_CT( Q_nom_CT_FP_to_single_ACH_to_AHU_ARU_SCU_W, locator, 'CT1') Capex_a_boiler_USD, Opex_fixed_boiler_USD, Capex_boiler_USD = boiler.calc_Cinv_boiler( Q_nom_Boiler_FP_to_single_ACH_to_AHU_ARU_SCU_W, locator, config, 'BO1') Capex_a_USD[2][0] = Capex_a_CT_USD + Capex_a_ACH_USD + Capex_a_boiler_USD + Capex_a_SC_FP_USD Capex_total_USD[2][0] = Capex_CT_USD + Capex_ACH_USD + Capex_boiler_USD + Capex_SC_FP_USD Opex_a_fixed_USD[2][ 0] = Opex_fixed_CT_USD + Opex_fixed_ACH_USD + Opex_fixed_boiler_USD + Opex_SC_FP_USD # 3: double effect ACH + CT + Boiler + SC_ET Capex_a_ACH_USD, Opex_fixed_ACH_USD, Capex_ACH_USD = chiller_absorption.calc_Cinv_ACH( Qc_nom_AHU_ARU_SCU_W, locator, ACH_TYPE_SINGLE) Capex_a_CT_USD, Opex_fixed_CT_USD, Capex_CT_USD = cooling_tower.calc_Cinv_CT( Q_nom_CT_ET_to_single_ACH_to_AHU_ARU_SCU_W, locator, 'CT1') Capex_a_burner_USD, Opex_fixed_burner_USD, Capex_burner_USD = burner.calc_Cinv_burner( Q_nom_Burner_ET_to_single_ACH_to_AHU_ARU_SCU_W, locator, config, 'BO1') Capex_a_USD[3][0] = Capex_a_CT_USD + Capex_a_ACH_USD + Capex_a_burner_USD + Capex_a_SC_ET_USD Capex_total_USD[3][0] = Capex_CT_USD + Capex_ACH_USD + Capex_burner_USD + Capex_SC_ET_USD Opex_a_fixed_USD[3][ 0] = Opex_fixed_CT_USD + Opex_fixed_ACH_USD + Opex_fixed_burner_USD + Opex_SC_ET_USD # these two configurations are only activated when SCU is in use if Qc_nom_SCU_W > 0.0: # 4: VCC (AHU + ARU) + VCC (SCU) + CT Capex_a_VCC_AA_USD, Opex_VCC_AA_USD, Capex_VCC_AA_USD = chiller_vapor_compression.calc_Cinv_VCC( Qc_nom_AHU_ARU_W, locator, config, 'CH3') Capex_a_VCC_S_USD, Opex_VCC_S_USD, Capex_VCC_S_USD = chiller_vapor_compression.calc_Cinv_VCC( Qc_nom_SCU_W, locator, config, 'CH3') Capex_a_CT_USD, Opex_fixed_CT_USD, Capex_CT_USD = cooling_tower.calc_Cinv_CT( Q_nom_CT_VCC_to_AHU_ARU_and_VCC_to_SCU_W, locator, 'CT1') Capex_a_USD[4][0] = Capex_a_CT_USD + Capex_a_VCC_AA_USD + Capex_a_VCC_S_USD Capex_total_USD[4][0] = Capex_CT_USD + Capex_VCC_AA_USD + Capex_VCC_S_USD Opex_a_fixed_USD[4][0] = Opex_fixed_CT_USD + Opex_VCC_AA_USD + Opex_VCC_S_USD # 5: VCC (AHU + ARU) + ACH (SCU) + CT + Boiler + SC_FP Capex_a_ACH_S_USD, Opex_fixed_ACH_S_USD, Capex_ACH_S_USD = chiller_absorption.calc_Cinv_ACH( Qc_nom_SCU_W, locator, ACH_TYPE_SINGLE) Capex_a_CT_USD, Opex_fixed_CT_USD, Capex_CT_USD = cooling_tower.calc_Cinv_CT( Q_nom_CT_VCC_to_AHU_ARU_and_FP_to_single_ACH_to_SCU_W, locator, 'CT1') Capex_a_boiler_USD, Opex_fixed_boiler_USD, Capex_boiler_USD = boiler.calc_Cinv_boiler( Q_nom_boiler_VCC_to_AHU_ARU_and_FP_to_single_ACH_to_SCU_W, locator, config, 'BO1') Capex_a_USD[5][0] = Capex_a_CT_USD + Capex_a_VCC_AA_USD + Capex_a_ACH_S_USD + \ Capex_a_SC_FP_USD + Capex_a_boiler_USD Capex_total_USD[5][0] = Capex_CT_USD + Capex_VCC_AA_USD + Capex_ACH_S_USD + \ Capex_SC_FP_USD + Capex_boiler_USD Opex_a_fixed_USD[5][0] = Opex_fixed_CT_USD + Opex_VCC_AA_USD + Opex_fixed_ACH_S_USD + \ Opex_SC_FP_USD + Opex_fixed_boiler_USD ## write all results from the configurations into TotalCosts, TotalCO2, TotalPrim Opex_a_USD, TAC_USD, TotalCO2, TotalPrim = compile_TAC_CO2_Prim(Capex_a_USD, Opex_a_fixed_USD, number_of_configurations, operation_results) ## Determine the best configuration Best, indexBest = rank_results(TAC_USD, TotalCO2, TotalPrim, number_of_configurations) # Save results in csv file performance_results = { "DX to AHU_ARU_SCU Share": operation_results[:, 0], "VCC to AHU_ARU_SCU Share": operation_results[:, 1], "single effect ACH to AHU_ARU_SCU Share (FP)": operation_results[:, 2], "single effect ACH to AHU_ARU_SCU Share (ET)": operation_results[:, 3], "VCC to AHU_ARU Share": operation_results[:, 4], "VCC to SCU Share": operation_results[:, 5], "single effect ACH to SCU Share (FP)": operation_results[:, 6], "Capex_a_USD": Capex_a_USD[:, 0], "Capex_total_USD": Capex_total_USD[:, 0], "Opex_a_USD": Opex_a_USD[:, 1], "Opex_a_fixed_USD": Opex_a_fixed_USD[:, 0], "Opex_a_var_USD": operation_results[:, 7], "GHG_tonCO2": operation_results[:, 8], "PEN_MJoil": operation_results[:, 9], "TAC_USD": TAC_USD[:, 1], "Best configuration": Best[:, 0] } performance_results_df = pd.DataFrame(performance_results) performance_results_df.to_csv( locator.get_optimization_decentralized_folder_building_result_cooling(building_name)) # save activation for the best supply system configuration best_activation_df = pd.DataFrame.from_dict(cooling_dispatch[indexBest]) # best_activation_df.to_csv( locator.get_optimization_decentralized_folder_building_cooling_activation(building_name)) print time.clock() - t0, "seconds process time for the decentralized Building Routine \n"
def addCosts(DHN_barcode, DCN_barcode, buildList, locator, master_to_slave_vars, Q_uncovered_design_W, Q_uncovered_annual_W, solarFeat, ntwFeat, gv, config, prices, lca): """ Computes additional costs / GHG emisions / primary energy needs for the individual addCosts = additional costs addCO2 = GHG emissions addPrm = primary energy needs :param DHN_barcode: parameter indicating if the building is connected or not :param buildList: list of buildings in the district :param locator: input locator set to scenario :param master_to_slave_vars: class containing the features of a specific individual :param Q_uncovered_design_W: hourly max of the heating uncovered demand :param Q_uncovered_annual_W: total heating uncovered :param solarFeat: solar features :param ntwFeat: network features :param gv: global variables :type indCombi: string :type buildList: list :type locator: string :type master_to_slave_vars: class :type Q_uncovered_design_W: float :type Q_uncovered_annual_W: float :type solarFeat: class :type ntwFeat: class :type gv: class :return: returns the objectives addCosts, addCO2, addPrim :rtype: tuple """ addcosts_Capex_a = 0 addcosts_Opex_fixed = 0 addCO2 = 0 addPrim = 0 nBuildinNtw = 0 # Add the features from the disconnected buildings CostDiscBuild = 0 CO2DiscBuild = 0 PrimDiscBuild = 0 Capex_Disconnected = 0 Opex_Disconnected = 0 Capex_a_furnace = 0 Capex_a_CHP = 0 Capex_a_Boiler = 0 Capex_a_Boiler_peak = 0 Capex_a_Lake = 0 Capex_a_Sewage = 0 Capex_a_GHP = 0 Capex_a_PV = 0 Capex_a_SC = 0 Capex_a_PVT = 0 Capex_a_Boiler_backup = 0 Capex_a_HEX = 0 Capex_a_storage_HP = 0 Capex_a_HP_storage = 0 Opex_fixed_SC = 0 Opex_fixed_PVT = 0 Opex_fixed_HP_PVT = 0 Opex_fixed_furnace = 0 Opex_fixed_CHP = 0 Opex_fixed_Boiler = 0 Opex_fixed_Boiler_peak = 0 Opex_fixed_Boiler_backup = 0 Opex_fixed_Lake = 0 Opex_fixed_wasteserver_HEX = 0 Opex_fixed_wasteserver_HP = 0 Opex_fixed_PV = 0 Opex_fixed_GHP = 0 Opex_fixed_storage = 0 Opex_fixed_Sewage = 0 Opex_fixed_HP_storage = 0 StorageInvC = 0 NetworkCost = 0 SubstHEXCost_capex = 0 SubstHEXCost_opex = 0 PVTHEXCost_Capex = 0 PVTHEXCost_Opex = 0 SCHEXCost_Capex = 0 SCHEXCost_Opex = 0 pumpCosts = 0 GasConnectionInvCost = 0 cost_PV_disconnected = 0 CO2_PV_disconnected = 0 Eprim_PV_disconnected = 0 if config.optimization.isheating: for (index, building_name) in zip(DHN_barcode, buildList): if index == "0": df = pd.read_csv( locator. get_optimization_disconnected_folder_building_result_heating( building_name)) dfBest = df[df["Best configuration"] == 1] CostDiscBuild += dfBest["Total Costs [CHF]"].iloc[0] # [CHF] CO2DiscBuild += dfBest["CO2 Emissions [kgCO2-eq]"].iloc[ 0] # [kg CO2] PrimDiscBuild += dfBest[ "Primary Energy Needs [MJoil-eq]"].iloc[0] # [MJ-oil-eq] Capex_Disconnected += dfBest[ "Annualized Investment Costs [CHF]"].iloc[0] Opex_Disconnected += dfBest["Operation Costs [CHF]"].iloc[0] else: nBuildinNtw += 1 if config.optimization.iscooling: PV_barcode = '' for (index, building_name) in zip(DCN_barcode, buildList): if index == "0": # choose the best decentralized configuration df = pd.read_csv( locator. get_optimization_disconnected_folder_building_result_cooling( building_name, configuration='AHU_ARU_SCU')) dfBest = df[df["Best configuration"] == 1] CostDiscBuild += dfBest["Total Costs [CHF]"].iloc[0] # [CHF] CO2DiscBuild += dfBest["CO2 Emissions [kgCO2-eq]"].iloc[ 0] # [kg CO2] PrimDiscBuild += dfBest[ "Primary Energy Needs [MJoil-eq]"].iloc[0] # [MJ-oil-eq] Capex_Disconnected += dfBest[ "Annualized Investment Costs [CHF]"].iloc[0] Opex_Disconnected += dfBest["Operation Costs [CHF]"].iloc[0] to_PV = 1 if dfBest["single effect ACH to AHU_ARU_SCU Share (FP)"].iloc[ 0] == 1: to_PV = 0 if dfBest["single effect ACH to AHU_ARU_SCU Share (ET)"].iloc[ 0] == 1: to_PV = 0 if dfBest["single effect ACH to SCU Share (FP)"].iloc[0] == 1: to_PV = 0 else: # adding costs for buildings in which the centralized plant provides a part of the load requirements DCN_unit_configuration = master_to_slave_vars.DCN_supplyunits if DCN_unit_configuration == 1: # corresponds to AHU in the central plant, so remaining load need to be provided by decentralized plant decentralized_configuration = 'ARU_SCU' df = pd.read_csv( locator. get_optimization_disconnected_folder_building_result_cooling( building_name, decentralized_configuration)) dfBest = df[df["Best configuration"] == 1] CostDiscBuild += dfBest["Total Costs [CHF]"].iloc[ 0] # [CHF] CO2DiscBuild += dfBest["CO2 Emissions [kgCO2-eq]"].iloc[ 0] # [kg CO2] PrimDiscBuild += dfBest[ "Primary Energy Needs [MJoil-eq]"].iloc[ 0] # [MJ-oil-eq] Capex_Disconnected += dfBest[ "Annualized Investment Costs [CHF]"].iloc[0] Opex_Disconnected += dfBest["Operation Costs [CHF]"].iloc[ 0] to_PV = 1 if dfBest["single effect ACH to ARU_SCU Share (FP)"].iloc[ 0] == 1: to_PV = 0 if dfBest["single effect ACH to ARU_SCU Share (ET)"].iloc[ 0] == 1: to_PV = 0 if DCN_unit_configuration == 2: # corresponds to ARU in the central plant, so remaining load need to be provided by decentralized plant decentralized_configuration = 'AHU_SCU' df = pd.read_csv( locator. get_optimization_disconnected_folder_building_result_cooling( building_name, decentralized_configuration)) dfBest = df[df["Best configuration"] == 1] CostDiscBuild += dfBest["Total Costs [CHF]"].iloc[ 0] # [CHF] CO2DiscBuild += dfBest["CO2 Emissions [kgCO2-eq]"].iloc[ 0] # [kg CO2] PrimDiscBuild += dfBest[ "Primary Energy Needs [MJoil-eq]"].iloc[ 0] # [MJ-oil-eq] Capex_Disconnected += dfBest[ "Annualized Investment Costs [CHF]"].iloc[0] Opex_Disconnected += dfBest["Operation Costs [CHF]"].iloc[ 0] to_PV = 1 if dfBest["single effect ACH to AHU_SCU Share (FP)"].iloc[ 0] == 1: to_PV = 0 if dfBest["single effect ACH to AHU_SCU Share (ET)"].iloc[ 0] == 1: to_PV = 0 if DCN_unit_configuration == 3: # corresponds to SCU in the central plant, so remaining load need to be provided by decentralized plant decentralized_configuration = 'AHU_ARU' df = pd.read_csv( locator. get_optimization_disconnected_folder_building_result_cooling( building_name, decentralized_configuration)) dfBest = df[df["Best configuration"] == 1] CostDiscBuild += dfBest["Total Costs [CHF]"].iloc[ 0] # [CHF] CO2DiscBuild += dfBest["CO2 Emissions [kgCO2-eq]"].iloc[ 0] # [kg CO2] PrimDiscBuild += dfBest[ "Primary Energy Needs [MJoil-eq]"].iloc[ 0] # [MJ-oil-eq] Capex_Disconnected += dfBest[ "Annualized Investment Costs [CHF]"].iloc[0] Opex_Disconnected += dfBest["Operation Costs [CHF]"].iloc[ 0] to_PV = 1 if dfBest["single effect ACH to AHU_ARU Share (FP)"].iloc[ 0] == 1: to_PV = 0 if dfBest["single effect ACH to AHU_ARU Share (ET)"].iloc[ 0] == 1: to_PV = 0 if DCN_unit_configuration == 4: # corresponds to AHU + ARU in the central plant, so remaining load need to be provided by decentralized plant decentralized_configuration = 'SCU' df = pd.read_csv( locator. get_optimization_disconnected_folder_building_result_cooling( building_name, decentralized_configuration)) dfBest = df[df["Best configuration"] == 1] CostDiscBuild += dfBest["Total Costs [CHF]"].iloc[ 0] # [CHF] CO2DiscBuild += dfBest["CO2 Emissions [kgCO2-eq]"].iloc[ 0] # [kg CO2] PrimDiscBuild += dfBest[ "Primary Energy Needs [MJoil-eq]"].iloc[ 0] # [MJ-oil-eq] Capex_Disconnected += dfBest[ "Annualized Investment Costs [CHF]"].iloc[0] Opex_Disconnected += dfBest["Operation Costs [CHF]"].iloc[ 0] to_PV = 1 if dfBest["single effect ACH to SCU Share (FP)"].iloc[ 0] == 1: to_PV = 0 if dfBest["single effect ACH to SCU Share (ET)"].iloc[ 0] == 1: to_PV = 0 if DCN_unit_configuration == 5: # corresponds to AHU + SCU in the central plant, so remaining load need to be provided by decentralized plant decentralized_configuration = 'ARU' df = pd.read_csv( locator. get_optimization_disconnected_folder_building_result_cooling( building_name, decentralized_configuration)) dfBest = df[df["Best configuration"] == 1] CostDiscBuild += dfBest["Total Costs [CHF]"].iloc[ 0] # [CHF] CO2DiscBuild += dfBest["CO2 Emissions [kgCO2-eq]"].iloc[ 0] # [kg CO2] PrimDiscBuild += dfBest[ "Primary Energy Needs [MJoil-eq]"].iloc[ 0] # [MJ-oil-eq] Capex_Disconnected += dfBest[ "Annualized Investment Costs [CHF]"].iloc[0] Opex_Disconnected += dfBest["Operation Costs [CHF]"].iloc[ 0] to_PV = 1 if dfBest["single effect ACH to ARU Share (FP)"].iloc[ 0] == 1: to_PV = 0 if dfBest["single effect ACH to ARU Share (ET)"].iloc[ 0] == 1: to_PV = 0 if DCN_unit_configuration == 6: # corresponds to ARU + SCU in the central plant, so remaining load need to be provided by decentralized plant decentralized_configuration = 'AHU' df = pd.read_csv( locator. get_optimization_disconnected_folder_building_result_cooling( building_name, decentralized_configuration)) dfBest = df[df["Best configuration"] == 1] CostDiscBuild += dfBest["Total Costs [CHF]"].iloc[ 0] # [CHF] CO2DiscBuild += dfBest["CO2 Emissions [kgCO2-eq]"].iloc[ 0] # [kg CO2] PrimDiscBuild += dfBest[ "Primary Energy Needs [MJoil-eq]"].iloc[ 0] # [MJ-oil-eq] Capex_Disconnected += dfBest[ "Annualized Investment Costs [CHF]"].iloc[0] Opex_Disconnected += dfBest["Operation Costs [CHF]"].iloc[ 0] to_PV = 1 if dfBest["single effect ACH to AHU Share (FP)"].iloc[ 0] == 1: to_PV = 0 if dfBest["single effect ACH to AHU Share (ET)"].iloc[ 0] == 1: to_PV = 0 if DCN_unit_configuration == 7: # corresponds to AHU + ARU + SCU from central plant to_PV = 1 nBuildinNtw += 1 PV_barcode = PV_barcode + str(to_PV) addcosts_Capex_a += CostDiscBuild addCO2 += CO2DiscBuild addPrim += PrimDiscBuild if not config.optimization.isheating: if PV_barcode.count("1") > 0: df1 = pd.DataFrame({'A': []}) for (i, index) in enumerate(PV_barcode): if index == str(1): if df1.empty: data = pd.read_csv(locator.PV_results(buildList[i])) df1 = data else: data = pd.read_csv(locator.PV_results(buildList[i])) df1 = df1 + data if not df1.empty: df1.to_csv(locator.PV_network(PV_barcode), index=True, float_format='%.2f') solar_data = pd.read_csv(locator.PV_network(PV_barcode), usecols=['E_PV_gen_kWh', 'Area_PV_m2'], nrows=8760) E_PV_sum_kW = np.sum(solar_data['E_PV_gen_kWh']) E_PV_W = solar_data['E_PV_gen_kWh'] * 1000 Area_AvailablePV_m2 = np.max(solar_data['Area_PV_m2']) Q_PowerPeakAvailablePV_kW = Area_AvailablePV_m2 * ETA_AREA_TO_PEAK KEV_RpPerkWhPV = calc_Crem_pv(Q_PowerPeakAvailablePV_kW * 1000.0) KEV_total = KEV_RpPerkWhPV / 100 * np.sum(E_PV_sum_kW) addcosts_Capex_a = addcosts_Capex_a - KEV_total addCO2 = addCO2 - (E_PV_sum_kW * 1000 * (lca.EL_PV_TO_CO2 - lca.EL_TO_CO2_GREEN) * WH_TO_J / 1.0E6) addPrim = addPrim - (E_PV_sum_kW * 1000 * (lca.EL_PV_TO_OIL_EQ - lca.EL_TO_OIL_EQ_GREEN) * WH_TO_J / 1.0E6) cost_PV_disconnected = KEV_total CO2_PV_disconnected = (E_PV_sum_kW * 1000 * (lca.EL_PV_TO_CO2 - lca.EL_TO_CO2_GREEN) * WH_TO_J / 1.0E6) Eprim_PV_disconnected = ( E_PV_sum_kW * 1000 * (lca.EL_PV_TO_OIL_EQ - lca.EL_TO_OIL_EQ_GREEN) * WH_TO_J / 1.0E6) network_data = pd.read_csv( locator.get_optimization_network_data_folder( master_to_slave_vars.network_data_file_cooling)) E_total_req_W = np.array(network_data['Electr_netw_total_W']) cooling_data = pd.read_csv( locator.get_optimization_slave_cooling_activation_pattern( master_to_slave_vars.individual_number, master_to_slave_vars.generation_number)) E_from_CHP_W = np.array(cooling_data[ 'E_gen_CCGT_associated_with_absorption_chillers_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) for hour in range(8760): E_hour_W = E_total_req_W[hour] if E_hour_W > 0: if E_PV_W[hour] > E_hour_W: E_PV_to_directload_W[hour] = E_hour_W E_PV_to_grid_W[ hour] = E_PV_W[hour] - E_total_req_W[hour] E_hour_W = 0 else: E_hour_W = E_hour_W - E_PV_W[hour] E_PV_to_directload_W[hour] = E_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 = network_data.DATE.values results = pd.DataFrame({ "DATE": date, "E_total_req_W": E_total_req_W, "E_PV_W": solar_data['E_PV_gen_kWh'] * 1000, "Area_PV_m2": solar_data['Area_PV_m2'], "KEV": KEV_RpPerkWhPV / 100 * solar_data['E_PV_gen_kWh'], "E_from_grid_W": E_from_grid_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 }) results.to_csv( locator. get_optimization_slave_electricity_activation_pattern_cooling( master_to_slave_vars.individual_number, master_to_slave_vars.generation_number), index=False) # Add the features for the distribution if DHN_barcode.count("1") > 0 and config.optimization.isheating: os.chdir( locator.get_optimization_slave_results_folder( master_to_slave_vars.generation_number)) # Add the investment costs of the energy systems # Furnace if master_to_slave_vars.Furnace_on == 1: P_design_W = master_to_slave_vars.Furnace_Q_max fNameSlavePP = locator.get_optimization_slave_heating_activation_pattern_heating( master_to_slave_vars.configKey, master_to_slave_vars.individual_number, master_to_slave_vars.generation_number) dfFurnace = pd.read_csv(fNameSlavePP, usecols=["Q_Furnace_W"]) arrayFurnace_W = np.array(dfFurnace) Q_annual_W = 0 for i in range(int(np.shape(arrayFurnace_W)[0])): Q_annual_W += arrayFurnace_W[i][0] Capex_a_furnace, Opex_fixed_furnace = furnace.calc_Cinv_furnace( P_design_W, Q_annual_W, config, locator, 'FU1') addcosts_Capex_a += Capex_a_furnace addcosts_Opex_fixed += Opex_fixed_furnace # CC if master_to_slave_vars.CC_on == 1: CC_size_W = master_to_slave_vars.CC_GT_SIZE Capex_a_CHP, Opex_fixed_CHP = chp.calc_Cinv_CCGT( CC_size_W, locator, config) addcosts_Capex_a += Capex_a_CHP addcosts_Opex_fixed += Opex_fixed_CHP # Boiler Base if master_to_slave_vars.Boiler_on == 1: Q_design_W = master_to_slave_vars.Boiler_Q_max fNameSlavePP = locator.get_optimization_slave_heating_activation_pattern( master_to_slave_vars.individual_number, master_to_slave_vars.generation_number) dfBoilerBase = pd.read_csv(fNameSlavePP, usecols=["Q_BaseBoiler_W"]) arrayBoilerBase_W = np.array(dfBoilerBase) Q_annual_W = 0 for i in range(int(np.shape(arrayBoilerBase_W)[0])): Q_annual_W += arrayBoilerBase_W[i][0] Capex_a_Boiler, Opex_fixed_Boiler = boiler.calc_Cinv_boiler( Q_design_W, locator, config, 'BO1') addcosts_Capex_a += Capex_a_Boiler addcosts_Opex_fixed += Opex_fixed_Boiler # Boiler Peak if master_to_slave_vars.BoilerPeak_on == 1: Q_design_W = master_to_slave_vars.BoilerPeak_Q_max fNameSlavePP = locator.get_optimization_slave_heating_activation_pattern( master_to_slave_vars.individual_number, master_to_slave_vars.generation_number) dfBoilerPeak = pd.read_csv(fNameSlavePP, usecols=["Q_PeakBoiler_W"]) arrayBoilerPeak_W = np.array(dfBoilerPeak) Q_annual_W = 0 for i in range(int(np.shape(arrayBoilerPeak_W)[0])): Q_annual_W += arrayBoilerPeak_W[i][0] Capex_a_Boiler_peak, Opex_fixed_Boiler_peak = boiler.calc_Cinv_boiler( Q_design_W, locator, config, 'BO1') addcosts_Capex_a += Capex_a_Boiler_peak addcosts_Opex_fixed += Opex_fixed_Boiler_peak # HP Lake if master_to_slave_vars.HP_Lake_on == 1: HP_Size_W = master_to_slave_vars.HPLake_maxSize Capex_a_Lake, Opex_fixed_Lake = hp.calc_Cinv_HP( HP_Size_W, locator, config, 'HP2') addcosts_Capex_a += Capex_a_Lake addcosts_Opex_fixed += Opex_fixed_Lake # HP Sewage if master_to_slave_vars.HP_Sew_on == 1: HP_Size_W = master_to_slave_vars.HPSew_maxSize Capex_a_Sewage, Opex_fixed_Sewage = hp.calc_Cinv_HP( HP_Size_W, locator, config, 'HP2') addcosts_Capex_a += Capex_a_Sewage addcosts_Opex_fixed += Opex_fixed_Sewage # GHP if master_to_slave_vars.GHP_on == 1: fNameSlavePP = locator.get_optimization_slave_electricity_activation_pattern_heating( master_to_slave_vars.individual_number, master_to_slave_vars.generation_number) dfGHP = pd.read_csv(fNameSlavePP, usecols=["E_GHP_req_W"]) arrayGHP_W = np.array(dfGHP) GHP_Enom_W = np.amax(arrayGHP_W) Capex_a_GHP, Opex_fixed_GHP = hp.calc_Cinv_GHP( GHP_Enom_W, locator, config) addcosts_Capex_a += Capex_a_GHP * prices.EURO_TO_CHF addcosts_Opex_fixed += Opex_fixed_GHP * prices.EURO_TO_CHF # Solar technologies PV_installed_area_m2 = master_to_slave_vars.SOLAR_PART_PV * solarFeat.A_PV_m2 #kW Capex_a_PV, Opex_fixed_PV = pv.calc_Cinv_pv(PV_installed_area_m2, locator, config) addcosts_Capex_a += Capex_a_PV addcosts_Opex_fixed += Opex_fixed_PV SC_ET_area_m2 = master_to_slave_vars.SOLAR_PART_SC_ET * solarFeat.A_SC_ET_m2 Capex_a_SC_ET, Opex_fixed_SC_ET = stc.calc_Cinv_SC( SC_ET_area_m2, locator, config, 'ET') addcosts_Capex_a += Capex_a_SC_ET addcosts_Opex_fixed += Opex_fixed_SC_ET SC_FP_area_m2 = master_to_slave_vars.SOLAR_PART_SC_FP * solarFeat.A_SC_FP_m2 Capex_a_SC_FP, Opex_fixed_SC_FP = stc.calc_Cinv_SC( SC_FP_area_m2, locator, config, 'FP') addcosts_Capex_a += Capex_a_SC_FP addcosts_Opex_fixed += Opex_fixed_SC_FP PVT_peak_kW = master_to_slave_vars.SOLAR_PART_PVT * solarFeat.A_PVT_m2 * N_PVT #kW Capex_a_PVT, Opex_fixed_PVT = pvt.calc_Cinv_PVT( PVT_peak_kW, locator, config) addcosts_Capex_a += Capex_a_PVT addcosts_Opex_fixed += Opex_fixed_PVT # Back-up boiler Capex_a_Boiler_backup, Opex_fixed_Boiler_backup = boiler.calc_Cinv_boiler( Q_uncovered_design_W, locator, config, 'BO1') addcosts_Capex_a += Capex_a_Boiler_backup addcosts_Opex_fixed += Opex_fixed_Boiler_backup # Hex and HP for Heat recovery if master_to_slave_vars.WasteServersHeatRecovery == 1: df = pd.read_csv(os.path.join( locator.get_optimization_network_results_folder(), master_to_slave_vars.network_data_file_heating), usecols=["Qcdata_netw_total_kWh"]) array = np.array(df) Q_HEX_max_kWh = np.amax(array) Capex_a_wasteserver_HEX, Opex_fixed_wasteserver_HEX = hex.calc_Cinv_HEX( Q_HEX_max_kWh, locator, config, 'HEX1') addcosts_Capex_a += (Capex_a_wasteserver_HEX) addcosts_Opex_fixed += Opex_fixed_wasteserver_HEX df = pd.read_csv( locator.get_optimization_slave_storage_operation_data( master_to_slave_vars.individual_number, master_to_slave_vars.generation_number), usecols=["HPServerHeatDesignArray_kWh"]) array = np.array(df) Q_HP_max_kWh = np.amax(array) Capex_a_wasteserver_HP, Opex_fixed_wasteserver_HP = hp.calc_Cinv_HP( Q_HP_max_kWh, locator, config, 'HP2') addcosts_Capex_a += (Capex_a_wasteserver_HP) addcosts_Opex_fixed += Opex_fixed_wasteserver_HP # if master_to_slave_vars.WasteCompressorHeatRecovery == 1: # df = pd.read_csv( # os.path.join(locator.get_optimization_network_results_folder(), master_to_slave_vars.network_data_file_heating), # usecols=["Ecaf_netw_total_kWh"]) # array = np.array(df) # Q_HEX_max_kWh = np.amax(array) # # Capex_a_wastecompressor_HEX, Opex_fixed_wastecompressor_HEX = hex.calc_Cinv_HEX(Q_HEX_max_kWh, locator, # config, 'HEX1') # addcosts_Capex_a += (Capex_a_wastecompressor_HEX) # addcosts_Opex_fixed += Opex_fixed_wastecompressor_HEX # df = pd.read_csv( # locator.get_optimization_slave_storage_operation_data(master_to_slave_vars.individual_number, # master_to_slave_vars.generation_number), # usecols=["HPCompAirDesignArray_kWh"]) # array = np.array(df) # Q_HP_max_kWh = np.amax(array) # Capex_a_wastecompressor_HP, Opex_fixed_wastecompressor_HP = hp.calc_Cinv_HP(Q_HP_max_kWh, locator, config, 'HP2') # addcosts_Capex_a += (Capex_a_wastecompressor_HP) # addcosts_Opex_fixed += Opex_fixed_wastecompressor_HP # Heat pump from solar to DH df = pd.read_csv( locator.get_optimization_slave_storage_operation_data( master_to_slave_vars.individual_number, master_to_slave_vars.generation_number), usecols=["HPScDesignArray_Wh", "HPpvt_designArray_Wh"]) array = np.array(df) Q_HP_max_PVT_wh = np.amax(array[:, 1]) Q_HP_max_SC_Wh = np.amax(array[:, 0]) Capex_a_HP_PVT, Opex_fixed_HP_PVT = hp.calc_Cinv_HP( Q_HP_max_PVT_wh, locator, config, 'HP2') Capex_a_storage_HP += (Capex_a_HP_PVT) addcosts_Opex_fixed += Opex_fixed_HP_PVT Capex_a_HP_SC, Opex_fixed_HP_SC = hp.calc_Cinv_HP( Q_HP_max_SC_Wh, locator, config, 'HP2') Capex_a_storage_HP += (Capex_a_HP_SC) addcosts_Opex_fixed += Opex_fixed_HP_SC # HP for storage operation for charging from solar and discharging to DH df = pd.read_csv(locator.get_optimization_slave_storage_operation_data( master_to_slave_vars.individual_number, master_to_slave_vars.generation_number), usecols=[ "E_aux_ch_W", "E_aux_dech_W", "Q_from_storage_used_W", "Q_to_storage_W" ]) array = np.array(df) Q_HP_max_storage_W = 0 for i in range(DAYS_IN_YEAR * HOURS_IN_DAY): if array[i][0] > 0: Q_HP_max_storage_W = max(Q_HP_max_storage_W, array[i][3] + array[i][0]) elif array[i][1] > 0: Q_HP_max_storage_W = max(Q_HP_max_storage_W, array[i][2] + array[i][1]) Capex_a_HP_storage, Opex_fixed_HP_storage = hp.calc_Cinv_HP( Q_HP_max_storage_W, locator, config, 'HP2') addcosts_Capex_a += (Capex_a_HP_storage) addcosts_Opex_fixed += Opex_fixed_HP_storage # Storage df = pd.read_csv(locator.get_optimization_slave_storage_operation_data( master_to_slave_vars.individual_number, master_to_slave_vars.generation_number), usecols=["Storage_Size_m3"], nrows=1) StorageVol_m3 = np.array(df)[0][0] Capex_a_storage, Opex_fixed_storage = storage.calc_Cinv_storage( StorageVol_m3, locator, config, 'TES2') addcosts_Capex_a += Capex_a_storage addcosts_Opex_fixed += Opex_fixed_storage # Costs from distribution configuration if gv.ZernezFlag == 1: NetworkCost += network.calc_Cinv_network_linear( gv.NetworkLengthZernez, gv) * nBuildinNtw / len(buildList) else: NetworkCost += ntwFeat.pipesCosts_DHN * nBuildinNtw / len( buildList) addcosts_Capex_a += NetworkCost # HEX (1 per building in ntw) for (index, building_name) in zip(DHN_barcode, buildList): if index == "1": df = pd.read_csv( locator.get_optimization_substations_results_file( building_name), usecols=["Q_dhw_W", "Q_heating_W"]) subsArray = np.array(df) Q_max_W = np.amax(subsArray[:, 0] + subsArray[:, 1]) Capex_a_HEX_building, Opex_fixed_HEX_building = hex.calc_Cinv_HEX( Q_max_W, locator, config, 'HEX1') addcosts_Capex_a += Capex_a_HEX_building addcosts_Opex_fixed += Opex_fixed_HEX_building # HEX for solar roof_area_m2 = np.array( pd.read_csv(locator.get_total_demand(), usecols=["Aroof_m2"])) areaAvail = 0 for i in range(len(DHN_barcode)): index = DHN_barcode[i] if index == "1": areaAvail += roof_area_m2[i][0] for i in range(len(DHN_barcode)): index = DHN_barcode[i] if index == "1": share = roof_area_m2[i][0] / areaAvail #print share, "solar area share", buildList[i] Q_max_SC_ET_Wh = solarFeat.Q_nom_SC_ET_Wh * master_to_slave_vars.SOLAR_PART_SC_ET * share Capex_a_HEX_SC_ET, Opex_fixed_HEX_SC_ET = hex.calc_Cinv_HEX( Q_max_SC_ET_Wh, locator, config, 'HEX1') addcosts_Capex_a += Capex_a_HEX_SC_ET addcosts_Opex_fixed += Opex_fixed_HEX_SC_ET Q_max_SC_FP_Wh = solarFeat.Q_nom_SC_FP_Wh * master_to_slave_vars.SOLAR_PART_SC_FP * share Capex_a_HEX_SC_FP, Opex_fixed_HEX_SC_FP = hex.calc_Cinv_HEX( Q_max_SC_FP_Wh, locator, config, 'HEX1') addcosts_Capex_a += Capex_a_HEX_SC_FP addcosts_Opex_fixed += Opex_fixed_HEX_SC_FP Q_max_PVT_Wh = solarFeat.Q_nom_PVT_Wh * master_to_slave_vars.SOLAR_PART_PVT * share Capex_a_HEX_PVT, Opex_fixed_HEX_PVT = hex.calc_Cinv_HEX( Q_max_PVT_Wh, locator, config, 'HEX1') addcosts_Capex_a += Capex_a_HEX_PVT addcosts_Opex_fixed += Opex_fixed_HEX_PVT # Pump operation costs Capex_a_pump, Opex_fixed_pump, Opex_var_pump = pumps.calc_Ctot_pump( master_to_slave_vars, ntwFeat, gv, locator, lca, config) addcosts_Capex_a += Capex_a_pump addcosts_Opex_fixed += Opex_fixed_pump # import gas consumption data from: if DHN_barcode.count("1") > 0 and config.optimization.isheating: # import gas consumption data from: EgasPrimaryDataframe_W = pd.read_csv( locator.get_optimization_slave_cost_prime_primary_energy_data( master_to_slave_vars.individual_number, master_to_slave_vars.generation_number), usecols=["E_gas_PrimaryPeakPower_W"]) E_gas_primary_peak_power_W = float(np.array(EgasPrimaryDataframe_W)) GasConnectionInvCost = ngas.calc_Cinv_gas(E_gas_primary_peak_power_W, gv) else: GasConnectionInvCost = 0.0 addcosts_Capex_a += GasConnectionInvCost # Save data results = pd.DataFrame({ "Capex_a_SC": [Capex_a_SC], "Opex_fixed_SC": [Opex_fixed_SC], "Capex_a_PVT": [Capex_a_PVT], "Opex_fixed_PVT": [Opex_fixed_PVT], "Capex_a_Boiler_backup": [Capex_a_Boiler_backup], "Opex_fixed_Boiler_backup": [Opex_fixed_Boiler_backup], "Capex_a_storage_HEX": [Capex_a_HP_storage], "Opex_fixed_storage_HEX": [Opex_fixed_HP_storage], "Capex_a_storage_HP": [Capex_a_storage_HP], "Capex_a_CHP": [Capex_a_CHP], "Opex_fixed_CHP": [Opex_fixed_CHP], "StorageInvC": [StorageInvC], "StorageCostSum": [StorageInvC + Capex_a_storage_HP + Capex_a_HEX], "NetworkCost": [NetworkCost], "SubstHEXCost": [SubstHEXCost_capex], "DHNInvestCost": [addcosts_Capex_a - CostDiscBuild], "PVTHEXCost_Capex": [PVTHEXCost_Capex], "CostDiscBuild": [CostDiscBuild], "CO2DiscBuild": [CO2DiscBuild], "PrimDiscBuild": [PrimDiscBuild], "Capex_a_furnace": [Capex_a_furnace], "Opex_fixed_furnace": [Opex_fixed_furnace], "Capex_a_Boiler": [Capex_a_Boiler], "Opex_fixed_Boiler": [Opex_fixed_Boiler], "Capex_a_Boiler_peak": [Capex_a_Boiler_peak], "Opex_fixed_Boiler_peak": [Opex_fixed_Boiler_peak], "Capex_Disconnected": [Capex_Disconnected], "Opex_Disconnected": [Opex_Disconnected], "Capex_a_Lake": [Capex_a_Lake], "Opex_fixed_Lake": [Opex_fixed_Lake], "Capex_a_Sewage": [Capex_a_Sewage], "Opex_fixed_Sewage": [Opex_fixed_Sewage], "SCHEXCost_Capex": [SCHEXCost_Capex], "Capex_a_pump": [Capex_a_pump], "Opex_fixed_pump": [Opex_fixed_pump], "Opex_var_pump": [Opex_var_pump], "Sum_CAPEX": [addcosts_Capex_a], "Sum_OPEX_fixed": [addcosts_Opex_fixed], "GasConnectionInvCa": [GasConnectionInvCost], "CO2_PV_disconnected": [CO2_PV_disconnected], "cost_PV_disconnected": [cost_PV_disconnected], "Eprim_PV_disconnected": [Eprim_PV_disconnected] }) results.to_csv(locator.get_optimization_slave_investment_cost_detailed( master_to_slave_vars.individual_number, master_to_slave_vars.generation_number), sep=',') return (addcosts_Capex_a + addcosts_Opex_fixed, addCO2, addPrim)