Example #1
0
def evaluation_main(individual, building_names, locator, solar_features,
                    network_features, gv, config, prices, lca, ind_num, gen):
    """
    This function evaluates an individual

    :param individual: list with values of the individual
    :param building_names: list with names of buildings
    :param locator: locator class
    :param solar_features: solar features call to class
    :param network_features: network features call to class
    :param gv: global variables class
    :param optimization_constants: class containing constants used in optimization
    :param config: configuration file
    :param prices: class of prices used in optimization
    :type individual: list
    :type building_names: list
    :type locator: string
    :type solar_features: class
    :type network_features: class
    :type gv: class
    :type optimization_constants: class
    :type config: class
    :type prices: class
    :return: Resulting values of the objective function. costs, CO2, prim
    :rtype: tuple

    """
    # Check the consistency of the individual or create a new one
    individual = check_invalid(individual, len(building_names), config)

    # Initialize objective functions costs, CO2 and primary energy
    costs_USD = 0
    GHG_tonCO2 = 0
    PEN_MJoil = 0
    Q_heating_uncovered_design_W = 0
    Q_heating_uncovered_annual_W = 0

    # Create the string representation of the individual
    DHN_barcode, DCN_barcode, DHN_configuration, DCN_configuration = supportFn.individual_to_barcode(
        individual, building_names)

    if DHN_barcode.count("1") == gv.num_tot_buildings:
        network_file_name_heating = "Network_summary_result_all.csv"
        Q_DHNf_W = pd.read_csv(
            locator.get_optimization_network_all_results_summary('all'),
            usecols=["Q_DHNf_W"]).values
        Q_heating_max_W = Q_DHNf_W.max()
    elif DHN_barcode.count("1") == 0:
        network_file_name_heating = "Network_summary_result_all.csv"
        Q_heating_max_W = 0
    else:
        network_file_name_heating = "Network_summary_result_" + hex(
            int(str(DHN_barcode), 2)) + ".csv"
        if not os.path.exists(
                locator.get_optimization_network_results_summary(DHN_barcode)):
            total_demand = supportFn.createTotalNtwCsv(DHN_barcode, locator)
            building_names = total_demand.Name.values
            # Run the substation and distribution routines
            substation.substation_main(locator,
                                       total_demand,
                                       building_names,
                                       DHN_configuration,
                                       DCN_configuration,
                                       Flag=True)
            summarize_network.network_main(locator, total_demand,
                                           building_names, config, gv,
                                           DHN_barcode)

        Q_DHNf_W = pd.read_csv(
            locator.get_optimization_network_results_summary(DHN_barcode),
            usecols=["Q_DHNf_W"]).values
        Q_heating_max_W = Q_DHNf_W.max()

    if DCN_barcode.count("1") == gv.num_tot_buildings:
        network_file_name_cooling = "Network_summary_result_all.csv"
        if individual[
                N_HEAT *
                2] == 1:  # if heat recovery is ON, then only need to satisfy cooling load of space cooling and refrigeration
            Q_DCNf_W = pd.read_csv(
                locator.get_optimization_network_all_results_summary('all'),
                usecols=["Q_DCNf_space_cooling_and_refrigeration_W"]).values
        else:
            Q_DCNf_W = pd.read_csv(
                locator.get_optimization_network_all_results_summary('all'),
                usecols=[
                    "Q_DCNf_space_cooling_data_center_and_refrigeration_W"
                ]).values
        Q_cooling_max_W = Q_DCNf_W.max()
    elif DCN_barcode.count("1") == 0:
        network_file_name_cooling = "Network_summary_result_all.csv"
        Q_cooling_max_W = 0
    else:
        network_file_name_cooling = "Network_summary_result_" + hex(
            int(str(DCN_barcode), 2)) + ".csv"

        if not os.path.exists(
                locator.get_optimization_network_results_summary(DCN_barcode)):
            total_demand = supportFn.createTotalNtwCsv(DCN_barcode, locator)
            building_names = total_demand.Name.values

            # Run the substation and distribution routines
            substation.substation_main(locator,
                                       total_demand,
                                       building_names,
                                       DHN_configuration,
                                       DCN_configuration,
                                       Flag=True)
            summarize_network.network_main(locator, total_demand,
                                           building_names, config, gv,
                                           DCN_barcode)

        if individual[
                N_HEAT *
                2] == 1:  # if heat recovery is ON, then only need to satisfy cooling load of space cooling and refrigeration
            Q_DCNf_W = pd.read_csv(
                locator.get_optimization_network_results_summary(DCN_barcode),
                usecols=["Q_DCNf_space_cooling_and_refrigeration_W"]).values
        else:
            Q_DCNf_W = pd.read_csv(
                locator.get_optimization_network_results_summary(DCN_barcode),
                usecols=[
                    "Q_DCNf_space_cooling_data_center_and_refrigeration_W"
                ]).values
        Q_cooling_max_W = Q_DCNf_W.max()

    Q_heating_nom_W = Q_heating_max_W * (1 + Q_MARGIN_FOR_NETWORK)
    Q_cooling_nom_W = Q_cooling_max_W * (1 + Q_MARGIN_FOR_NETWORK)

    # Modify the individual with the extra GHP constraint
    try:
        check.GHPCheck(individual, locator, Q_heating_nom_W, gv)
    except:
        print "No GHP constraint check possible \n"

    # Export to context
    master_to_slave_vars = calc_master_to_slave_variables(
        individual, Q_heating_max_W, Q_cooling_max_W, building_names, ind_num,
        gen)
    master_to_slave_vars.network_data_file_heating = network_file_name_heating
    master_to_slave_vars.network_data_file_cooling = network_file_name_cooling
    master_to_slave_vars.total_buildings = len(building_names)
    master_to_slave_vars.DHN_barcode = DHN_barcode
    master_to_slave_vars.DCN_barcode = DCN_barcode

    if master_to_slave_vars.number_of_buildings_connected_heating > 1:
        if DHN_barcode.count("0") == 0:
            master_to_slave_vars.fNameTotalCSV = locator.get_total_demand()
        else:
            master_to_slave_vars.fNameTotalCSV = os.path.join(
                locator.get_optimization_network_totals_folder(),
                "Total_%(DHN_barcode)s.csv" % locals())
    else:
        master_to_slave_vars.fNameTotalCSV = locator.get_optimization_substations_total_file(
            DHN_barcode)

    if master_to_slave_vars.number_of_buildings_connected_cooling > 1:
        if DCN_barcode.count("0") == 0:
            master_to_slave_vars.fNameTotalCSV = locator.get_total_demand()
        else:
            master_to_slave_vars.fNameTotalCSV = os.path.join(
                locator.get_optimization_network_totals_folder(),
                "Total_%(DCN_barcode)s.csv" % locals())
    else:
        master_to_slave_vars.fNameTotalCSV = locator.get_optimization_substations_total_file(
            DCN_barcode)

    # Thermal Storage Calculations; Run storage optimization
    costs_storage_USD, GHG_storage_tonCO2, PEN_storage_MJoil = storage_main.storage_optimization(
        locator, master_to_slave_vars, lca, prices, config)

    costs_USD += costs_storage_USD
    GHG_tonCO2 += GHG_storage_tonCO2
    PEN_MJoil += PEN_storage_MJoil

    # District Heating Calculations
    if config.district_heating_network:

        if DHN_barcode.count("1") > 0:

            (PEN_heating_MJoil, GHG_heating_tonCO2, costs_heating_USD,
             Q_heating_uncovered_design_W, Q_heating_uncovered_annual_W
             ) = heating_main.heating_calculations_of_DH_buildings(
                 locator, master_to_slave_vars, gv, config, prices, lca)
        else:

            GHG_heating_tonCO2 = 0
            costs_heating_USD = 0
            PEN_heating_MJoil = 0
    else:
        GHG_heating_tonCO2 = 0
        costs_heating_USD = 0
        PEN_heating_MJoil = 0

    costs_USD += costs_heating_USD
    GHG_tonCO2 += GHG_heating_tonCO2
    PEN_MJoil += PEN_heating_MJoil

    # District Cooling Calculations
    if gv.ZernezFlag == 1:
        costs_cooling_USD, GHG_cooling_tonCO2, PEN_cooling_MJoil = 0, 0, 0
    elif config.district_cooling_network:
        reduced_timesteps_flag = False
        (costs_cooling_USD, GHG_cooling_tonCO2, PEN_cooling_MJoil
         ) = cooling_main.cooling_calculations_of_DC_buildings(
             locator, master_to_slave_vars, network_features, gv, prices, lca,
             config, reduced_timesteps_flag)
    else:
        costs_cooling_USD, GHG_cooling_tonCO2, PEN_cooling_MJoil = 0, 0, 0

    costs_USD += costs_cooling_USD
    GHG_tonCO2 += GHG_cooling_tonCO2
    PEN_MJoil += PEN_cooling_MJoil

    # District Electricity Calculations
    (costs_electricity_USD, GHG_electricity_tonCO2, PEN_electricity_MJoil
     ) = electricity_main.electricity_calculations_of_all_buildings(
         DHN_barcode, DCN_barcode, locator, master_to_slave_vars,
         network_features, gv, prices, lca, config)

    costs_USD += costs_electricity_USD
    GHG_tonCO2 += GHG_electricity_tonCO2
    PEN_MJoil += PEN_electricity_MJoil

    # Natural Gas Import Calculations. Prices, GHG and PEN are already included in the various sections.
    # This is to save the files for further processing and plots
    natural_gas_main.natural_gas_imports(master_to_slave_vars, locator, config)

    # Capex Calculations
    print "Add extra costs"
    (costs_additional_USD,
     GHG_additional_tonCO2, PEN_additional_MJoil) = cost_model.addCosts(
         building_names, locator, master_to_slave_vars,
         Q_heating_uncovered_design_W, Q_heating_uncovered_annual_W,
         solar_features, network_features, gv, config, prices, lca)

    costs_USD += costs_additional_USD
    GHG_tonCO2 += GHG_additional_tonCO2
    PEN_MJoil += PEN_additional_MJoil

    summarize_individual.summarize_individual_main(master_to_slave_vars,
                                                   building_names, individual,
                                                   solar_features, locator,
                                                   config)

    # Converting costs into float64 to avoid longer values
    costs_USD = np.float64(costs_USD)
    GHG_tonCO2 = np.float64(GHG_tonCO2)
    PEN_MJoil = np.float64(PEN_MJoil)

    print('Total costs = ' + str(costs_USD))
    print('Total CO2 = ' + str(GHG_tonCO2))
    print('Total prim = ' + str(PEN_MJoil))

    # Saving capacity details of the individual

    return costs_USD, GHG_tonCO2, PEN_MJoil, master_to_slave_vars, individual
