def preprocessing_cost_data(locator, data_raw, individual, generations, data_address, config): string_network = data_raw['network'].loc[individual].values[0] total_demand = pd.read_csv(locator.get_total_demand()) building_names = total_demand.Name.values individual_barcode_list = data_raw['individual_barcode'].loc[ individual].values[0] # The current structure of CEA has the following columns saved, in future, this will be slightly changed and # correspondingly these columns_of_saved_files needs to be changed columns_of_saved_files = [ 'CHP/Furnace', 'CHP/Furnace Share', 'Base Boiler', 'Base Boiler Share', 'Peak Boiler', 'Peak Boiler Share', 'Heating Lake', 'Heating Lake Share', 'Heating Sewage', 'Heating Sewage Share', 'GHP', 'GHP Share', 'Data Centre', 'Compressed Air', 'PV', 'PV Area Share', 'PVT', 'PVT Area Share', 'SC_ET', 'SC_ET Area Share', 'SC_FP', 'SC_FP Area Share', 'DHN Temperature', 'DHN unit configuration', 'Lake Cooling', 'Lake Cooling Share', 'VCC Cooling', 'VCC Cooling Share', 'Absorption Chiller', 'Absorption Chiller Share', 'Storage', 'Storage Share', 'DCN Temperature', 'DCN unit configuration' ] for i in building_names: # DHN columns_of_saved_files.append(str(i) + ' DHN') for i in building_names: # DCN columns_of_saved_files.append(str(i) + ' DCN') df_current_individual = pd.DataFrame( np.zeros(shape=(1, len(columns_of_saved_files))), columns=columns_of_saved_files) for i, ind in enumerate((columns_of_saved_files)): df_current_individual[ind] = individual_barcode_list[i] data_address = data_address[data_address['individual_list'] == individual] generation_number = data_address['generation_number_address'].values[0] individual_number = data_address['individual_number_address'].values[0] # get data about the activation patterns of these buildings (main units) if config.multi_criteria.network_type == 'DH': building_demands_df = pd.read_csv( locator.get_optimization_network_results_summary( string_network)).set_index("DATE") data_activation_path = os.path.join( locator.get_optimization_slave_heating_activation_pattern( individual_number, generation_number)) df_heating = pd.read_csv(data_activation_path).set_index("DATE") data_activation_path = os.path.join( locator. get_optimization_slave_electricity_activation_pattern_heating( individual_number, generation_number)) df_electricity = pd.read_csv(data_activation_path).set_index("DATE") # get data about the activation patterns of these buildings (storage) data_storage_path = os.path.join( locator.get_optimization_slave_storage_operation_data( individual_number, generation_number)) df_SO = pd.read_csv(data_storage_path).set_index("DATE") # join into one database data_processed = df_heating.join(df_electricity).join(df_SO).join( building_demands_df) elif config.multi_criteria.network_type == 'DC': data_costs = pd.read_csv( os.path.join( locator. get_optimization_slave_investment_cost_detailed_cooling( individual_number, generation_number))) data_cooling = pd.read_csv( os.path.join( locator.get_optimization_slave_cooling_activation_pattern( individual_number, generation_number))) data_electricity = pd.read_csv( os.path.join( locator. get_optimization_slave_electricity_activation_pattern_cooling( individual_number, generation_number))) data_emissions = pd.read_csv( os.path.join( locator.get_optimization_slave_investment_cost_detailed( individual_number, generation_number))) # Total CAPEX calculations # Absorption Chiller Absorption_chiller_cost_data = pd.read_excel( locator.get_supply_systems(config.region), sheetname="Absorption_chiller") Absorption_chiller_cost_data = Absorption_chiller_cost_data[[ 'type', 'code', 'cap_min', 'cap_max', 'a', 'b', 'c', 'd', 'e', 'IR_%', 'LT_yr', 'O&M_%' ]] Absorption_chiller_cost_data = Absorption_chiller_cost_data[ Absorption_chiller_cost_data['type'] == 'double'] max_ACH_chiller_size = max( Absorption_chiller_cost_data['cap_max'].values) Inv_IR = (Absorption_chiller_cost_data.iloc[0]['IR_%']) / 100 Inv_LT = Absorption_chiller_cost_data.iloc[0]['LT_yr'] Q_ACH_max_W = data_cooling['Q_from_ACH_W'].max() Q_ACH_max_W = Q_ACH_max_W * (1 + SIZING_MARGIN) number_of_ACH_chillers = max( int(ceil(Q_ACH_max_W / max_ACH_chiller_size)), 1) Q_nom_ACH_W = Q_ACH_max_W / number_of_ACH_chillers Capex_a_ACH_USD, Opex_fixed_ACH_USD, Capex_ACH_USD = calc_Cinv_ACH( Q_nom_ACH_W, locator, 'double', config) Capex_total_ACH_USD = (Capex_a_ACH_USD * ((1 + Inv_IR)**Inv_LT - 1) / (Inv_IR) * (1 + Inv_IR)**Inv_LT) * number_of_ACH_chillers data_costs['Capex_total_ACH'] = Capex_total_ACH_USD data_costs['Opex_total_ACH'] = np.sum( data_cooling['Opex_var_ACH']) + data_costs['Opex_fixed_ACH'] # VCC VCC_cost_data = pd.read_excel(locator.get_supply_systems( config.region), sheetname="Chiller") VCC_cost_data = VCC_cost_data[VCC_cost_data['code'] == 'CH3'] max_VCC_chiller_size = max(VCC_cost_data['cap_max'].values) Inv_IR = (VCC_cost_data.iloc[0]['IR_%']) / 100 Inv_LT = VCC_cost_data.iloc[0]['LT_yr'] Q_VCC_max_W = data_cooling['Q_from_VCC_W'].max() Q_VCC_max_W = Q_VCC_max_W * (1 + SIZING_MARGIN) number_of_VCC_chillers = max( int(ceil(Q_VCC_max_W / max_VCC_chiller_size)), 1) Q_nom_VCC_W = Q_VCC_max_W / number_of_VCC_chillers Capex_a_VCC_USD, Opex_fixed_VCC_USD, Capex_VCC_USD = calc_Cinv_VCC( Q_nom_VCC_W, locator, config, 'CH3') Capex_total_VCC_USD = (Capex_a_VCC_USD * ((1 + Inv_IR)**Inv_LT - 1) / (Inv_IR) * (1 + Inv_IR)**Inv_LT) * number_of_VCC_chillers data_costs['Capex_total_VCC'] = Capex_total_VCC_USD data_costs['Opex_total_VCC'] = np.sum( data_cooling['Opex_var_VCC']) + data_costs['Opex_fixed_VCC'] # VCC Backup Q_VCC_backup_max_W = data_cooling['Q_from_VCC_backup_W'].max() Q_VCC_backup_max_W = Q_VCC_backup_max_W * (1 + SIZING_MARGIN) number_of_VCC_backup_chillers = max( int(ceil(Q_VCC_backup_max_W / max_VCC_chiller_size)), 1) Q_nom_VCC_backup_W = Q_VCC_backup_max_W / number_of_VCC_backup_chillers Capex_a_VCC_backup_USD, Opex_fixed_VCC_backup_USD, Capex_VCC_backup_USD = calc_Cinv_VCC( Q_nom_VCC_backup_W, locator, config, 'CH3') Capex_total_VCC_backup_USD = ( Capex_a_VCC_backup_USD * ((1 + Inv_IR)**Inv_LT - 1) / (Inv_IR) * (1 + Inv_IR)**Inv_LT) * number_of_VCC_backup_chillers data_costs['Capex_total_VCC_backup'] = Capex_total_VCC_backup_USD data_costs['Opex_total_VCC_backup'] = np.sum( data_cooling['Opex_var_VCC_backup'] ) + data_costs['Opex_fixed_VCC_backup'] # Storage Tank storage_cost_data = pd.read_excel(locator.get_supply_systems( config.region), sheetname="TES") storage_cost_data = storage_cost_data[storage_cost_data['code'] == 'TES2'] Inv_IR = (storage_cost_data.iloc[0]['IR_%']) / 100 Inv_LT = storage_cost_data.iloc[0]['LT_yr'] Capex_a_storage_tank_USD = data_costs['Capex_a_Tank'][0] Capex_total_storage_tank_USD = (Capex_a_storage_tank_USD * ((1 + Inv_IR)**Inv_LT - 1) / (Inv_IR) * (1 + Inv_IR)**Inv_LT) data_costs['Capex_total_storage_tank'] = Capex_total_storage_tank_USD data_costs['Opex_total_storage_tank'] = np.sum( data_cooling['Opex_var_VCC_backup'] ) + data_costs['Opex_fixed_Tank'] # Cooling Tower CT_cost_data = pd.read_excel(locator.get_supply_systems(config.region), sheetname="CT") CT_cost_data = CT_cost_data[CT_cost_data['code'] == 'CT1'] max_CT_size = max(CT_cost_data['cap_max'].values) Inv_IR = (CT_cost_data.iloc[0]['IR_%']) / 100 Inv_LT = CT_cost_data.iloc[0]['LT_yr'] Qc_CT_max_W = data_cooling['Qc_CT_associated_with_all_chillers_W'].max( ) number_of_CT = max(int(ceil(Qc_CT_max_W / max_CT_size)), 1) Qnom_CT_W = Qc_CT_max_W / number_of_CT Capex_a_CT_USD, Opex_fixed_CT_USD, Capex_CT_USD = calc_Cinv_CT( Qnom_CT_W, locator, config, 'CT1') Capex_total_CT_USD = (Capex_a_CT_USD * ((1 + Inv_IR)**Inv_LT - 1) / (Inv_IR) * (1 + Inv_IR)**Inv_LT) * number_of_CT data_costs['Capex_total_CT'] = Capex_total_CT_USD data_costs['Opex_total_CT'] = np.sum( data_cooling['Opex_var_CT']) + data_costs['Opex_fixed_CT'] # CCGT CCGT_cost_data = pd.read_excel(locator.get_supply_systems( config.region), sheetname="CCGT") technology_code = list(set(CCGT_cost_data['code'])) CCGT_cost_data = CCGT_cost_data[CCGT_cost_data['code'] == technology_code[0]] Inv_IR = (CCGT_cost_data.iloc[0]['IR_%']) / 100 Inv_LT = CCGT_cost_data.iloc[0]['LT_yr'] Capex_a_CCGT_USD = data_costs['Capex_a_CCGT'][0] Capex_total_CCGT_USD = (Capex_a_CCGT_USD * ((1 + Inv_IR)**Inv_LT - 1) / (Inv_IR) * (1 + Inv_IR)**Inv_LT) data_costs['Capex_total_CCGT'] = Capex_total_CCGT_USD data_costs['Opex_total_CCGT'] = np.sum( data_cooling['Opex_var_CCGT']) + data_costs['Opex_fixed_CCGT'] # pump config.restricted_to = None # FIXME: remove this later config.thermal_network.network_type = config.multi_criteria.network_type config.thermal_network.network_names = [] network_features = network_opt.network_opt_main(config, locator) DCN_barcode = "" for name in building_names: DCN_barcode += str(df_current_individual[name + ' DCN'][0]) if df_current_individual['Data Centre'][0] == 1: df = pd.read_csv( locator.get_optimization_network_data_folder( "Network_summary_result_" + hex(int(str(DCN_barcode), 2)) + ".csv"), usecols=[ "mdot_cool_space_cooling_and_refrigeration_netw_all_kgpers" ]) else: df = pd.read_csv( locator.get_optimization_network_data_folder( "Network_summary_result_" + hex(int(str(DCN_barcode), 2)) + ".csv"), usecols=[ "mdot_cool_space_cooling_data_center_and_refrigeration_netw_all_kgpers" ]) mdotA_kgpers = np.array(df) mdotnMax_kgpers = np.amax(mdotA_kgpers) deltaPmax = np.max((network_features.DeltaP_DCN) * DCN_barcode.count("1") / len(DCN_barcode)) E_pumping_required_W = mdotnMax_kgpers * deltaPmax / DENSITY_OF_WATER_AT_60_DEGREES_KGPERM3 P_motor_tot_W = E_pumping_required_W / PUMP_ETA # electricty to run the motor Pump_max_kW = 375.0 Pump_min_kW = 0.5 nPumps = int(np.ceil(P_motor_tot_W / 1000.0 / Pump_max_kW)) # if the nominal load (electric) > 375kW, a new pump is installed Pump_Array_W = np.zeros((nPumps)) Pump_Remain_W = P_motor_tot_W Capex_total_pumps_USD = 0 Capex_a_total_pumps_USD = 0 for pump_i in range(nPumps): # calculate pump nominal capacity Pump_Array_W[pump_i] = min(Pump_Remain_W, Pump_max_kW * 1000) if Pump_Array_W[pump_i] < Pump_min_kW * 1000: Pump_Array_W[pump_i] = Pump_min_kW * 1000 Pump_Remain_W -= Pump_Array_W[pump_i] pump_cost_data = pd.read_excel(locator.get_supply_systems( config.region), sheetname="Pump") pump_cost_data = pump_cost_data[pump_cost_data['code'] == 'PU1'] # if the Q_design is below the lowest capacity available for the technology, then it is replaced by the least # capacity for the corresponding technology from the database if Pump_Array_W[pump_i] < pump_cost_data.iloc[0]['cap_min']: Pump_Array_W[pump_i] = pump_cost_data.iloc[0]['cap_min'] pump_cost_data = pump_cost_data[ (pump_cost_data['cap_min'] <= Pump_Array_W[pump_i]) & (pump_cost_data['cap_max'] > Pump_Array_W[pump_i])] Inv_a = pump_cost_data.iloc[0]['a'] Inv_b = pump_cost_data.iloc[0]['b'] Inv_c = pump_cost_data.iloc[0]['c'] Inv_d = pump_cost_data.iloc[0]['d'] Inv_e = pump_cost_data.iloc[0]['e'] Inv_IR = (pump_cost_data.iloc[0]['IR_%']) / 100 Inv_LT = pump_cost_data.iloc[0]['LT_yr'] Inv_OM = pump_cost_data.iloc[0]['O&M_%'] / 100 InvC = Inv_a + Inv_b * (Pump_Array_W[pump_i])**Inv_c + ( Inv_d + Inv_e * Pump_Array_W[pump_i]) * log( Pump_Array_W[pump_i]) Capex_total_pumps_USD += InvC Capex_a_total_pumps_USD += InvC * (Inv_IR) * ( 1 + Inv_IR)**Inv_LT / ((1 + Inv_IR)**Inv_LT - 1) data_costs['Capex_total_pumps'] = Capex_total_pumps_USD data_costs['Opex_total_pumps'] = data_costs[ 'Opex_fixed_pump'] + data_costs['Opex_fixed_pump'] # Lake - No lake in singapore, should be modified in future data_costs['Opex_fixed_Lake'] = [0] data_costs['Opex_total_Lake'] = [0] data_costs['Capex_total_Lake'] = [0] data_costs['Capex_a_Lake'] = [0] # PV pv_installed_area = data_electricity['Area_PV_m2'].max() Capex_a_PV_USD, Opex_fixed_PV_USD, Capex_PV_USD = calc_Cinv_pv( pv_installed_area, locator, config) pv_annual_production_kWh = (data_electricity['E_PV_W'].sum()) / 1000 Opex_a_PV_USD = calc_opex_PV(pv_annual_production_kWh, pv_installed_area) PV_cost_data = pd.read_excel(locator.get_supply_systems(config.region), sheetname="PV") technology_code = list(set(PV_cost_data['code'])) PV_cost_data[PV_cost_data['code'] == technology_code[0]] Inv_IR = (PV_cost_data.iloc[0]['IR_%']) / 100 Inv_LT = PV_cost_data.iloc[0]['LT_yr'] Capex_total_PV_USD = (Capex_a_PV_USD * ((1 + Inv_IR)**Inv_LT - 1) / (Inv_IR) * (1 + Inv_IR)**Inv_LT) data_costs['Capex_total_PV'] = Capex_total_PV_USD data_costs['Opex_total_PV'] = Opex_a_PV_USD + Opex_fixed_PV_USD data_costs['Opex_fixed_PV'] = Opex_fixed_PV_USD data_costs['Capex_a_PV'] = Capex_a_PV_USD # Disconnected Buildings Capex_total_disconnected_USD = 0 Opex_total_disconnected_USD = 0 Capex_a_total_disconnected_USD = 0 for (index, building_name) in zip(DCN_barcode, building_names): if index is '0': df = pd.read_csv( locator. get_optimization_decentralized_folder_building_result_cooling( building_name, configuration='AHU_ARU_SCU')) dfBest = df[df["Best configuration"] == 1] if dfBest['VCC to AHU_ARU_SCU Share'].iloc[ 0] == 1: #FIXME: Check for other options Inv_IR = (VCC_cost_data.iloc[0]['IR_%']) / 100 Inv_LT = VCC_cost_data.iloc[0]['LT_yr'] if dfBest['single effect ACH to AHU_ARU_SCU Share (FP)'].iloc[ 0] == 1: Inv_IR = ( Absorption_chiller_cost_data.iloc[0]['IR_%']) / 100 Inv_LT = Absorption_chiller_cost_data.iloc[0]['LT_yr'] Opex_total_disconnected_USD += dfBest[ "Operation Costs [CHF]"].iloc[0] Capex_a_total_disconnected_USD += dfBest[ "Annualized Investment Costs [CHF]"].iloc[0] Capex_total_disconnected_USD += ( dfBest["Annualized Investment Costs [CHF]"].iloc[0] * ((1 + Inv_IR)**Inv_LT - 1) / (Inv_IR) * (1 + Inv_IR)**Inv_LT) data_costs[ 'Capex_total_disconnected_Mio'] = Capex_total_disconnected_USD / 1000000 data_costs[ 'Opex_total_disconnected_Mio'] = Opex_total_disconnected_USD / 1000000 data_costs[ 'Capex_a_disconnected_Mio'] = Capex_a_total_disconnected_USD / 1000000 data_costs['Capex_a_disconnected'] = Capex_a_total_disconnected_USD data_costs['Opex_total_disconnected'] = Opex_total_disconnected_USD data_costs['costs_Mio'] = data_raw['population']['costs_Mio'][ individual] data_costs['emissions_kiloton'] = data_raw['population'][ 'emissions_kiloton'][individual] data_costs['prim_energy_TJ'] = data_raw['population'][ 'prim_energy_TJ'][individual] # Network costs network_costs_a_USD = network_features.pipesCosts_DCN_USD * DCN_barcode.count( "1") / len(DCN_barcode) data_costs['Network_costs'] = network_costs_a_USD Inv_IR = 0.05 Inv_LT = 20 network_costs_total_USD = (network_costs_a_USD * ((1 + Inv_IR)**Inv_LT - 1) / (Inv_IR) * (1 + Inv_IR)**Inv_LT) data_costs['Network_costs_Total'] = network_costs_total_USD # Substation costs substation_costs_a_USD = 0 substation_costs_total_USD = 0 for (index, building_name) in zip(DCN_barcode, building_names): if index == "1": if df_current_individual['Data Centre'][0] == 1: df = pd.read_csv( locator.get_optimization_substations_results_file( building_name), usecols=["Q_space_cooling_and_refrigeration_W"]) else: df = pd.read_csv( locator.get_optimization_substations_results_file( building_name), usecols=[ "Q_space_cooling_data_center_and_refrigeration_W" ]) subsArray = np.array(df) Q_max_W = np.amax(subsArray) HEX_cost_data = pd.read_excel(locator.get_supply_systems( config.region), sheetname="HEX") HEX_cost_data = HEX_cost_data[HEX_cost_data['code'] == 'HEX1'] # if the Q_design is below the lowest capacity available for the technology, then it is replaced by the least # capacity for the corresponding technology from the database if Q_max_W < HEX_cost_data.iloc[0]['cap_min']: Q_max_W = HEX_cost_data.iloc[0]['cap_min'] HEX_cost_data = HEX_cost_data[ (HEX_cost_data['cap_min'] <= Q_max_W) & (HEX_cost_data['cap_max'] > Q_max_W)] Inv_a = HEX_cost_data.iloc[0]['a'] Inv_b = HEX_cost_data.iloc[0]['b'] Inv_c = HEX_cost_data.iloc[0]['c'] Inv_d = HEX_cost_data.iloc[0]['d'] Inv_e = HEX_cost_data.iloc[0]['e'] Inv_IR = (HEX_cost_data.iloc[0]['IR_%']) / 100 Inv_LT = HEX_cost_data.iloc[0]['LT_yr'] Inv_OM = HEX_cost_data.iloc[0]['O&M_%'] / 100 InvC = Inv_a + Inv_b * (Q_max_W)**Inv_c + ( Inv_d + Inv_e * Q_max_W) * log(Q_max_W) Capex_a = InvC * (Inv_IR) * (1 + Inv_IR)**Inv_LT / ( (1 + Inv_IR)**Inv_LT - 1) Opex_fixed = Capex_a * Inv_OM substation_costs_total_USD += InvC substation_costs_a_USD += Capex_a + Opex_fixed data_costs['Substation_costs'] = substation_costs_a_USD data_costs['Substation_costs_Total'] = substation_costs_total_USD # Electricity Details/Renewable Share total_electricity_demand_decentralized_W = np.zeros(8760) DCN_barcode = "" for name in building_names: # identifying the DCN code DCN_barcode += str( int(df_current_individual[name + ' DCN'].values[0])) for i, name in zip( DCN_barcode, building_names ): # adding the electricity demand from the decentralized buildings if i is '0': building_demand = pd.read_csv( locator.get_demand_results_folder() + '//' + name + ".csv", usecols=['E_sys_kWh']) total_electricity_demand_decentralized_W += building_demand[ 'E_sys_kWh'] * 1000 lca = lca_calculations(locator, config) data_electricity_processed = electricity_calculations_of_all_buildings( generation_number, individual_number, locator, config) data_costs['Network_electricity_demand_GW'] = ( data_electricity['E_total_req_W'].sum()) / 1000000000 # GW data_costs['Decentralized_electricity_demand_GW'] = ( data_electricity_processed['E_decentralized_appliances_W'].sum() ) / 1000000000 # GW data_costs['Total_electricity_demand_GW'] = ( data_electricity_processed['E_total_req_W'].sum() ) / 1000000000 # GW data_costs['Electricity_for_hotwater_GW'] = ( data_electricity_processed['E_for_hot_water_demand_W'].sum() ) / 1000000000 # GW data_costs['Electricity_for_appliances_GW'] = ( data_electricity_processed['E_appliances_total_W'].sum() ) / 1000000000 # GW renewable_share_electricity = (data_electricity_processed['E_PV_to_directload_W'].sum() + data_electricity_processed['E_PV_to_grid_W'].sum()) * 100 / \ (data_costs['Total_electricity_demand_GW'] * 1000000000) data_costs['renewable_share_electricity'] = renewable_share_electricity data_costs['Electricity_Costs_Mio'] = ( (data_electricity_processed['E_from_grid_W'].sum() + data_electricity_processed['E_total_to_grid_W_negative'].sum()) * lca.ELEC_PRICE) / 1000000 data_costs['Capex_a_total_Mio'] = (Capex_a_ACH_USD * number_of_ACH_chillers + Capex_a_VCC_USD * number_of_VCC_chillers + \ Capex_a_VCC_backup_USD * number_of_VCC_backup_chillers + Capex_a_CT_USD * number_of_CT + Capex_a_storage_tank_USD + \ Capex_a_total_pumps_USD + Capex_a_CCGT_USD + Capex_a_PV_USD + Capex_a_total_disconnected_USD + substation_costs_a_USD + network_costs_a_USD) / 1000000 data_costs['Capex_a_ACH'] = Capex_a_ACH_USD * number_of_ACH_chillers data_costs['Capex_a_VCC'] = Capex_a_VCC_USD * number_of_VCC_chillers data_costs[ 'Capex_a_VCC_backup'] = Capex_a_VCC_backup_USD * number_of_VCC_backup_chillers data_costs['Capex_a_CT'] = Capex_a_CT_USD * number_of_CT data_costs['Capex_a_storage_tank'] = Capex_a_storage_tank_USD data_costs['Capex_a_total_pumps'] = Capex_a_total_pumps_USD data_costs['Capex_a_CCGT'] = Capex_a_CCGT_USD data_costs['Capex_a_PV'] = Capex_a_PV_USD data_costs['Capex_total_Mio'] = (data_costs['Capex_total_ACH'] + data_costs['Capex_total_VCC'] + data_costs['Capex_total_VCC_backup'] + \ data_costs['Capex_total_storage_tank'] + data_costs['Capex_total_CT'] + data_costs['Capex_total_CCGT'] + \ data_costs['Capex_total_pumps'] + data_costs['Capex_total_PV'] + Capex_total_disconnected_USD + substation_costs_total_USD + network_costs_total_USD) / 1000000 data_costs['Opex_total_Mio'] = (((data_costs['Opex_total_ACH'] + data_costs['Opex_total_VCC'] + data_costs['Opex_total_VCC_backup'] + \ data_costs['Opex_total_storage_tank'] + data_costs['Opex_total_CT'] + data_costs['Opex_total_CCGT'] + \ data_costs['Opex_total_pumps'] + Opex_total_disconnected_USD)) + data_costs['Opex_total_PV'] + \ data_costs['Total_electricity_demand_GW'] * 1000000000 * lca.ELEC_PRICE) / 1000000 data_costs['TAC_Mio'] = data_costs['Capex_a_total_Mio'] + data_costs[ 'Opex_total_Mio'] # temporary fix for bug in emissions calculation, change it after executive course data_costs[ 'total_emissions_kiloton'] = data_costs['emissions_kiloton'] - abs( 2 * data_emissions['CO2_PV_disconnected'] / 1000000) data_costs[ 'total_prim_energy_TJ'] = data_costs['prim_energy_TJ'] - abs( 2 * data_emissions['Eprim_PV_disconnected'] / 1000000) return data_costs
def cooling_calculations_of_DC_buildings(locator, master_to_slave_vars, ntwFeat, prices, lca, config, reduced_timesteps_flag): """ Computes the parameters for the cooling of the complete DCN :param locator: path to res folder :param ntwFeat: network features :param prices: Prices imported from the database :type locator: string :type ntwFeat: class :type prices: class :return: costs, co2, prim :rtype: tuple """ ############# Recover the cooling needs # Cooling demands in a neighborhood are divided into three categories currently. They are # 1. Space Cooling in buildings # 2. Data center Cooling # 3. Refrigeration Needs # Data center cooling can also be done by recovering the heat and heating other demands during the same time # whereas Space cooling and refrigeration needs are to be provided by District Cooling Network or decentralized cooling # Currently, all the buildings are assumed to be connected to DCN # In the following code, the cooling demands of Space cooling and refrigeration are first satisfied by using Lake and VCC # This is then followed by checking of the Heat recovery from Data Centre, if it is allowed, then the corresponding # cooling demand is ignored. If not, the corresponding coolind demand is also satisfied by DCN. t0 = time.time() DCN_barcode = master_to_slave_vars.DCN_barcode print ('Cooling Main is Running') # Space cooling previously aggregated in the substation routine if master_to_slave_vars.WasteServersHeatRecovery == 1: df = pd.read_csv(locator.get_optimization_network_data_folder(master_to_slave_vars.network_data_file_cooling), usecols=["T_DCNf_space_cooling_and_refrigeration_sup_K", "T_DCNf_space_cooling_and_refrigeration_re_K", "mdot_cool_space_cooling_and_refrigeration_netw_all_kgpers"]) df = df.fillna(0) T_sup_K = df['T_DCNf_space_cooling_and_refrigeration_sup_K'].values T_re_K = df['T_DCNf_space_cooling_and_refrigeration_re_K'].values mdot_kgpers = df['mdot_cool_space_cooling_and_refrigeration_netw_all_kgpers'].values else: df = pd.read_csv(locator.get_optimization_network_data_folder(master_to_slave_vars.network_data_file_cooling), usecols=["T_DCNf_space_cooling_data_center_and_refrigeration_sup_K", "T_DCNf_space_cooling_data_center_and_refrigeration_re_K", "mdot_cool_space_cooling_data_center_and_refrigeration_netw_all_kgpers"]) df = df.fillna(0) T_sup_K = df['T_DCNf_space_cooling_data_center_and_refrigeration_sup_K'].values T_re_K = df['T_DCNf_space_cooling_data_center_and_refrigeration_re_K'].values mdot_kgpers = df['mdot_cool_space_cooling_data_center_and_refrigeration_netw_all_kgpers'].values DCN_operation_parameters = df.fillna(0) DCN_operation_parameters_array = DCN_operation_parameters.values Qc_DCN_W = np.array( pd.read_csv(locator.get_optimization_network_data_folder(master_to_slave_vars.network_data_file_cooling), usecols=["Q_DCNf_space_cooling_and_refrigeration_W", "Q_DCNf_space_cooling_data_center_and_refrigeration_W"])) # importing the cooling demands of DCN (space cooling + refrigeration) # Data center cooling, (treated separately for each building) df = pd.read_csv(locator.get_total_demand(), usecols=["Name", "Qcdata_sys_MWhyr"]) arrayData = np.array(df) # total cooling requirements based on the Heat Recovery Flag Q_cooling_req_W = np.zeros(8760) if master_to_slave_vars.WasteServersHeatRecovery == 0: for hour in range(8760): # summing cooling loads of space cooling, refrigeration and data center Q_cooling_req_W[hour] = Qc_DCN_W[hour][1] else: for hour in range(8760): # only including cooling loads of space cooling and refrigeration Q_cooling_req_W[hour] = Qc_DCN_W[hour][0] ############# Recover the heat already taken from the Lake by the heat pumps if config.district_heating_network: try: dfSlave = pd.read_csv( locator.get_optimization_slave_heating_activation_pattern(master_to_slave_vars.individual_number, master_to_slave_vars.generation_number), usecols=["Q_coldsource_HPLake_W"]) Q_Lake_Array_W = np.array(dfSlave) except: Q_Lake_Array_W = [0] else: Q_Lake_Array_W = [0] ### input parameters Qc_VCC_max_W = master_to_slave_vars.VCC_cooling_size_W Qc_ACH_max_W = master_to_slave_vars.Absorption_chiller_size_W T_ground_K = calculate_ground_temperature(locator, config) # sizing cold water storage tank if master_to_slave_vars.Storage_cooling_size_W > 0: Qc_tank_discharge_peak_W = master_to_slave_vars.Storage_cooling_size_W Qc_tank_charge_max_W = (Qc_VCC_max_W + Qc_ACH_max_W) * 0.8 # assume reduced capacity when Tsup is lower peak_hour = np.argmax(Q_cooling_req_W) area_HEX_tank_discharege_m2, UA_HEX_tank_discharge_WperK, \ area_HEX_tank_charge_m2, UA_HEX_tank_charge_WperK, \ V_tank_m3 = storage_tank.calc_storage_tank_properties(DCN_operation_parameters, Qc_tank_charge_max_W, Qc_tank_discharge_peak_W, peak_hour, master_to_slave_vars) else: Qc_tank_discharge_peak_W = 0 Qc_tank_charge_max_W = 0 area_HEX_tank_discharege_m2 = 0 UA_HEX_tank_discharge_WperK = 0 area_HEX_tank_charge_m2 = 0 UA_HEX_tank_charge_WperK = 0 V_tank_m3 = 0 VCC_cost_data = pd.read_excel(locator.get_supply_systems(config.region), sheetname="Chiller") VCC_cost_data = VCC_cost_data[VCC_cost_data['code'] == 'CH3'] max_VCC_chiller_size = max(VCC_cost_data['cap_max'].values) Absorption_chiller_cost_data = pd.read_excel(locator.get_supply_systems(config.region), sheetname="Absorption_chiller") Absorption_chiller_cost_data = Absorption_chiller_cost_data[Absorption_chiller_cost_data['type'] == ACH_TYPE_DOUBLE] max_ACH_chiller_size = max(Absorption_chiller_cost_data['cap_max'].values) # deciding the number of chillers and the nominal size based on the maximum chiller size Qc_VCC_max_W = Qc_VCC_max_W * (1 + SIZING_MARGIN) Qc_ACH_max_W = Qc_ACH_max_W * (1 + SIZING_MARGIN) Q_peak_load_W = Q_cooling_req_W.max() * (1 + SIZING_MARGIN) Qc_VCC_backup_max_W = (Q_peak_load_W - Qc_ACH_max_W - Qc_VCC_max_W - Qc_tank_discharge_peak_W) if Qc_VCC_backup_max_W < 0: Qc_VCC_backup_max_W = 0 if Qc_VCC_max_W <= max_VCC_chiller_size: Qnom_VCC_W = Qc_VCC_max_W number_of_VCC_chillers = 1 else: number_of_VCC_chillers = int(ceil(Qc_VCC_max_W / max_VCC_chiller_size)) Qnom_VCC_W = Qc_VCC_max_W / number_of_VCC_chillers if Qc_VCC_backup_max_W <= max_VCC_chiller_size: Qnom_VCC_backup_W = Qc_VCC_backup_max_W number_of_VCC_backup_chillers = 1 else: number_of_VCC_backup_chillers = int(ceil(Qc_VCC_backup_max_W / max_VCC_chiller_size)) Qnom_VCC_backup_W = Qc_VCC_backup_max_W / number_of_VCC_backup_chillers if Qc_ACH_max_W <= max_ACH_chiller_size: Qnom_ACH_W = Qc_ACH_max_W number_of_ACH_chillers = 1 else: number_of_ACH_chillers = int(ceil(Qc_ACH_max_W / max_ACH_chiller_size)) Qnom_ACH_W = Qc_ACH_max_W / number_of_ACH_chillers limits = {'Qc_VCC_max_W': Qc_VCC_max_W, 'Qc_ACH_max_W': Qc_ACH_max_W, 'Qc_peak_load_W': Qc_tank_discharge_peak_W, 'Qnom_VCC_W': Qnom_VCC_W, 'number_of_VCC_chillers': number_of_VCC_chillers, 'Qnom_ACH_W': Qnom_ACH_W, 'number_of_ACH_chillers': number_of_ACH_chillers, 'Qnom_VCC_backup_W': Qnom_VCC_backup_W, 'number_of_VCC_backup_chillers': number_of_VCC_backup_chillers, 'Qc_tank_discharge_peak_W': Qc_tank_discharge_peak_W, 'Qc_tank_charge_max_W': Qc_tank_charge_max_W, 'V_tank_m3': V_tank_m3, 'T_tank_fully_charged_K': T_TANK_FULLY_CHARGED_K, 'area_HEX_tank_discharge_m2': area_HEX_tank_discharege_m2, 'UA_HEX_tank_discharge_WperK': UA_HEX_tank_discharge_WperK, 'area_HEX_tank_charge_m2': area_HEX_tank_charge_m2, 'UA_HEX_tank_charge_WperK': UA_HEX_tank_charge_WperK} ### input variables lake_available_cooling = pd.read_csv(locator.get_lake_potential(), usecols=['lake_potential']) Qc_available_from_lake_W = np.sum(lake_available_cooling).values[0] + np.sum(Q_Lake_Array_W) Qc_from_lake_cumulative_W = 0 cooling_resource_potentials = {'T_tank_K': T_TANK_FULLY_DISCHARGED_K, 'Qc_avail_from_lake_W': Qc_available_from_lake_W, 'Qc_from_lake_cumulative_W': Qc_from_lake_cumulative_W} ############# Output results PipeLifeTime = 40.0 # years, Data from A&W PipeInterestRate = 0.05 # 5% interest rate network_costs_USD = ntwFeat.pipesCosts_DCN_USD * DCN_barcode.count('1') / master_to_slave_vars.total_buildings network_costs_a_USD = network_costs_USD * PipeInterestRate * (1+ PipeInterestRate) ** PipeLifeTime / ((1+PipeInterestRate) ** PipeLifeTime - 1) costs_a_USD = network_costs_a_USD CO2_kgCO2 = 0 prim_MJ = 0 nBuild = int(np.shape(arrayData)[0]) if reduced_timesteps_flag == False: start_t = 0 stop_t = int(np.shape(DCN_operation_parameters)[0]) else: # timesteps in May start_t = 2880 stop_t = 3624 timesteps = range(start_t, stop_t) calfactor_buildings = np.zeros(8760) TotalCool = 0 Qc_from_Lake_W = np.zeros(8760) Qc_from_VCC_W = np.zeros(8760) Qc_from_ACH_W = np.zeros(8760) Qc_from_storage_tank_W = np.zeros(8760) Qc_from_VCC_backup_W = np.zeros(8760) Qc_req_from_CT_W = np.zeros(8760) Qh_req_from_CCGT_W = np.zeros(8760) Qh_from_CCGT_W = np.zeros(8760) E_gen_CCGT_W = np.zeros(8760) opex_var_Lake_USD = np.zeros(8760) opex_var_VCC_USD = np.zeros(8760) opex_var_ACH_USD = np.zeros(8760) opex_var_VCC_backup_USD = np.zeros(8760) opex_var_CCGT_USD = np.zeros(8760) opex_var_CT_USD = np.zeros(8760) E_used_Lake_W = np.zeros(8760) E_used_VCC_W = np.zeros(8760) E_used_VCC_backup_W = np.zeros(8760) E_used_ACH_W = np.zeros(8760) E_used_CT_W = np.zeros(8760) co2_Lake_kgCO2 = np.zeros(8760) co2_VCC_kgCO2 = np.zeros(8760) co2_ACH_kgCO2 = np.zeros(8760) co2_VCC_backup_kgCO2 = np.zeros(8760) co2_CCGT_kgCO2 = np.zeros(8760) co2_CT_kgCO2 = np.zeros(8760) prim_energy_Lake_MJ = np.zeros(8760) prim_energy_VCC_MJ = np.zeros(8760) prim_energy_ACH_MJ = np.zeros(8760) prim_energy_VCC_backup_MJ = np.zeros(8760) prim_energy_CCGT_MJ = np.zeros(8760) prim_energy_CT_MJ = np.zeros(8760) NG_used_CCGT_W = np.zeros(8760) calfactor_total = 0 for hour in timesteps: # cooling supply for all buildings excluding cooling loads from data centers performance_indicators_output, \ Qc_supply_to_DCN, calfactor_output, \ Qc_CT_W, Qh_CHP_ACH_W, \ cooling_resource_potentials = cooling_resource_activator(mdot_kgpers[hour], T_sup_K[hour], T_re_K[hour], limits, cooling_resource_potentials, T_ground_K[hour], prices, lca, master_to_slave_vars, config, Q_cooling_req_W[hour], locator) print (hour) # save results for each time-step opex_var_Lake_USD[hour] = performance_indicators_output['Opex_var_Lake_USD'] opex_var_VCC_USD[hour] = performance_indicators_output['Opex_var_VCC_USD'] opex_var_ACH_USD[hour] = performance_indicators_output['Opex_var_ACH_USD'] opex_var_VCC_backup_USD[hour] = performance_indicators_output['Opex_var_VCC_backup_USD'] E_used_Lake_W[hour] = performance_indicators_output['E_used_Lake_W'] E_used_VCC_W[hour] = performance_indicators_output['E_used_VCC_W'] E_used_VCC_backup_W[hour] = performance_indicators_output['E_used_VCC_backup_W'] E_used_ACH_W[hour] = performance_indicators_output['E_used_ACH_W'] co2_Lake_kgCO2[hour] = performance_indicators_output['CO2_Lake_kgCO2'] co2_VCC_kgCO2[hour] = performance_indicators_output['CO2_VCC_kgCO2'] co2_ACH_kgCO2[hour] = performance_indicators_output['CO2_ACH_kgCO2'] co2_VCC_backup_kgCO2[hour] = performance_indicators_output['CO2_VCC_backup_kgCO2'] prim_energy_Lake_MJ[hour] = performance_indicators_output['Primary_Energy_Lake_MJ'] prim_energy_VCC_MJ[hour] = performance_indicators_output['Primary_Energy_VCC_MJ'] prim_energy_ACH_MJ[hour] = performance_indicators_output['Primary_Energy_ACH_MJ'] prim_energy_VCC_backup_MJ[hour] = performance_indicators_output['Primary_Energy_VCC_backup_MJ'] calfactor_buildings[hour] = calfactor_output Qc_from_Lake_W[hour] = Qc_supply_to_DCN['Qc_from_Lake_W'] Qc_from_storage_tank_W[hour] = Qc_supply_to_DCN['Qc_from_Tank_W'] Qc_from_VCC_W[hour] = Qc_supply_to_DCN['Qc_from_VCC_W'] Qc_from_ACH_W[hour] = Qc_supply_to_DCN['Qc_from_ACH_W'] Qc_from_VCC_backup_W[hour] = Qc_supply_to_DCN['Qc_from_backup_VCC_W'] Qc_req_from_CT_W[hour] = Qc_CT_W Qh_req_from_CCGT_W[hour] = Qh_CHP_ACH_W if reduced_timesteps_flag: reduced_costs_USD = np.sum(opex_var_Lake_USD) + np.sum(opex_var_VCC_USD) + np.sum(opex_var_ACH_USD) + np.sum(opex_var_VCC_backup_USD) reduced_CO2_kgCO2 = np.sum(co2_Lake_kgCO2) + np.sum(co2_Lake_kgCO2) + np.sum(co2_ACH_kgCO2) + np.sum(co2_VCC_backup_kgCO2) reduced_prim_MJ = np.sum(prim_energy_Lake_MJ) + np.sum(prim_energy_VCC_MJ) + np.sum(prim_energy_ACH_MJ) + np.sum( prim_energy_VCC_backup_MJ) costs_a_USD += reduced_costs_USD*(8760/(stop_t-start_t)) CO2_kgCO2 += reduced_CO2_kgCO2*(8760/(stop_t-start_t)) prim_MJ += reduced_prim_MJ*(8760/(stop_t-start_t)) else: costs_a_USD += np.sum(opex_var_Lake_USD) + np.sum(opex_var_VCC_USD) + np.sum(opex_var_ACH_USD) + np.sum(opex_var_VCC_backup_USD) CO2_kgCO2 += np.sum(co2_Lake_kgCO2) + np.sum(co2_Lake_kgCO2) + np.sum(co2_ACH_kgCO2) + np.sum(co2_VCC_backup_kgCO2) prim_MJ += np.sum(prim_energy_Lake_MJ) + np.sum(prim_energy_VCC_MJ) + np.sum(prim_energy_ACH_MJ) + np.sum( prim_energy_VCC_backup_MJ) calfactor_total += np.sum(calfactor_buildings) TotalCool += np.sum(Qc_from_Lake_W) + np.sum(Qc_from_VCC_W) + np.sum(Qc_from_ACH_W) + np.sum(Qc_from_VCC_backup_W) + np.sum(Qc_from_storage_tank_W) Q_VCC_nom_W = limits['Qnom_VCC_W'] Q_ACH_nom_W = limits['Qnom_ACH_W'] Q_VCC_backup_nom_W = limits['Qnom_VCC_backup_W'] Q_CT_nom_W = np.amax(Qc_req_from_CT_W) Qh_req_from_CCGT_max_W = np.amax(Qh_req_from_CCGT_W) # the required heat output from CCGT at peak mdot_Max_kgpers = np.amax(DCN_operation_parameters_array[:, 1]) # sizing of DCN network pumps Q_GT_nom_W = 0 ########## Operation of the cooling tower if Q_CT_nom_W > 0: for hour in timesteps: wdot_CT = CTModel.calc_CT(Qc_req_from_CT_W[hour], Q_CT_nom_W) opex_var_CT_USD[hour] = (wdot_CT) * lca.ELEC_PRICE co2_CT_kgCO2[hour] = (wdot_CT) * lca.EL_TO_CO2 * 3600E-6 prim_energy_CT_MJ[hour] = (wdot_CT) * lca.EL_TO_OIL_EQ * 3600E-6 E_used_CT_W[hour] = wdot_CT if reduced_timesteps_flag: reduced_costs_USD = np.sum(opex_var_CT_USD) reduced_CO2_kgCO2 = np.sum(co2_CT_kgCO2) reduced_prim_MJ = np.sum(prim_energy_CT_MJ) costs_a_USD += reduced_costs_USD * (8760 / (stop_t - start_t)) CO2_kgCO2 += reduced_CO2_kgCO2 * (8760 / (stop_t - start_t)) prim_MJ += reduced_prim_MJ * (8760 / (stop_t - start_t)) else: costs_a_USD += np.sum(opex_var_CT_USD) CO2_kgCO2 += np.sum(co2_CT_kgCO2) prim_MJ += np.sum(prim_energy_CT_MJ) ########## Operation of the CCGT if Qh_req_from_CCGT_max_W > 0: # Sizing of CCGT GT_fuel_type = 'NG' # assumption for scenarios in SG Q_GT_nom_sizing_W = Qh_req_from_CCGT_max_W # starting guess for the size of GT Qh_output_CCGT_max_W = 0 # the heat output of CCGT at currently installed size (Q_GT_nom_sizing_W) while (Qh_output_CCGT_max_W - Qh_req_from_CCGT_max_W) <= 0: Q_GT_nom_sizing_W += 1000 # update GT size # get CCGT performance limits and functions at Q_GT_nom_sizing_W CCGT_performances = cogeneration.calc_cop_CCGT(Q_GT_nom_sizing_W, ACH_T_IN_FROM_CHP, GT_fuel_type, prices, lca) Qh_output_CCGT_max_W = CCGT_performances['q_output_max_W'] # unpack CCGT performance functions Q_GT_nom_W = Q_GT_nom_sizing_W * (1 + SIZING_MARGIN) # installed CCGT capacity CCGT_performances = cogeneration.calc_cop_CCGT(Q_GT_nom_W, ACH_T_IN_FROM_CHP, GT_fuel_type, prices, lca) Q_used_prim_W_CCGT_fn = CCGT_performances['q_input_fn_q_output_W'] cost_per_Wh_th_CCGT_fn = CCGT_performances[ 'fuel_cost_per_Wh_th_fn_q_output_W'] # gets interpolated cost function Qh_output_CCGT_min_W = CCGT_performances['q_output_min_W'] Qh_output_CCGT_max_W = CCGT_performances['q_output_max_W'] eta_elec_interpol = CCGT_performances['eta_el_fn_q_input'] for hour in timesteps: if Qh_req_from_CCGT_W[hour] > Qh_output_CCGT_min_W: # operate above minimal load if Qh_req_from_CCGT_W[hour] < Qh_output_CCGT_max_W: # Normal operation Possible within partload regime cost_per_Wh_th = cost_per_Wh_th_CCGT_fn(Qh_req_from_CCGT_W[hour]) Q_used_prim_CCGT_W = Q_used_prim_W_CCGT_fn(Qh_req_from_CCGT_W[hour]) Qh_from_CCGT_W[hour] = Qh_req_from_CCGT_W[hour].copy() E_gen_CCGT_W[hour] = np.float(eta_elec_interpol(Q_used_prim_CCGT_W)) * Q_used_prim_CCGT_W else: raise ValueError('Incorrect CCGT sizing!') else: # operate at minimum load cost_per_Wh_th = cost_per_Wh_th_CCGT_fn(Qh_output_CCGT_min_W) Q_used_prim_CCGT_W = Q_used_prim_W_CCGT_fn(Qh_output_CCGT_min_W) Qh_from_CCGT_W[hour] = Qh_output_CCGT_min_W E_gen_CCGT_W[hour] = np.float(eta_elec_interpol( Qh_output_CCGT_max_W)) * Q_used_prim_CCGT_W opex_var_CCGT_USD[hour] = cost_per_Wh_th * Qh_from_CCGT_W[hour] - E_gen_CCGT_W[hour] * lca.ELEC_PRICE co2_CCGT_kgCO2[hour] = Q_used_prim_CCGT_W * lca.NG_CC_TO_CO2_STD * WH_TO_J / 1.0E6 - E_gen_CCGT_W[hour] * lca.EL_TO_CO2 * 3600E-6 prim_energy_CCGT_MJ[hour] = Q_used_prim_CCGT_W * lca.NG_CC_TO_OIL_STD * WH_TO_J / 1.0E6 - E_gen_CCGT_W[hour] * lca.EL_TO_OIL_EQ * 3600E-6 NG_used_CCGT_W[hour] = Q_used_prim_CCGT_W if reduced_timesteps_flag: reduced_costs_USD = np.sum(opex_var_CCGT_USD) reduced_CO2_kgCO2 = np.sum(co2_CCGT_kgCO2) reduced_prim_MJ = np.sum(prim_energy_CCGT_MJ) costs_a_USD += reduced_costs_USD * (8760 / (stop_t - start_t)) CO2_kgCO2 += reduced_CO2_kgCO2 * (8760 / (stop_t - start_t)) prim_MJ += reduced_prim_MJ * (8760 / (stop_t - start_t)) else: costs_a_USD += np.sum(opex_var_CCGT_USD) CO2_kgCO2 += np.sum(co2_CCGT_kgCO2) prim_MJ += np.sum(prim_energy_CCGT_MJ) ########## Add investment costs for i in range(limits['number_of_VCC_chillers']): Capex_a_VCC_USD, Opex_fixed_VCC_USD, Capex_VCC_USD = VCCModel.calc_Cinv_VCC(Q_VCC_nom_W, locator, config, 'CH3') costs_a_USD += Capex_a_VCC_USD + Opex_fixed_VCC_USD for i in range(limits['number_of_VCC_backup_chillers']): Capex_a_VCC_backup_USD, Opex_fixed_VCC_backup_USD, Capex_VCC_backup_USD = VCCModel.calc_Cinv_VCC(Q_VCC_backup_nom_W, locator, config, 'CH3') costs_a_USD += Capex_a_VCC_backup_USD + Opex_fixed_VCC_backup_USD master_to_slave_vars.VCC_backup_cooling_size_W = Q_VCC_backup_nom_W * limits['number_of_VCC_backup_chillers'] for i in range(limits['number_of_ACH_chillers']): Capex_a_ACH_USD, Opex_fixed_ACH_USD, Capex_ACH_USD = chiller_absorption.calc_Cinv_ACH(Q_ACH_nom_W, locator, ACH_TYPE_DOUBLE, config) costs_a_USD += Capex_a_ACH_USD + Opex_fixed_ACH_USD Capex_a_CCGT_USD, Opex_fixed_CCGT_USD, Capex_CCGT_USD = cogeneration.calc_Cinv_CCGT(Q_GT_nom_W, locator, config) costs_a_USD += Capex_a_CCGT_USD + Opex_fixed_CCGT_USD Capex_a_Tank_USD, Opex_fixed_Tank_USD, Capex_Tank_USD = thermal_storage.calc_Cinv_storage(V_tank_m3, locator, config, 'TES2') costs_a_USD += Capex_a_Tank_USD + Opex_fixed_Tank_USD Capex_a_CT_USD, Opex_fixed_CT_USD, Capex_CT_USD = CTModel.calc_Cinv_CT(Q_CT_nom_W, locator, config, 'CT1') costs_a_USD += Capex_a_CT_USD + Opex_fixed_CT_USD Capex_a_pump_USD, Opex_fixed_pump_USD, Opex_var_pump_USD, Capex_pump_USD = PumpModel.calc_Ctot_pump(master_to_slave_vars, ntwFeat, locator, lca, config) costs_a_USD += Capex_a_pump_USD + Opex_fixed_pump_USD + Opex_var_pump_USD network_data = pd.read_csv(locator.get_optimization_network_data_folder(master_to_slave_vars.network_data_file_cooling)) date = network_data.DATE.values results = pd.DataFrame({"DATE": date, "Q_total_cooling_W": Q_cooling_req_W, "Opex_var_Lake_USD": opex_var_Lake_USD, "Opex_var_VCC_USD": opex_var_VCC_USD, "Opex_var_ACH_USD": opex_var_ACH_USD, "Opex_var_VCC_backup_USD": opex_var_VCC_backup_USD, "Opex_var_CT_USD": opex_var_CT_USD, "Opex_var_CCGT_USD": opex_var_CCGT_USD, "E_used_Lake_W": E_used_Lake_W, "E_used_VCC_W": E_used_VCC_W, "E_used_VCC_backup_W": E_used_VCC_backup_W, "E_used_ACH_W": E_used_ACH_W, "E_used_CT_W": E_used_CT_W, "NG_used_CCGT_W": NG_used_CCGT_W, "CO2_from_using_Lake": co2_Lake_kgCO2, "CO2_from_using_VCC": co2_VCC_kgCO2, "CO2_from_using_ACH": co2_ACH_kgCO2, "CO2_from_using_VCC_backup": co2_VCC_backup_kgCO2, "CO2_from_using_CT": co2_CT_kgCO2, "CO2_from_using_CCGT": co2_CCGT_kgCO2, "Primary_Energy_from_Lake": prim_energy_Lake_MJ, "Primary_Energy_from_VCC": prim_energy_VCC_MJ, "Primary_Energy_from_ACH": prim_energy_ACH_MJ, "Primary_Energy_from_VCC_backup": prim_energy_VCC_backup_MJ, "Primary_Energy_from_CT": prim_energy_CT_MJ, "Primary_Energy_from_CCGT": prim_energy_CCGT_MJ, "Q_from_Lake_W": Qc_from_Lake_W, "Q_from_VCC_W": Qc_from_VCC_W, "Q_from_ACH_W": Qc_from_ACH_W, "Q_from_VCC_backup_W": Qc_from_VCC_backup_W, "Q_from_storage_tank_W": Qc_from_storage_tank_W, "Qc_CT_associated_with_all_chillers_W": Qc_req_from_CT_W, "Qh_CCGT_associated_with_absorption_chillers_W": Qh_from_CCGT_W, "E_gen_CCGT_associated_with_absorption_chillers_W": E_gen_CCGT_W }) results.to_csv(locator.get_optimization_slave_cooling_activation_pattern(master_to_slave_vars.individual_number, master_to_slave_vars.generation_number), index=False) ########### Adjust and add the pumps for filtering and pre-treatment of the water calibration = calfactor_total / 50976000 extraElec = (127865400 + 85243600) * calibration costs_a_USD += extraElec * lca.ELEC_PRICE CO2_kgCO2 += extraElec * lca.EL_TO_CO2 * 3600E-6 prim_MJ += extraElec * lca.EL_TO_OIL_EQ * 3600E-6 # Converting costs into float64 to avoid longer values costs_a_USD = np.float64(costs_a_USD) CO2_kgCO2 = np.float64(CO2_kgCO2) prim_MJ = np.float64(prim_MJ) # Capex_a and Opex_fixed results = pd.DataFrame({"Capex_a_VCC_USD": [Capex_a_VCC_USD], "Opex_fixed_VCC_USD": [Opex_fixed_VCC_USD], "Capex_a_VCC_backup_USD": [Capex_a_VCC_backup_USD], "Opex_fixed_VCC_backup_USD": [Opex_fixed_VCC_backup_USD], "Capex_a_ACH_USD": [Capex_a_ACH_USD], "Opex_fixed_ACH_USD": [Opex_fixed_ACH_USD], "Capex_a_CCGT_USD": [Capex_a_CCGT_USD], "Opex_fixed_CCGT_USD": [Opex_fixed_CCGT_USD], "Capex_a_Tank_USD": [Capex_a_Tank_USD], "Opex_fixed_Tank_USD": [Opex_fixed_Tank_USD], "Capex_a_CT_USD": [Capex_a_CT_USD], "Opex_fixed_CT_USD": [Opex_fixed_CT_USD], "Capex_a_pump_USD": [Capex_a_pump_USD], "Opex_fixed_pump_USD": [Opex_fixed_pump_USD], "Opex_var_pump_USD": [Opex_var_pump_USD], "Capex_VCC_USD": [Capex_VCC_USD], "Capex_VCC_backup_USD": [Capex_VCC_backup_USD], "Capex_ACH_USD": [Capex_ACH_USD], "Capex_CCGT_USD": [Capex_CCGT_USD], "Capex_Tank_USD": [Capex_Tank_USD], "Capex_CT_USD": [Capex_CT_USD], "Capex_pump_USD": [Capex_pump_USD] }) results.to_csv(locator.get_optimization_slave_investment_cost_detailed_cooling(master_to_slave_vars.individual_number, master_to_slave_vars.generation_number), index=False) # print " Cooling main done (", round(time.time()-t0, 1), " seconds used for this task)" # print ('Cooling costs = ' + str(costs)) # print ('Cooling CO2 = ' + str(CO2)) # print ('Cooling Eprim = ' + str(prim)) return (costs_a_USD, CO2_kgCO2, prim_MJ)
def calc_generation_costs_cooling( locator, master_to_slave_variables, config, ): # TRIGENERATION if master_to_slave_variables.NG_Trigen_on == 1: Qc_ACH_nom_W = master_to_slave_variables.NG_Trigen_ACH_size_W Q_GT_nom_W = master_to_slave_variables.NG_Trigen_CCGT_size_W # ACH Capex_a_ACH_USD, Opex_fixed_ACH_USD, Capex_ACH_USD = chiller_absorption.calc_Cinv_ACH( Qc_ACH_nom_W, locator, ACH_TYPE_DOUBLE) # CCGT Capex_a_CCGT_USD, Opex_fixed_CCGT_USD, Capex_CCGT_USD = cogeneration.calc_Cinv_CCGT( Q_GT_nom_W, locator, config) Capex_a_Trigen_NG_USD = Capex_a_ACH_USD + Capex_a_CCGT_USD Opex_fixed_Trigen_NG_USD = Opex_fixed_ACH_USD + Opex_fixed_CCGT_USD Capex_Trigen_NG_USD = Capex_ACH_USD + Capex_CCGT_USD else: Capex_a_Trigen_NG_USD = 0.0 Opex_fixed_Trigen_NG_USD = 0.0 Capex_Trigen_NG_USD = 0.0 # WATER-SOURCE VAPOR COMPRESION CHILLER BASE if master_to_slave_variables.WS_BaseVCC_on == 1: Qc_VCC_nom_W = master_to_slave_variables.WS_BaseVCC_size_W # VCC Capex_a_BaseVCC_WS_USD, Opex_fixed_BaseVCC_WS_USD, Capex_BaseVCC_WS_USD = VCCModel.calc_Cinv_VCC( Qc_VCC_nom_W, locator, config, 'CH3') else: Capex_a_BaseVCC_WS_USD = 0.0 Opex_fixed_BaseVCC_WS_USD = 0.0 Capex_BaseVCC_WS_USD = 0.0 # WATER-SOURCE VAPOR COMPRESION CHILLER PEAK if master_to_slave_variables.WS_PeakVCC_on == 1: Qc_VCC_nom_W = master_to_slave_variables.WS_PeakVCC_size_W # VCC Capex_a_PeakVCC_WS_USD, Opex_fixed_PeakVCC_WS_USD, Capex_PeakVCC_WS_USD = VCCModel.calc_Cinv_VCC( Qc_VCC_nom_W, locator, config, 'CH3') else: Capex_a_PeakVCC_WS_USD = 0.0 Opex_fixed_PeakVCC_WS_USD = 0.0 Capex_PeakVCC_WS_USD = 0.0 # AIR-SOURCE VAPOR COMPRESION CHILLER BASE if master_to_slave_variables.AS_BaseVCC_on == 1: Qc_VCC_nom_W = master_to_slave_variables.AS_BaseVCC_size_W # VCC Capex_a_VCC_USD, Opex_fixed_VCC_USD, Capex_VCC_USD = VCCModel.calc_Cinv_VCC( Qc_VCC_nom_W, locator, config, 'CH3') # COOLING TOWER Capex_a_CT_USD, Opex_fixed_CT_USD, Capex_CT_USD = CTModel.calc_Cinv_CT( Qc_VCC_nom_W, locator, 'CT1') Capex_a_BaseVCC_AS_USD = Capex_a_VCC_USD + Capex_a_CT_USD Opex_fixed_BaseVCC_AS_USD = Opex_fixed_VCC_USD + Opex_fixed_CT_USD Capex_BaseVCC_AS_USD = Capex_VCC_USD + Capex_CT_USD else: Capex_a_BaseVCC_AS_USD = 0.0 Opex_fixed_BaseVCC_AS_USD = 0.0 Capex_BaseVCC_AS_USD = 0.0 # AIR-SOURCE VAPOR COMPRESION CHILLER PEAK if master_to_slave_variables.AS_PeakVCC_on == 1: Qc_VCC_nom_W = master_to_slave_variables.AS_PeakVCC_size_W # VCC Capex_a_VCC_USD, Opex_fixed_VCC_USD, Capex_VCC_USD = VCCModel.calc_Cinv_VCC( Qc_VCC_nom_W, locator, config, 'CH3') # COOLING TOWER Capex_a_CT_USD, Opex_fixed_CT_USD, Capex_CT_USD = CTModel.calc_Cinv_CT( Qc_VCC_nom_W, locator, 'CT1') Capex_a_PeakVCC_AS_USD = Capex_a_VCC_USD + Capex_a_CT_USD Opex_fixed_PeakVCC_AS_USD = Opex_fixed_VCC_USD + Opex_fixed_CT_USD Capex_PeakVCC_AS_USD = Capex_VCC_USD + Capex_CT_USD else: Capex_a_PeakVCC_AS_USD = 0.0 Opex_fixed_PeakVCC_AS_USD = 0.0 Capex_PeakVCC_AS_USD = 0.0 # AIR-SOURCE VCC BACK-UP if master_to_slave_variables.AS_BackupVCC_on == 1: Qc_VCC_nom_W = master_to_slave_variables.AS_BackupVCC_size_W # VCC Capex_a_VCC_USD, Opex_fixed_VCC_USD, Capex_VCC_USD = VCCModel.calc_Cinv_VCC( Qc_VCC_nom_W, locator, config, 'CH3') # COOLING TOWER Capex_a_CT_USD, Opex_fixed_CT_USD, Capex_CT_USD = CTModel.calc_Cinv_CT( Qc_VCC_nom_W, locator, 'CT1') Capex_a_BackupVCC_AS_USD = Capex_a_VCC_USD + Capex_a_CT_USD Opex_fixed_BackupVCC_AS_USD = Opex_fixed_VCC_USD + Opex_fixed_CT_USD Capex_BackupVCC_AS_USD = Capex_VCC_USD + Capex_CT_USD else: Capex_a_BackupVCC_AS_USD = 0.0 Opex_fixed_BackupVCC_AS_USD = 0.0 Capex_BackupVCC_AS_USD = 0.0 # PLOT RESULTS performance = { # annualized capex "Capex_a_Trigen_NG_connected_USD": Capex_a_Trigen_NG_USD, "Capex_a_BaseVCC_WS_connected_USD": Capex_a_BaseVCC_WS_USD, "Capex_a_PeakVCC_WS_connected_USD": Capex_a_PeakVCC_WS_USD, "Capex_a_BaseVCC_AS_connected_USD": Capex_a_BaseVCC_AS_USD, "Capex_a_PeakVCC_AS_connected_USD": Capex_a_PeakVCC_AS_USD, "Capex_a_BackupVCC_AS_connected_USD": Capex_a_BackupVCC_AS_USD, # total capex "Capex_total_Trigen_NG_connected_USD": Capex_Trigen_NG_USD, "Capex_total_BaseVCC_WS_connected_USD": Capex_BaseVCC_WS_USD, "Capex_total_PeakVCC_WS_connected_USD": Capex_PeakVCC_WS_USD, "Capex_total_BaseVCC_AS_connected_USD": Capex_BaseVCC_AS_USD, "Capex_total_PeakVCC_AS_connected_USD": Capex_PeakVCC_AS_USD, "Capex_total_BackupVCC_AS_connected_USD": Capex_BackupVCC_AS_USD, # opex fixed "Opex_fixed_Trigen_NG_connected_USD": Opex_fixed_Trigen_NG_USD, "Opex_fixed_BaseVCC_WS_connected_USD": Opex_fixed_BaseVCC_WS_USD, "Opex_fixed_PeakVCC_WS_connected_USD": Opex_fixed_PeakVCC_WS_USD, "Opex_fixed_BaseVCC_AS_connected_USD": Opex_fixed_BaseVCC_AS_USD, "Opex_fixed_PeakVCC_AS_connected_USD": Opex_fixed_PeakVCC_AS_USD, "Opex_fixed_BackupVCC_AS_connected_USD": Opex_fixed_BackupVCC_AS_USD, } return performance
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 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"