def calc_electricity_performance_emissions(lca, E_PV_gen_export_W, E_GRID_directload_W): # SOlar technologies GHG_PV_gen_export_tonCO2 = calc_emissions_Whyr_to_tonCO2yr(sum(E_PV_gen_export_W), lca.EL_TO_CO2) GHG_PV_gen_directload_tonCO2 = 0.0 # because the price of fuel is already included PEN_PV_gen_export_MJoil = calc_pen_Whyr_to_MJoilyr(sum(E_PV_gen_export_W), lca.EL_TO_OIL_EQ) PEN_PV_gen_directload_MJoil = 0.0 # because the price of fuel is already included GHG_PV_connected_tonCO2 = GHG_PV_gen_directload_tonCO2 - GHG_PV_gen_export_tonCO2 PEN_PV_connected_MJoil = PEN_PV_gen_directload_MJoil - PEN_PV_gen_export_MJoil # GRid GHG_GRID_directload_tonCO2 = calc_emissions_Whyr_to_tonCO2yr(sum(E_GRID_directload_W), lca.EL_TO_CO2) PEN_GRID_directload_MJoil = calc_pen_Whyr_to_MJoilyr(sum(E_GRID_directload_W), lca.EL_TO_OIL_EQ) # calculate emissions of generation units BUT solar (the last will be calculated in the next STEP) # PEN_HPSolarandHeatRecovery_MJoil = E_aux_solar_and_heat_recovery_W * lca.EL_TO_OIL_EQ * WH_TO_J / 1.0E6 # GHG_HPSolarandHeatRecovery_tonCO2 = E_aux_solar_and_heat_recovery_W * lca.EL_TO_CO2 * WH_TO_J / 1E6 performance_electricity = { # emissions "GHG_PV_connected_tonCO2": GHG_PV_connected_tonCO2, "GHG_GRID_connected_tonCO2": GHG_GRID_directload_tonCO2, # primary energy "PEN_PV_connected_MJoil": PEN_PV_connected_MJoil, "PEN_GRID_connected_MJoil": PEN_GRID_directload_MJoil } return performance_electricity
def calc_emissions_connected_buildings(sum_natural_gas_imports_W, sum_wet_biomass_imports_W, sum_dry_biomass_imports_W, sum_electricity_imports_W, sum_electricity_exports_W, lca): # SUMMARIZE sum_natural_gas_imports_Whyr = sum(sum_natural_gas_imports_W) sum_wet_biomass_imports_Whyr = sum(sum_wet_biomass_imports_W) sum_dry_biomass_imports_Whyr = sum(sum_dry_biomass_imports_W) sum_electricity_imports_Whyr = sum(sum_electricity_imports_W) sum_electricity_exports_Whyr = sum(sum_electricity_exports_W) GHG_NG_connected_tonCO2yr = calc_emissions_Whyr_to_tonCO2yr( sum_natural_gas_imports_Whyr, lca.NG_BOILER_TO_CO2_STD) GHG_WB_connected_tonCO2yr = calc_emissions_Whyr_to_tonCO2yr( sum_wet_biomass_imports_Whyr, lca.FURNACE_TO_CO2_STD) GHG_DB_connected_tonCO2yr = calc_emissions_Whyr_to_tonCO2yr( sum_dry_biomass_imports_Whyr, lca.FURNACE_TO_CO2_STD) GHG_GRID_imports_connected_tonCO2yr = calc_emissions_Whyr_to_tonCO2yr( sum_electricity_imports_Whyr, lca.EL_TO_CO2) GHG_GRID_exports_connected_tonCO2yr = -calc_emissions_Whyr_to_tonCO2yr( sum_electricity_exports_Whyr, lca.EL_TO_CO2) PEN_NG_connected_MJoilyr = calc_pen_Whyr_to_MJoilyr( sum_natural_gas_imports_Whyr, lca.NG_BOILER_TO_OIL_STD) PEN_WB_connected_MJoilyr = calc_pen_Whyr_to_MJoilyr( sum_wet_biomass_imports_Whyr, lca.FURNACE_TO_OIL_STD) PEN_DB_connected_MJoilyr = calc_pen_Whyr_to_MJoilyr( sum_dry_biomass_imports_Whyr, lca.FURNACE_TO_OIL_STD) PEN_GRID_imports_connected_MJoilyr = calc_pen_Whyr_to_MJoilyr( sum_electricity_imports_Whyr, lca.EL_TO_OIL_EQ) PEN_GRID_exports_connected_MJoilyr = -calc_pen_Whyr_to_MJoilyr( sum_electricity_exports_Whyr, lca.EL_TO_OIL_EQ) buildings_connected_emissions_primary_energy = { "GHG_NG_connected_tonCO2yr": GHG_NG_connected_tonCO2yr, "GHG_WB_connected_tonCO2yr": GHG_WB_connected_tonCO2yr, "GHG_DB_connected_tonCO2yr": GHG_DB_connected_tonCO2yr, "GHG_GRID_imports_connected_tonCO2yr": GHG_GRID_imports_connected_tonCO2yr, "GHG_GRID_exports_connected_tonCO2yr": GHG_GRID_exports_connected_tonCO2yr, "PEN_NG_connected_MJoilyr": PEN_NG_connected_MJoilyr, "PEN_WB_connected_MJoilyr": PEN_WB_connected_MJoilyr, "PEN_DB_connected_MJoilyr": PEN_DB_connected_MJoilyr, "PEN_GRID_imports_connected_MJoilyr": PEN_GRID_imports_connected_MJoilyr, "PEN_GRID_exports_connected_MJoilyr": PEN_GRID_exports_connected_MJoilyr } return buildings_connected_emissions_primary_energy
def update_per_emissions_cooling(E_CCGT_gen_export_W, lca, performance_cooling): GHG_CCGT_gen_export_tonCO2 = calc_emissions_Whyr_to_tonCO2yr( sum(E_CCGT_gen_export_W), lca.EL_TO_CO2) GHG_CCGT_gen_directload_tonCO2 = 0.0 # because the price of fuel is already included PEN_CCGT_gen_export_MJoil = calc_pen_Whyr_to_MJoilyr( sum(E_CCGT_gen_export_W), lca.EL_TO_OIL_EQ) PEN_CCGT_gen_directload_MJoil = 0.0 # because the price of fuel is already included # UPDATE PARAMETERS (NET ERERGY COSTS) # CCGT for cooling performance_cooling['GHG_CCGT_connected_tonCO2'] = performance_cooling['GHG_CCGT_connected_tonCO2'] + \ GHG_CCGT_gen_directload_tonCO2 - \ GHG_CCGT_gen_export_tonCO2 performance_cooling['PEN_CCGT_connected_MJoil'] = performance_cooling['PEN_CCGT_connected_MJoil'] + \ PEN_CCGT_gen_directload_MJoil - \ PEN_CCGT_gen_export_MJoil return performance_cooling
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 update_performance_emissions_heating(E_CHP_gen_export_W, E_Furnace_dry_gen_export_W, E_Furnace_wet_gen_export_W, E_PVT_gen_export_W, lca, performance_heating): GHG_PVT_gen_export_tonCO2 = calc_emissions_Whyr_to_tonCO2yr( sum(E_PVT_gen_export_W), lca.EL_TO_CO2) GHG_PVT_gen_directload_tonCO2 = 0.0 # because the price of fuel is already included GHG_CHP_gen_export_tonCO2 = calc_emissions_Whyr_to_tonCO2yr( sum(E_CHP_gen_export_W), lca.EL_TO_CO2) GHG_CHP_gen_directload_tonCO2 = 0.0 # because the price of fuel is already included GHG_Furnace_dry_gen_export_tonCO2 = calc_emissions_Whyr_to_tonCO2yr( sum(E_Furnace_dry_gen_export_W), lca.EL_TO_CO2) GHG_Furnace_dry_gen_directload_tonCO2 = 0.0 # because the price of fuel is already included GHG_Furnace_wet_gen_export_tonCO2 = calc_emissions_Whyr_to_tonCO2yr( sum(E_Furnace_wet_gen_export_W), lca.EL_TO_CO2) GHG_Furnace_wet_gen_directload_tonCO2 = 0.0 # because the price of fuel is already included PEN_PVT_gen_export_MJoil = calc_pen_Whyr_to_MJoilyr( sum(E_PVT_gen_export_W), lca.EL_TO_OIL_EQ) PEN_PVT_gen_directload_MJoil = 0.0 # because the price of fuel is already included PEN_CHP_gen_export_MJoil = calc_pen_Whyr_to_MJoilyr( sum(E_CHP_gen_export_W), lca.EL_TO_OIL_EQ) PEN_CHP_gen_directload_MJoil = 0.0 # because the price of fuel is already included PEN_Furnace_dry_gen_export_MJoil = calc_pen_Whyr_to_MJoilyr( sum(E_Furnace_dry_gen_export_W), lca.EL_TO_OIL_EQ) PEN_Furnace_dry_gen_directload_MJoil = 0.0 # because the price of fuel is already included PEN_Furnace_wet_gen_export_MJoil = calc_pen_Whyr_to_MJoilyr( sum(E_Furnace_wet_gen_export_W), lca.EL_TO_OIL_EQ) PEN_Furnace_wet_gen_directload_MJoil = 0.0 # because the price of fuel is already included # CHP for heating performance_heating['GHG_CHP_NG_connected_tonCO2'] = performance_heating['GHG_CHP_NG_connected_tonCO2'] + \ GHG_CHP_gen_directload_tonCO2 - \ GHG_CHP_gen_export_tonCO2 performance_heating['PEN_CHP_NG_connected_MJoil'] = performance_heating['PEN_CHP_NG_connected_MJoil'] + \ PEN_CHP_gen_directload_MJoil - \ PEN_CHP_gen_export_MJoil performance_heating['GHG_Furnace_dry_connected_tonCO2'] = performance_heating[ 'GHG_Furnace_dry_connected_tonCO2'] + \ GHG_Furnace_dry_gen_directload_tonCO2 - \ GHG_Furnace_dry_gen_export_tonCO2 performance_heating['PEN_Furnace_dry_connected_MJoil'] = performance_heating[ 'PEN_Furnace_dry_connected_MJoil'] + \ PEN_Furnace_dry_gen_directload_MJoil - \ PEN_Furnace_dry_gen_export_MJoil performance_heating['GHG_Furnace_wet_connected_tonCO2'] = performance_heating[ 'GHG_Furnace_wet_connected_tonCO2'] + \ GHG_Furnace_wet_gen_directload_tonCO2 - \ GHG_Furnace_wet_gen_export_tonCO2 performance_heating['PEN_Furnace_wet_connected_MJoil'] = performance_heating[ 'PEN_Furnace_wet_connected_MJoil'] + \ PEN_Furnace_wet_gen_directload_MJoil - \ PEN_Furnace_wet_gen_export_MJoil # PV and PVT performance_heating['GHG_PVT_connected_tonCO2'] = performance_heating['GHG_PVT_connected_tonCO2'] + \ GHG_PVT_gen_directload_tonCO2 - \ GHG_PVT_gen_export_tonCO2 performance_heating['PEN_PVT_connected_MJoil'] = performance_heating['PEN_PVT_connected_MJoil'] + \ PEN_PVT_gen_directload_MJoil - \ PEN_PVT_gen_export_MJoil return performance_heating
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)