Example #2
0
def evaluation_main(
    individual,
    building_names_all,
    locator,
    network_features,
    config,
    prices,
    lca,
    ind_num,
    gen,
    column_names_individual,
    column_names_buildings_heating,
    column_names_buildings_cooling,
    building_names_heating,
    building_names_cooling,
    building_names_electricity,
    district_heating_network,
    district_cooling_network,
):
    """
    This function evaluates an individual

    :param individual: list with values of the individual
    :param column_names_buildings_all: list with names of buildings
    :param locator: locator class
    :param solar_features: solar features call to class
    :param network_features: network features call to class
    :param optimization_constants: class containing constants used in optimization
    :param config: configuration file
    :param prices: class of prices used in optimization
    :type individual: list
    :type column_names_buildings_all: list
    :type locator: string
    :type solar_features: class
    :type network_features: class
    :type optimization_constants: class
    :type config: class
    :type prices: class
    :return: Resulting values of the objective function. costs, CO2, prim
    :rtype: tuple

    """

    # CREATE THE INDIVIDUAL BARCODE AND INDIVIDUAL WITH HER COLUMN NAME AS A DICT
    DHN_barcode, DCN_barcode, individual_with_name_dict, building_connectivity_dict = individual_to_barcode(
        individual, building_names_all, building_names_heating,
        building_names_cooling, column_names_individual,
        column_names_buildings_heating, column_names_buildings_cooling)

    print("EVALUATING THE NEXT SYSTEM OPTION/INDIVIDUAL")
    print(individual_with_name_dict)

    # CREATE CLASS AND PASS KEY CHARACTERISTICS OF INDIVIDUAL
    # THIS CLASS SHOULD CONTAIN ALL VARIABLES THAT MAKE AN INDIVIDUAL CONFIGURATION
    master_to_slave_vars = master.export_data_to_master_to_slave_class(
        locator, gen, ind_num, individual_with_name_dict, building_names_all,
        building_names_heating, building_names_cooling,
        building_names_electricity, DHN_barcode, DCN_barcode,
        district_heating_network, district_cooling_network)
    # INITIALIZE DICTS STORING PERFORMANCE DATA
    district_heating_fixed_costs = {}
    district_heating_generation_dispatch = {}
    district_cooling_fixed_costs = {}
    district_cooling_generation_dispatch = {}
    district_heating_capacity_installed = {}
    district_cooling_capacity_installed = {}
    # DISTRICT HEATING NETWORK
    if master_to_slave_vars.DHN_exists:
        print("DISTRICT HEATING OPERATION")
        district_heating_fixed_costs, \
        district_heating_generation_dispatch, \
        district_heating_electricity_requirements_dispatch, \
        district_heating_fuel_requirements_dispatch, \
        district_heating_capacity_installed = heating_main.district_heating_network(locator,
                                                                                    master_to_slave_vars,
                                                                                    config,
                                                                                    prices,
                                                                                    lca,
                                                                                    network_features,
                                                                                    )
    else:
        district_heating_electricity_requirements_dispatch = {
            # ENERGY REQUIREMENTS
            # Electricity
            "E_Storage_charging_req_W": np.zeros(HOURS_IN_YEAR),
            "E_Storage_discharging_req_W": np.zeros(HOURS_IN_YEAR),
            "E_DHN_req_W": np.zeros(HOURS_IN_YEAR),
            "E_HP_SC_FP_req_W": np.zeros(HOURS_IN_YEAR),
            "E_HP_SC_ET_req_W": np.zeros(HOURS_IN_YEAR),
            "E_HP_PVT_req_W": np.zeros(HOURS_IN_YEAR),
            "E_HP_Server_req_W": np.zeros(HOURS_IN_YEAR),
            "E_HP_Sew_req_W": np.zeros(HOURS_IN_YEAR),
            "E_HP_Lake_req_W": np.zeros(HOURS_IN_YEAR),
            "E_GHP_req_W": np.zeros(HOURS_IN_YEAR),
            "E_BaseBoiler_req_W": np.zeros(HOURS_IN_YEAR),
            "E_PeakBoiler_req_W": np.zeros(HOURS_IN_YEAR),
            "E_BackupBoiler_req_W": np.zeros(HOURS_IN_YEAR),
        }
        district_heating_fuel_requirements_dispatch = {
            "NG_CHP_req_W": np.zeros(HOURS_IN_YEAR),
            "NG_BaseBoiler_req_W": np.zeros(HOURS_IN_YEAR),
            "NG_PeakBoiler_req_W": np.zeros(HOURS_IN_YEAR),
            "NG_BackupBoiler_req_W": np.zeros(HOURS_IN_YEAR),
            "WB_Furnace_req_W": np.zeros(HOURS_IN_YEAR),
            "DB_Furnace_req_W": np.zeros(HOURS_IN_YEAR),
        }

    # DISTRICT COOLING NETWORK:
    if master_to_slave_vars.DCN_exists:
        print("DISTRICT COOLING OPERATION")
        district_cooling_fixed_costs, \
        district_cooling_generation_dispatch, \
        district_cooling_electricity_requirements_dispatch, \
        district_cooling_fuel_requirements_dispatch, \
        district_cooling_capacity_installed = cooling_main.district_cooling_network(locator,
                                                                                    master_to_slave_vars,
                                                                                    config,
                                                                                    prices,
                                                                                    network_features)
    else:
        district_cooling_electricity_requirements_dispatch = {
            # ENERGY REQUIREMENTS
            # Electricity
            "E_DCN_req_W": np.zeros(HOURS_IN_YEAR),
            "E_BaseVCC_WS_req_W": np.zeros(HOURS_IN_YEAR),
            "E_PeakVCC_WS_req_W": np.zeros(HOURS_IN_YEAR),
            "E_BaseVCC_AS_req_W": np.zeros(HOURS_IN_YEAR),
            "E_PeakVCC_AS_req_W": np.zeros(HOURS_IN_YEAR),
            "E_BackupVCC_AS_req_W": np.zeros(HOURS_IN_YEAR),
        }
        district_cooling_fuel_requirements_dispatch = {
            "NG_Trigen_req_W": np.zeros(HOURS_IN_YEAR)
        }

    # ELECTRICITY CONSUMPTION CALCULATIONS
    print("DISTRICT ELECTRICITY GRID OPERATION")
    district_electricity_fixed_costs, \
    district_electricity_dispatch, \
    district_electricity_demands, \
    district_electricity_capacity_installed = electricity_main.electricity_calculations_of_all_buildings(locator,
                                                                                                         master_to_slave_vars,
                                                                                                         district_heating_generation_dispatch,
                                                                                                         district_heating_electricity_requirements_dispatch,
                                                                                                         district_cooling_generation_dispatch,
                                                                                                         district_cooling_electricity_requirements_dispatch)

    # print("DISTRICT NATURAL GAS / BIOMASS GRID OPERATION")
    # electricity_main.extract_fuels_demand_buildings(master_to_slave_vars, building_names_all, locator)

    print(
        "DISTRICT ENERGY SYSTEM - COSTS, PRIMARY ENERGY AND EMISSIONS OF CONNECTED BUILDINGS"
    )
    buildings_connected_costs, \
    buildings_connected_emissions = cost_model.buildings_connected_costs_and_emissions(district_heating_fixed_costs,
                                                                                       district_cooling_fixed_costs,
                                                                                       district_electricity_fixed_costs,
                                                                                       district_electricity_dispatch,
                                                                                       district_heating_fuel_requirements_dispatch,
                                                                                       district_cooling_fuel_requirements_dispatch,
                                                                                       district_electricity_demands,
                                                                                       prices,
                                                                                       lca)

    print(
        "DISTRICT ENERGY SYSTEM - COSTS, PRIMARY ENERGY AND EMISSIONS OF DISCONNECTED BUILDINGS"
    )
    buildings_disconnected_costs, \
    buildings_disconnected_emissions, \
    buildings_disconnected_heating_capacities, \
    buildings_disconnected_cooling_capacities = cost_model.buildings_disconnected_costs_and_emissions(
        building_names_heating,
        building_names_cooling,
        locator,
        master_to_slave_vars)

    print("AGGREGATING RESULTS")
    TAC_sys_USD, GHG_sys_tonCO2, PEN_sys_MJoil, performance_totals = summarize_results_individual(
        master_to_slave_vars, buildings_connected_costs,
        buildings_connected_emissions, buildings_disconnected_costs,
        buildings_disconnected_emissions)

    print("SAVING RESULTS TO DISK")
    save_results(
        master_to_slave_vars, locator, buildings_connected_costs,
        buildings_connected_emissions, buildings_disconnected_costs,
        buildings_disconnected_emissions, district_heating_generation_dispatch,
        district_cooling_generation_dispatch, district_electricity_dispatch,
        district_electricity_demands, performance_totals,
        building_connectivity_dict, district_heating_capacity_installed,
        district_cooling_capacity_installed,
        district_electricity_capacity_installed,
        buildings_disconnected_heating_capacities,
        buildings_disconnected_cooling_capacities)

    # Converting costs into float64 to avoid longer values
    print('Total TAC in USD = ' + str(TAC_sys_USD))
    print('Total GHG emissions in tonCO2-eq = ' + str(GHG_sys_tonCO2))
    print('Total PEN non-renewable in MJoil ' + str(PEN_sys_MJoil) + "\n")

    return TAC_sys_USD, GHG_sys_tonCO2, PEN_sys_MJoil
Example #3
0
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
Example #4
0
def supply_calculation(individual, building_names, total_demand, locator,
                       extra_costs, extra_CO2, extra_primary_energy,
                       solar_features, network_features, gv, config, prices,
                       lca):
    """
    This function evaluates one supply system configuration of the case study.
    :param individual: a list that indicates the supply system configuration
    :type individual: list
    :param building_names: names of all building in the district
    :type building_names: ndarray
    :param locator:
    :param extra_costs: cost of decentralized supply systems
    :param extra_CO2: CO2 emission of decentralized supply systems
    :param extra_primary_energy: Primary energy of decentralized supply systems
    :param solar_features: Energy production potentials of solar technologies, including area of installed panels and annual production
    :type solar_features: dict
    :param network_features: hourly network operating conditions (thermal/pressure losses) and capital costs
    :type network_features: dict
    :param gv:
    :param config:
    :param prices:
    :return:
    """
    individual = evaluation.check_invalid(individual, len(building_names),
                                          config)

    # Initialize objective functions costs, CO2 and primary energy
    costs_USD = 0.0
    GHG_tonCO2 = extra_CO2
    PEN_MJoil = extra_primary_energy
    Q_uncovered_design_W = 0.0
    Q_uncovered_annual_W = 0.0

    # Create the string representation of the individual
    DHN_barcode, DCN_barcode, DHN_configuration, DCN_configuration = supportFn.individual_to_barcode(
        individual, building_names)

    # read the total loads from buildings connected to thermal networks
    if DHN_barcode.count("1") == gv.num_tot_buildings:
        network_file_name_heating = "Network_summary_result_all.csv"
        Q_DHNf_W = pd.read_csv(
            locator.get_optimization_network_all_results_summary('all'),
            usecols=["Q_DHNf_W"]).values
        Q_heating_max_W = Q_DHNf_W.max()
    elif DHN_barcode.count("1") == 0:
        network_file_name_heating = "Network_summary_result_all.csv"
        Q_heating_max_W = 0.0
    else:
        # Run the substation and distribution routines
        substation.substation_main(locator,
                                   total_demand,
                                   building_names,
                                   DHN_configuration,
                                   DCN_configuration,
                                   Flag=True)

        summarize_network.network_main(locator, total_demand, building_names,
                                       config, gv, DHN_barcode)

        network_file_name_heating = "Network_summary_result_" + hex(
            int(str(DHN_barcode), 2)) + ".csv"
        Q_DHNf_W = pd.read_csv(
            locator.get_optimization_network_results_summary(DHN_barcode),
            usecols=["Q_DHNf_W"]).values
        Q_heating_max_W = Q_DHNf_W.max()

    if DCN_barcode.count("1") == gv.num_tot_buildings:
        network_file_name_cooling = "Network_summary_result_all.csv"
        if individual[
                N_HEAT *
                2] == 1:  # if heat recovery is ON, then only need to satisfy cooling load of space cooling and refrigeration
            Q_DCNf_W = pd.read_csv(
                locator.get_optimization_network_all_results_summary('all'),
                usecols=["Q_DCNf_space_cooling_and_refrigeration_W"]).values
        else:
            Q_DCNf_W = pd.read_csv(
                locator.get_optimization_network_all_results_summary('all'),
                usecols=[
                    "Q_DCNf_space_cooling_data_center_and_refrigeration_W"
                ]).values
        Q_cooling_max_W = Q_DCNf_W.max()
    elif DCN_barcode.count("1") == 0:
        network_file_name_cooling = "Network_summary_result_none.csv"
        Q_cooling_max_W = 0
    else:
        # Run the substation and distribution routines
        substation.substation_main(locator,
                                   total_demand,
                                   building_names,
                                   DHN_configuration,
                                   DCN_configuration,
                                   Flag=True)

        summarize_network.network_main(locator, total_demand, building_names,
                                       config, gv, DCN_barcode)

        network_file_name_cooling = "Network_summary_result_" + hex(
            int(str(DCN_barcode), 2)) + ".csv"

        if individual[
                N_HEAT *
                2] == 1:  # if heat recovery is ON, then only need to satisfy cooling load of space cooling and refrigeration
            Q_DCNf_W = pd.read_csv(
                locator.get_optimization_network_results_summary(DCN_barcode),
                usecols=["Q_DCNf_space_cooling_and_refrigeration_W"]).values
        else:
            Q_DCNf_W = pd.read_csv(
                locator.get_optimization_network_results_summary(DCN_barcode),
                usecols=[
                    "Q_DCNf_space_cooling_data_center_and_refrigeration_W"
                ]).values
        Q_cooling_max_W = Q_DCNf_W.max()

    Q_heating_nom_W = Q_heating_max_W * (1 + Q_MARGIN_FOR_NETWORK)
    Q_cooling_nom_W = Q_cooling_max_W * (1 + Q_MARGIN_FOR_NETWORK)

    # Modify the individual with the extra GHP constraint
    try:
        check.GHPCheck(individual, locator, Q_heating_nom_W, gv)
    except:
        print "No GHP constraint check possible \n"

    # Export to context
    individual_number = calc_individual_number(locator)
    master_to_slave_vars = evaluation.calc_master_to_slave_variables(
        individual, Q_heating_max_W, Q_cooling_max_W, building_names,
        individual_number, GENERATION_NUMBER)
    master_to_slave_vars.network_data_file_heating = network_file_name_heating
    master_to_slave_vars.network_data_file_cooling = network_file_name_cooling
    master_to_slave_vars.total_buildings = len(building_names)

    if master_to_slave_vars.number_of_buildings_connected_heating > 1:
        if DHN_barcode.count("0") == 0:
            master_to_slave_vars.fNameTotalCSV = locator.get_total_demand()
        else:
            master_to_slave_vars.fNameTotalCSV = os.path.join(
                locator.get_optimization_network_totals_folder(),
                "Total_%(DHN_barcode)s.csv" % locals())
    else:
        master_to_slave_vars.fNameTotalCSV = locator.get_optimization_substations_total_file(
            DHN_barcode)

    if master_to_slave_vars.number_of_buildings_connected_cooling > 1:
        if DCN_barcode.count("0") == 0:
            master_to_slave_vars.fNameTotalCSV = locator.get_total_demand()
        else:
            master_to_slave_vars.fNameTotalCSV = os.path.join(
                locator.get_optimization_network_totals_folder(),
                "Total_%(DCN_barcode)s.csv" % locals())
    else:
        master_to_slave_vars.fNameTotalCSV = locator.get_optimization_substations_total_file(
            DCN_barcode)

    costs_storage_USD, GHG_storage_tonCO2, PEN_storage_MJoil = storage_main.storage_optimization(
        locator, master_to_slave_vars, lca, prices, config)

    costs_USD += costs_storage_USD
    GHG_tonCO2 += GHG_storage_tonCO2
    PEN_MJoil += PEN_storage_MJoil

    # slave optimization of heating networks
    if config.district_heating_network:
        if DHN_barcode.count("1") > 0:
            (PEN_heating_MJoil, GHG_heating_tonCO2, costs_heating_USD,
             Q_uncovered_design_W, Q_uncovered_annual_W
             ) = heating_main.heating_calculations_of_DH_buildings(
                 locator, master_to_slave_vars, gv, config, prices, lca)
        else:
            GHG_heating_tonCO2 = 0.0
            costs_heating_USD = 0.0
            PEN_heating_MJoil = 0.0
    else:
        GHG_heating_tonCO2 = 0.0
        costs_heating_USD = 0.0
        PEN_heating_MJoil = 0.0

    costs_USD += costs_heating_USD
    GHG_tonCO2 += GHG_heating_tonCO2
    PEN_MJoil += PEN_heating_MJoil

    # slave optimization of cooling networks
    if gv.ZernezFlag == 1:
        costs_cooling_USD, GHG_cooling_tonCO2, PEN_cooling_MJoil = 0.0, 0.0, 0.0
    elif config.district_cooling_network and DCN_barcode.count("1") > 0:
        reduced_timesteps_flag = config.supply_system_simulation.reduced_timesteps
        (costs_cooling_USD, GHG_cooling_tonCO2, PEN_cooling_MJoil
         ) = cooling_main.cooling_calculations_of_DC_buildings(
             locator, master_to_slave_vars, network_features, gv, prices, lca,
             config, reduced_timesteps_flag)
        # if reduced_timesteps_flag:
        #     # reduced timesteps simulation for a month (May)
        #     coolCosts = coolCosts * (8760/(3624/2880))
        #     coolCO2 = coolCO2 * (8760/(3624/2880))
        #     coolPrim = coolPrim * (8760/(3624/2880))
        #     # FIXME: check results
    else:
        costs_cooling_USD, GHG_cooling_tonCO2, PEN_cooling_MJoil = 0.0, 0.0, 0.0

    # District Electricity Calculations
    costs_electricity_USD, GHG_electricity_tonCO2, PEN_electricity_MJoil = electricity_main.electricity_calculations_of_all_buildings(
        DHN_barcode, DCN_barcode, locator, master_to_slave_vars,
        network_features, gv, prices, lca, config)

    costs_USD += costs_electricity_USD
    GHG_tonCO2 += GHG_electricity_tonCO2
    PEN_MJoil += PEN_electricity_MJoil

    natural_gas_main.natural_gas_imports(master_to_slave_vars, locator, config)

    # print "Add extra costs"
    # add costs of disconnected buildings (best configuration)
    (costs_additional_USD,
     GHG_additional_tonCO2, PEN_additional_MJoil) = cost_model.addCosts(
         building_names, locator, master_to_slave_vars, Q_uncovered_design_W,
         Q_uncovered_annual_W, solar_features, network_features, gv, config,
         prices, lca)

    costs_USD += costs_additional_USD
    GHG_tonCO2 += GHG_additional_tonCO2
    PEN_MJoil += PEN_additional_MJoil

    costs_USD = (np.float64(costs_USD) / 1e6).round(2)  # $ to Mio$
    GHG_tonCO2 = (np.float64(GHG_tonCO2) / 1e6).round(2)  # kg to kilo-ton
    PEN_MJoil = (np.float64(PEN_MJoil) / 1e6).round(2)  # MJ to TJ

    # add electricity costs corresponding to

    # print ('Additional costs = ' + str(addCosts))
    # print ('Additional CO2 = ' + str(addCO2))
    # print ('Additional prim = ' + str(addPrim))

    print('Total annualized costs [USD$(2015) Mio/yr] = ' + str(costs_USD))
    print('Green house gas emission [kton-CO2/yr] = ' + str(GHG_tonCO2))
    print('Primary energy [TJ-oil-eq/yr] = ' + str(PEN_MJoil))

    results = {
        'TAC_Mio_per_yr': [costs_USD.round(2)],
        'CO2_kton_per_yr': [GHG_tonCO2.round(2)],
        'Primary_Energy_TJ_per_yr': [PEN_MJoil.round(2)]
    }
    results_df = pd.DataFrame(results)
    results_path = os.path.join(
        locator.get_optimization_slave_results_folder(GENERATION_NUMBER),
        'ind_' + str(individual_number) + '_results.csv')
    results_df.to_csv(results_path)

    with open(locator.get_optimization_checkpoint_initial(), "wb") as fp:
        pop = []
        g = GENERATION_NUMBER
        epsInd = []
        invalid_ind = []
        fitnesses = []
        capacities = []
        disconnected_capacities = []
        halloffame = []
        halloffame_fitness = []
        euclidean_distance = []
        spread = []
        cp = dict(population=pop,
                  generation=g,
                  epsIndicator=epsInd,
                  testedPop=invalid_ind,
                  population_fitness=fitnesses,
                  capacities=capacities,
                  disconnected_capacities=disconnected_capacities,
                  halloffame=halloffame,
                  halloffame_fitness=halloffame_fitness,
                  euclidean_distance=euclidean_distance,
                  spread=spread)
        json.dump(cp, fp)

    return costs_USD, GHG_tonCO2, PEN_MJoil, master_to_slave_vars, individual
def energy_mix_based_on_technologies_script(generation, individual, locator,
                                            network_type):
    category = "optimization-detailed"

    config = cea.config.Configuration()
    config.restricted_to = None  # do this to avoid problems with arcgis interface ##TODO: fix here
    if network_type == 'DH':
        print('Need to do this in future')

    elif network_type == 'DC':
        data_cooling = pd.read_csv(
            os.path.join(
                locator.get_optimization_slave_cooling_activation_pattern(
                    individual, generation)))

        Q_VCC_total_W = data_cooling['Q_from_VCC_W'].sum()
        Q_Lake_total_W = data_cooling['Q_from_Lake_W'].sum()
        Q_ACH_total_W = data_cooling['Q_from_ACH_W'].sum()
        Q_VCC_backup_total_W = data_cooling['Q_from_VCC_backup_W'].sum()
        Q_thermal_storage_total_W = data_cooling['Q_from_storage_tank_W'].sum()
        Q_cooling_total_W = data_cooling['Q_total_cooling_W'].sum()

        if not os.path.exists(
                locator.
                get_optimization_slave_electricity_activation_pattern_processed(
                    individual, generation)):
            data_electricity = electricity_calculations_of_all_buildings(
                generation, individual, locator, config)
        else:
            data_electricity = pd.read_csv(
                locator.
                get_optimization_slave_electricity_activation_pattern_processed(
                    individual, generation))

        E_ACH_total_W = data_electricity['E_ACH_W'].sum()
        E_CHP_to_directload_total_W = data_electricity[
            'E_CHP_to_directload_W'].sum()
        E_CHP_to_grid_total_W = data_electricity['E_CHP_to_grid_W'].sum()
        E_CT_total_W = data_electricity['E_CT_W'].sum()
        E_PV_to_directload_total_W = data_electricity[
            'E_PV_to_directload_W'].sum()
        E_PV_to_grid_total_W = data_electricity['E_PV_to_grid_W'].sum()
        E_VCC_total_W = data_electricity['E_VCC_W'].sum()
        E_VCC_backup_total_W = data_electricity['E_VCC_backup_W'].sum()
        E_hotwater_total_W = data_electricity['E_for_hot_water_demand_W'].sum()
        E_from_grid_total_W = data_electricity['E_from_grid_W'].sum()
        E_required_district_total_W = data_electricity['E_total_req_W'].sum()
        E_building_appliances_total_W = E_required_district_total_W - E_hotwater_total_W - E_VCC_backup_total_W - E_VCC_total_W - \
                                        E_CT_total_W - E_ACH_total_W

        if not os.path.exists(
                locator.get_optimization_slave_natural_gas_imports(
                    individual, generation)):
            data_natural_gas = natural_gas_imports(generation, individual,
                                                   locator, config)
        else:
            data_natural_gas = pd.read_csv(
                locator.get_optimization_slave_natural_gas_imports(
                    individual, generation))

        NG_used_total_W = data_natural_gas['NG_used_CCGT_W'].sum()

        results = pd.DataFrame({
            "Q_VCC_total_MWhyr": [round(Q_VCC_total_W / 1000000, 2)],
            "Q_Lake_total_MWhyr": [round(Q_Lake_total_W / 1000000, 2)],
            "Q_ACH_total_MWhyr": [round(Q_ACH_total_W / 1000000, 2)],
            "Q_VCC_backup_total_MWhyr":
            [round(Q_VCC_backup_total_W / 1000000, 2)],
            "Q_thermal_storage_total_MWhyr":
            [round(Q_thermal_storage_total_W / 1000000, 2)],
            "Q_cooling_total_MWhyr": [round(Q_cooling_total_W / 1000000, 2)],
            "E_ACH_total_MWhyr": [round(E_ACH_total_W / 1000000, 2)],
            "E_CHP_to_directload_MWhyr":
            [round(E_CHP_to_directload_total_W / 1000000, 2)],
            "E_CHP_to_grid_total_MWhyr":
            [round(E_CHP_to_grid_total_W / 1000000, 2)],
            "E_PV_to_directload_MWhyr":
            [round(E_PV_to_directload_total_W / 1000000, 2)],
            "E_PV_to_grid_total_MWhyr":
            [round(E_PV_to_grid_total_W / 1000000, 2)],
            "E_VCC_total_MWhyr": [round(E_VCC_total_W / 1000000, 2)],
            "E_VCC_backup_total_MWhyr":
            [round(E_VCC_backup_total_W / 1000000, 2)],
            "E_hotwater_total_MWhyr": [round(E_hotwater_total_W / 1000000, 2)],
            "GRID_MWhyr": [round(E_from_grid_total_W / 1000000, 2)],
            "E_required_district_total_MWhyr":
            [round(E_required_district_total_W / 1000000, 2)],
            "E_building_appliances_total_MWhyr":
            [round(E_building_appliances_total_W / 1000000, 2)],
            "NG_CCGT_MWhyr": [round(NG_used_total_W / 1000000, 2)]
        })

    results.to_csv(
        locator.get_optimization_slave_energy_mix_based_on_technologies(
            individual, generation, category),
        index=False)

    return results
def evaluation_main(individual, building_names_all, locator, network_features,
                    weather_features, config, prices, lca, individual_number,
                    generation_number, column_names_individual,
                    column_names_buildings_heating,
                    column_names_buildings_cooling, building_names_heating,
                    building_names_cooling, building_names_electricity,
                    district_heating_network, district_cooling_network,
                    technologies_heating_allowed,
                    technologies_cooling_allowed):
    """
    This function evaluates an individual

    :param individual: list with values of the individual
    :param column_names_buildings_all: list with names of buildings
    :param cea.inputlocator.InputLocator locator: locator class
    :param solar_features: solar features call to class
    :param network_features: network features call to class
    :param optimization_constants: class containing constants used in optimization
    :param config: configuration file
    :param prices: class of prices used in optimization
    :type individual: list
    :type column_names_buildings_all: list
    :type solar_features: class
    :type network_features: class
    :type optimization_constants: class
    :type config: class
    :type prices: class
    :return: Resulting values of the objective function. costs, CO2, prim
    :rtype: tuple

    """

    # CREATE THE INDIVIDUAL BARCODE AND INDIVIDUAL WITH HER COLUMN NAME AS A DICT
    DHN_barcode, DCN_barcode, individual_with_name_dict, building_connectivity_dict = individual_to_barcode(
        individual, building_names_all, building_names_heating,
        building_names_cooling, column_names_individual,
        column_names_buildings_heating, column_names_buildings_cooling)

    print("EVALUATING THE NEXT SYSTEM OPTION/INDIVIDUAL")
    print(individual_with_name_dict)
    # CREATE CLASS AND PASS KEY CHARACTERISTICS OF INDIVIDUAL
    # THIS CLASS SHOULD CONTAIN ALL VARIABLES THAT MAKE AN INDIVIDUAL CONFIGURATION
    master_to_slave_vars = master.export_data_to_master_to_slave_class(
        locator,
        generation_number,
        individual_number,
        individual_with_name_dict,
        building_names_all,
        building_names_heating,
        building_names_cooling,
        building_names_electricity,
        DHN_barcode,
        DCN_barcode,
        district_heating_network,
        district_cooling_network,
        technologies_heating_allowed,
        technologies_cooling_allowed,
        weather_features,
    )

    # DISTRICT HEATING NETWORK
    print("DISTRICT HEATING OPERATION")
    district_heating_fixed_costs, \
    district_heating_generation_dispatch, \
    district_heating_electricity_requirements_dispatch, \
    district_heating_fuel_requirements_dispatch, \
    district_heating_capacity_installed = heating_main.district_heating_network(locator,
                                                                                master_to_slave_vars,
                                                                                config,
                                                                                network_features,
                                                                                )

    # DISTRICT COOLING NETWORK:
    print("DISTRICT COOLING OPERATION")
    district_cooling_fixed_costs, \
    district_cooling_generation_dispatch, \
    district_cooling_electricity_requirements_dispatch, \
    district_cooling_fuel_requirements_dispatch, \
    district_cooling_capacity_installed = cooling_main.district_cooling_network(locator,
                                                                                master_to_slave_vars,
                                                                                config,
                                                                                prices,
                                                                                network_features)

    # ELECTRICITY CONSUMPTION CALCULATIONS
    print("DISTRICT ELECTRICITY GRID OPERATION")
    district_electricity_fixed_costs, \
    district_electricity_dispatch, \
    district_electricity_demands, \
    district_electricity_capacity_installed = electricity_main.electricity_calculations_of_all_buildings(locator,
                                                                                                         master_to_slave_vars,
                                                                                                         district_heating_generation_dispatch,
                                                                                                         district_heating_electricity_requirements_dispatch,
                                                                                                         district_cooling_generation_dispatch,
                                                                                                         district_cooling_electricity_requirements_dispatch)

    # electricity_main.extract_fuels_demand_buildings(master_to_slave_vars, building_names_all, locator)
    print(
        "DISTRICT ENERGY SYSTEM - COSTS, PRIMARY ENERGY AND EMISSIONS OF CONNECTED BUILDINGS"
    )
    buildings_district_scale_costs, \
    buildings_district_scale_emissions = cost_model.buildings_district_scale_costs_and_emissions(district_heating_fixed_costs,
                                                                                       district_cooling_fixed_costs,
                                                                                       district_electricity_fixed_costs,
                                                                                       district_electricity_dispatch,
                                                                                       district_heating_fuel_requirements_dispatch,
                                                                                       district_cooling_fuel_requirements_dispatch,
                                                                                       district_electricity_demands,
                                                                                       prices,
                                                                                       lca)

    print(
        "DISTRICT ENERGY SYSTEM - COSTS, PRIMARY ENERGY AND EMISSIONS OF DISCONNECTED BUILDINGS"
    )
    buildings_building_scale_costs, \
    buildings_building_scale_emissions, \
    buildings_building_scale_heating_capacities, \
    buildings_building_scale_cooling_capacities = cost_model.buildings_building_scale_costs_and_emissions(
        building_names_heating,
        building_names_cooling,
        locator,
        master_to_slave_vars)

    print("AGGREGATING RESULTS")
    TAC_sys_USD, GHG_sys_tonCO2, performance_totals = summarize_results_individual(
        buildings_district_scale_costs, buildings_district_scale_emissions,
        buildings_building_scale_costs, buildings_building_scale_emissions)

    print('Total TAC in USD = ' + str(TAC_sys_USD))
    print('Total GHG emissions in tonCO2-eq = ' + str(GHG_sys_tonCO2))

    return TAC_sys_USD, \
           GHG_sys_tonCO2, \
           buildings_district_scale_costs, \
           buildings_district_scale_emissions, \
           buildings_building_scale_costs, \
           buildings_building_scale_emissions, \
           district_heating_generation_dispatch, \
           district_cooling_generation_dispatch, \
           district_electricity_dispatch, \
           district_electricity_demands, \
           performance_totals, \
           building_connectivity_dict, \
           district_heating_capacity_installed, \
           district_cooling_capacity_installed, \
           district_electricity_capacity_installed, \
           buildings_building_scale_heating_capacities, \
           buildings_building_scale_cooling_capacities