Beispiel #1
0
def disconnected_cooling_for_building(building_name, supply_systems, lca,
                                      locator, prices, total_demand):
    chiller_prop = supply_systems.Absorption_chiller
    boiler_cost_data = supply_systems.Boiler

    scale = 'BUILDING'
    VCC_chiller = chiller_vapor_compression.VaporCompressionChiller(
        locator, scale)

    ## Calculate cooling loads for different combinations
    # SENSIBLE COOLING UNIT
    Qc_nom_SCU_W, \
    T_re_SCU_K, \
    T_sup_SCU_K, \
    mdot_SCU_kgpers = calc_combined_cooling_loads(building_name, locator, total_demand,
                                                  cooling_configuration=['scu'])
    # AIR HANDLING UNIT + AIR RECIRCULATION UNIT
    Qc_nom_AHU_ARU_W, \
    T_re_AHU_ARU_K, \
    T_sup_AHU_ARU_K, \
    mdot_AHU_ARU_kgpers = calc_combined_cooling_loads(building_name, locator, total_demand,
                                                      cooling_configuration=['ahu', 'aru'])
    # SENSIBLE COOLING UNIT + AIR HANDLING UNIT + AIR RECIRCULATION UNIT
    Qc_nom_AHU_ARU_SCU_W, \
    T_re_AHU_ARU_SCU_K, \
    T_sup_AHU_ARU_SCU_K, \
    mdot_AHU_ARU_SCU_kgpers = calc_combined_cooling_loads(building_name, locator, total_demand,
                                                          cooling_configuration=['ahu', 'aru', 'scu'])
    ## Get hourly hot water supply condition of Solar Collectors (SC)
    # Flate Plate Solar Collectors
    SC_FP_data, T_hw_in_FP_C, el_aux_SC_FP_Wh, q_sc_gen_FP_Wh = get_SC_data(
        building_name, locator, panel_type="FP")
    Capex_a_SC_FP_USD, Opex_SC_FP_USD, Capex_SC_FP_USD = solar_collector.calc_Cinv_SC(
        SC_FP_data['Area_SC_m2'][0], locator, panel_type="FP")
    # Evacuated Tube Solar Collectors
    SC_ET_data, T_hw_in_ET_C, el_aux_SC_ET_Wh, q_sc_gen_ET_Wh = get_SC_data(
        building_name, locator, panel_type="ET")
    Capex_a_SC_ET_USD, Opex_SC_ET_USD, Capex_SC_ET_USD = solar_collector.calc_Cinv_SC(
        SC_ET_data['Area_SC_m2'][0], locator, panel_type="ET")
    ## Calculate ground temperatures to estimate cold water supply temperatures for absorption chiller
    T_ground_K = calculate_ground_temperature(
        locator)  # FIXME: change to outlet temperature from the cooling towers
    ## Initialize table to save results
    # save costs of all supply configurations
    operation_results = initialize_result_tables_for_supply_configurations(
        Qc_nom_SCU_W)
    # save supply system activation of all supply configurations
    cooling_dispatch = {}
    ## HOURLY OPERATION
    print('{building_name} decentralized cooling supply system simulations...'.
          format(building_name=building_name))
    T_re_AHU_ARU_SCU_K = np.where(T_re_AHU_ARU_SCU_K > 0.0, T_re_AHU_ARU_SCU_K,
                                  T_sup_AHU_ARU_SCU_K)
    ## 0. DX operation
    print('{building_name} Config 0: Direct Expansion Units -> AHU,ARU,SCU'.
          format(building_name=building_name))
    el_DX_hourly_Wh, \
    q_DX_chw_Wh = np.vectorize(dx.calc_DX)(mdot_AHU_ARU_SCU_kgpers, T_sup_AHU_ARU_SCU_K, T_re_AHU_ARU_SCU_K)
    DX_Status = np.where(q_DX_chw_Wh > 0.0, 1, 0)
    # add electricity costs, CO2, PE
    operation_results[0][7] += sum(prices.ELEC_PRICE * el_DX_hourly_Wh)
    operation_results[0][8] += sum(
        calc_emissions_Whyr_to_tonCO2yr(el_DX_hourly_Wh,
                                        lca.EL_TO_CO2_EQ))  # ton CO2
    # activation
    cooling_dispatch[0] = {
        'Q_DX_AS_gen_directload_W': q_DX_chw_Wh,
        'E_DX_AS_req_W': el_DX_hourly_Wh,
        'E_cs_cre_cdata_req_W': el_DX_hourly_Wh,
    }
    # capacity of cooling technologies
    operation_results[0][0] = Qc_nom_AHU_ARU_SCU_W
    operation_results[0][1] = Qc_nom_AHU_ARU_SCU_W  # 1: DX_AS
    system_COP = np.nanmedian(
        np.divide(q_DX_chw_Wh[None, :], el_DX_hourly_Wh[None, :]).flatten())
    operation_results[0][9] += system_COP
    ## 1. VCC (AHU + ARU + SCU) + CT
    print(
        '{building_name} Config 1: Vapor Compression Chillers -> AHU,ARU,SCU'.
        format(building_name=building_name))
    # VCC operation
    el_VCC_Wh, q_VCC_cw_Wh, q_VCC_chw_Wh = calc_VCC_operation(
        T_re_AHU_ARU_SCU_K, T_sup_AHU_ARU_SCU_K, mdot_AHU_ARU_SCU_kgpers,
        VCC_chiller)
    VCC_Status = np.where(q_VCC_chw_Wh > 0.0, 1, 0)
    # CT operation
    q_CT_VCC_to_AHU_ARU_SCU_Wh = q_VCC_cw_Wh
    Q_nom_CT_VCC_to_AHU_ARU_SCU_W, el_CT_Wh = calc_CT_operation(
        q_CT_VCC_to_AHU_ARU_SCU_Wh)
    # add costs
    el_total_Wh = el_VCC_Wh + el_CT_Wh
    operation_results[1][7] += sum(prices.ELEC_PRICE * el_total_Wh)  # CHF
    operation_results[1][8] += sum(
        calc_emissions_Whyr_to_tonCO2yr(el_total_Wh,
                                        lca.EL_TO_CO2_EQ))  # ton CO2
    system_COP_list = np.divide(q_VCC_chw_Wh[None, :],
                                el_total_Wh[None, :]).flatten()
    system_COP = np.nansum(
        q_VCC_chw_Wh[None, :] * system_COP_list) / np.nansum(
            q_VCC_chw_Wh[None, :])  # weighted average of the system efficiency
    operation_results[1][9] += system_COP
    cooling_dispatch[1] = {
        'Q_BaseVCC_AS_gen_directload_W': q_VCC_chw_Wh,
        'E_BaseVCC_AS_req_W': el_VCC_Wh,
        'E_CT_req_W': el_CT_Wh,
        'E_cs_cre_cdata_req_W': el_total_Wh,
    }
    # capacity of cooling technologies
    operation_results[1][0] = Qc_nom_AHU_ARU_SCU_W
    operation_results[1][2] = Qc_nom_AHU_ARU_SCU_W  # 2: BaseVCC_AS
    ## 2: SC_FP + single-effect ACH (AHU + ARU + SCU) + CT + Boiler + SC_FP
    print(
        '{building_name} Config 2: Flat-plate Solar Collectors + Single-effect Absorption chillers -> AHU,ARU,SCU'
        .format(building_name=building_name))
    # ACH operation
    T_hw_out_single_ACH_K, \
    el_single_ACH_Wh, \
    q_cw_single_ACH_Wh, \
    q_hw_single_ACH_Wh, \
    q_chw_single_ACH_Wh = calc_ACH_operation(T_ground_K, T_hw_in_FP_C, T_re_AHU_ARU_SCU_K, T_sup_AHU_ARU_SCU_K,
                                             chiller_prop, mdot_AHU_ARU_SCU_kgpers, ACH_TYPE_SINGLE)
    ACH_Status = np.where(q_chw_single_ACH_Wh > 0.0, 1, 0)
    # CT operation
    q_CT_FP_to_single_ACH_to_AHU_ARU_SCU_Wh = q_cw_single_ACH_Wh
    Q_nom_CT_FP_to_single_ACH_to_AHU_ARU_SCU_W, el_CT_Wh = calc_CT_operation(
        q_CT_FP_to_single_ACH_to_AHU_ARU_SCU_Wh)
    # boiler operation
    q_gas_Boiler_FP_to_single_ACH_to_AHU_ARU_SCU_Wh, \
    Q_nom_Boiler_FP_to_single_ACH_to_AHU_ARU_SCU_W, \
    q_load_Boiler_FP_to_single_ACH_to_AHU_ARU_SCU_Wh = calc_boiler_operation(Qc_nom_AHU_ARU_SCU_W,
                                                                             T_hw_out_single_ACH_K,
                                                                             q_hw_single_ACH_Wh,
                                                                             q_sc_gen_FP_Wh)
    # add electricity costs
    el_total_Wh = el_single_ACH_Wh + el_aux_SC_FP_Wh + el_CT_Wh
    operation_results[2][7] += sum(prices.ELEC_PRICE * el_total_Wh)  # CHF
    operation_results[2][8] += sum(
        calc_emissions_Whyr_to_tonCO2yr(el_total_Wh,
                                        lca.EL_TO_CO2_EQ))  # ton CO2
    # add gas costs
    q_gas_total_Wh = q_gas_Boiler_FP_to_single_ACH_to_AHU_ARU_SCU_Wh
    operation_results[2][7] += sum(prices.NG_PRICE * q_gas_total_Wh)  # CHF
    operation_results[2][8] += sum(
        calc_emissions_Whyr_to_tonCO2yr(q_gas_total_Wh,
                                        lca.NG_TO_CO2_EQ))  # ton CO2
    # add activation
    cooling_dispatch[2] = {
        'Q_ACH_gen_directload_W': q_chw_single_ACH_Wh,
        'Q_Boiler_NG_ACH_W': q_load_Boiler_FP_to_single_ACH_to_AHU_ARU_SCU_Wh,
        'Q_SC_FP_ACH_W': q_sc_gen_FP_Wh,
        'E_ACH_req_W': el_single_ACH_Wh,
        'E_CT_req_W': el_CT_Wh,
        'E_SC_FP_req_W': el_aux_SC_FP_Wh,
        'E_cs_cre_cdata_req_W': el_total_Wh,
        'NG_Boiler_req': q_gas_Boiler_FP_to_single_ACH_to_AHU_ARU_SCU_Wh,
    }
    # capacity of cooling technologies
    operation_results[2][0] = Qc_nom_AHU_ARU_SCU_W
    operation_results[2][4] = Qc_nom_AHU_ARU_SCU_W  # 4: ACH_SC_FP
    q_total_load = q_chw_single_ACH_Wh[None, :] + q_sc_gen_FP_Wh[
        None, :] + q_load_Boiler_FP_to_single_ACH_to_AHU_ARU_SCU_Wh[None, :]
    system_COP_list = np.divide(
        q_total_load,
        (el_total_Wh[None, :] +
         q_gas_Boiler_FP_to_single_ACH_to_AHU_ARU_SCU_Wh[None, :])).flatten()
    system_COP = np.nansum(q_total_load * system_COP_list) / np.nansum(
        q_total_load)  # weighted average of the system efficiency
    operation_results[2][9] += system_COP

    # 3: SC_ET + single-effect ACH (AHU + ARU + SCU) + CT + Boiler + SC_ET
    print(
        '{building_name} Config 3: Evacuated Tube Solar Collectors + Single-effect Absorption chillers -> AHU,ARU,SCU'
        .format(building_name=building_name))
    # ACH operation
    T_hw_out_single_ACH_K, \
    el_single_ACH_Wh, \
    q_cw_single_ACH_Wh, \
    q_hw_single_ACH_Wh, \
    q_chw_single_ACH_Wh = calc_ACH_operation(T_ground_K, T_hw_in_ET_C, T_re_AHU_ARU_SCU_K, T_sup_AHU_ARU_SCU_K,
                                             chiller_prop, mdot_AHU_ARU_SCU_kgpers, ACH_TYPE_SINGLE)
    # CT operation
    q_CT_ET_to_single_ACH_to_AHU_ARU_SCU_W = q_cw_single_ACH_Wh
    Q_nom_CT_ET_to_single_ACH_to_AHU_ARU_SCU_W, el_CT_Wh = calc_CT_operation(
        q_CT_ET_to_single_ACH_to_AHU_ARU_SCU_W)
    # burner operation
    q_gas_for_burner_Wh, \
    Q_nom_Burner_ET_to_single_ACH_to_AHU_ARU_SCU_W, \
    q_burner_load_Wh = calc_burner_operation(Qc_nom_AHU_ARU_SCU_W, q_hw_single_ACH_Wh, q_sc_gen_ET_Wh)
    # add electricity costs
    el_total_Wh = el_single_ACH_Wh + el_aux_SC_ET_Wh + el_CT_Wh
    operation_results[3][7] += sum(prices.ELEC_PRICE * el_total_Wh)  # CHF
    operation_results[3][8] += sum(
        calc_emissions_Whyr_to_tonCO2yr(el_total_Wh,
                                        lca.EL_TO_CO2_EQ))  # ton CO2
    # add gas costs
    operation_results[3][7] += sum(prices.NG_PRICE *
                                   q_gas_for_burner_Wh)  # CHF
    operation_results[3][8] += sum(
        calc_emissions_Whyr_to_tonCO2yr(q_gas_for_burner_Wh,
                                        lca.NG_TO_CO2_EQ))  # ton CO2
    # add activation
    cooling_dispatch[3] = {
        'Q_ACH_gen_directload_W': q_chw_single_ACH_Wh,
        'Q_Burner_NG_ACH_W': q_burner_load_Wh,
        'Q_SC_ET_ACH_W': q_sc_gen_ET_Wh,
        'E_ACH_req_W': el_single_ACH_Wh,
        'E_CT_req_W': el_CT_Wh,
        'E_SC_ET_req_W': el_aux_SC_ET_Wh,
        'E_cs_cre_cdata_req_W': el_total_Wh,
        'NG_Burner_req': q_gas_for_burner_Wh,
    }
    # capacity of cooling technologies
    operation_results[3][0] = Qc_nom_AHU_ARU_SCU_W
    operation_results[3][5] = Qc_nom_AHU_ARU_SCU_W
    q_total_load = (q_burner_load_Wh[None, :] + q_chw_single_ACH_Wh[None, :] +
                    q_sc_gen_ET_Wh[None, :])
    system_COP_list = np.divide(
        q_total_load,
        (el_total_Wh[None, :] + q_gas_for_burner_Wh[None, :])).flatten()
    system_COP = np.nansum(q_total_load * system_COP_list) / np.nansum(
        q_total_load)  # weighted average of the system efficiency
    operation_results[3][9] += system_COP

    # these two configurations are only activated when SCU is in use
    if Qc_nom_SCU_W > 0.0:
        # 4: VCC (AHU + ARU) + VCC (SCU) + CT
        print(
            '{building_name} Config 4: Vapor Compression Chillers(HT) -> SCU & Vapor Compression Chillers(LT) -> AHU,ARU'
            .format(building_name=building_name))
        # VCC (AHU + ARU) operation
        el_VCC_to_AHU_ARU_Wh, \
        q_cw_VCC_to_AHU_ARU_Wh, \
        q_chw_VCC_to_AHU_ARU_Wh = calc_VCC_operation(T_re_AHU_ARU_K, T_sup_AHU_ARU_K, mdot_AHU_ARU_kgpers, VCC_chiller)
        VCC_LT_Status = np.where(q_chw_VCC_to_AHU_ARU_Wh > 0.0, 1, 0)
        # VCC(SCU) operation
        el_VCC_to_SCU_Wh, \
        q_cw_VCC_to_SCU_Wh, \
        q_chw_VCC_to_SCU_Wh = calc_VCC_operation(T_re_SCU_K, T_sup_SCU_K, mdot_SCU_kgpers, VCC_chiller)
        VCC_HT_Status = np.where(q_chw_VCC_to_AHU_ARU_Wh > 0.0, 1, 0)
        # CT operation
        q_CT_VCC_to_AHU_ARU_and_VCC_to_SCU_W = q_cw_VCC_to_AHU_ARU_Wh + q_cw_VCC_to_SCU_Wh
        Q_nom_CT_VCC_to_AHU_ARU_and_VCC_to_SCU_W, el_CT_Wh = calc_CT_operation(
            q_CT_VCC_to_AHU_ARU_and_VCC_to_SCU_W)
        # add el costs
        el_total_Wh = el_VCC_to_AHU_ARU_Wh + el_VCC_to_SCU_Wh + el_CT_Wh
        operation_results[4][7] += sum(prices.ELEC_PRICE * el_total_Wh)  # CHF
        operation_results[4][8] += sum(
            calc_emissions_Whyr_to_tonCO2yr(el_total_Wh,
                                            lca.EL_TO_CO2_EQ))  # ton CO2
        # add activation
        cooling_dispatch[4] = {
            'Q_BaseVCC_AS_gen_directload_W': q_chw_VCC_to_AHU_ARU_Wh,
            'Q_BaseVCCHT_AS_gen_directload_W': q_chw_VCC_to_SCU_Wh,
            'E_BaseVCC_req_W': el_VCC_to_AHU_ARU_Wh,
            'E_VCC_HT_req_W': el_VCC_to_SCU_Wh,
            'E_CT_req_W': el_CT_Wh,
            'E_cs_cre_cdata_req_W': el_total_Wh
        }
        # capacity of cooling technologies
        operation_results[4][0] = Qc_nom_AHU_ARU_SCU_W
        operation_results[4][2] = Qc_nom_AHU_ARU_W  # 2: BaseVCC_AS
        operation_results[4][3] = Qc_nom_SCU_W  # 3: VCCHT_AS
        system_COP_list = np.divide(
            q_CT_VCC_to_AHU_ARU_and_VCC_to_SCU_W[None, :],
            el_total_Wh[None, :]).flatten()
        system_COP = np.nansum(
            q_CT_VCC_to_AHU_ARU_and_VCC_to_SCU_W[None, :] *
            system_COP_list) / np.nansum(q_CT_VCC_to_AHU_ARU_and_VCC_to_SCU_W[
                None, :])  # weighted average of the system efficiency
        operation_results[4][9] += system_COP

        # 5: VCC (AHU + ARU) + ACH (SCU) + CT
        print(
            '{building_name} Config 5: Vapor Compression Chillers(LT) -> AHU,ARU & Flate-place SC + Absorption Chillers(HT) -> SCU'
            .format(building_name=building_name))
        # ACH (SCU) operation
        T_hw_FP_ACH_to_SCU_K, \
        el_FP_ACH_to_SCU_Wh, \
        q_cw_FP_ACH_to_SCU_Wh, \
        q_hw_FP_ACH_to_SCU_Wh, \
        q_chw_FP_ACH_to_SCU_Wh = calc_ACH_operation(T_ground_K, T_hw_in_FP_C, T_re_SCU_K, T_sup_SCU_K, chiller_prop,
                                                    mdot_SCU_kgpers, ACH_TYPE_SINGLE)
        ACH_HT_Status = np.where(q_chw_FP_ACH_to_SCU_Wh > 0.0, 1, 0)
        # boiler operation
        q_gas_for_boiler_Wh, \
        Q_nom_boiler_VCC_to_AHU_ARU_and_FP_to_single_ACH_to_SCU_W, \
        q_load_from_boiler_Wh = calc_boiler_operation(Qc_nom_SCU_W, T_hw_FP_ACH_to_SCU_K,
                                                      q_hw_FP_ACH_to_SCU_Wh, q_sc_gen_FP_Wh)
        # CT operation
        q_CT_VCC_to_AHU_ARU_and_single_ACH_to_SCU_Wh = q_cw_VCC_to_AHU_ARU_Wh + q_cw_FP_ACH_to_SCU_Wh
        Q_nom_CT_VCC_to_AHU_ARU_and_FP_to_single_ACH_to_SCU_W, \
        el_CT_Wh = calc_CT_operation(q_CT_VCC_to_AHU_ARU_and_single_ACH_to_SCU_Wh)

        # add electricity costs
        el_total_Wh = el_VCC_to_AHU_ARU_Wh + el_FP_ACH_to_SCU_Wh + el_aux_SC_FP_Wh + el_CT_Wh
        operation_results[5][7] += sum(prices.ELEC_PRICE * el_total_Wh)  # CHF
        operation_results[5][8] += sum(
            calc_emissions_Whyr_to_tonCO2yr(el_total_Wh,
                                            lca.EL_TO_CO2_EQ))  # ton CO2
        # add gas costs
        q_gas_total_Wh = q_gas_for_boiler_Wh
        operation_results[5][7] += sum(prices.NG_PRICE * q_gas_total_Wh)  # CHF
        operation_results[5][8] += sum(
            calc_emissions_Whyr_to_tonCO2yr(q_gas_total_Wh,
                                            lca.NG_TO_CO2_EQ))  # ton CO2
        # add activation
        cooling_dispatch[5] = {
            'Q_BaseVCC_AS_gen_directload_W': q_chw_VCC_to_AHU_ARU_Wh,
            'Q_ACHHT_AS_gen_directload_W': q_chw_FP_ACH_to_SCU_Wh,
            'E_BaseVCC_req_W': el_VCC_to_AHU_ARU_Wh,
            'E_ACHHT_req_W': el_FP_ACH_to_SCU_Wh,
            'E_SC_FP_ACH_req_W': el_aux_SC_FP_Wh,
            'E_CT_req_W': el_CT_Wh,
            'E_cs_cre_cdata_req_W': el_total_Wh,
            'Q_BaseBoiler_NG_req': q_gas_for_boiler_Wh,
        }
        # capacity of cooling technologies
        operation_results[5][0] = Qc_nom_AHU_ARU_SCU_W
        operation_results[5][2] = Qc_nom_AHU_ARU_W  # 2: BaseVCC_AS
        operation_results[5][6] = Qc_nom_SCU_W  # 6: ACHHT_SC_FP
        q_total_load = q_CT_VCC_to_AHU_ARU_and_single_ACH_to_SCU_Wh[
            None, :] + q_gas_for_boiler_Wh[None, :]
        system_COP_list = np.divide(q_total_load,
                                    el_total_Wh[None, :]).flatten()
        system_COP = np.nansum(q_total_load * system_COP_list) / np.nansum(
            q_total_load)  # weighted average of the system efficiency
        operation_results[5][9] += system_COP

    ## Calculate Capex/Opex
    # Initialize arrays
    number_of_configurations = len(operation_results)
    Capex_a_USD = np.zeros((number_of_configurations, 1))
    Capex_total_USD = np.zeros((number_of_configurations, 1))
    Opex_a_fixed_USD = np.zeros((number_of_configurations, 1))
    print('{building_name} Cost calculation...'.format(
        building_name=building_name))
    # 0: DX
    Capex_a_DX_USD, Opex_fixed_DX_USD, Capex_DX_USD = dx.calc_Cinv_DX(
        Qc_nom_AHU_ARU_SCU_W)
    # add costs
    Capex_a_USD[0][0] = Capex_a_DX_USD
    Capex_total_USD[0][0] = Capex_DX_USD
    Opex_a_fixed_USD[0][0] = Opex_fixed_DX_USD
    # 1: VCC + CT
    Capex_a_VCC_USD, Opex_fixed_VCC_USD, Capex_VCC_USD = chiller_vapor_compression.calc_Cinv_VCC(
        Qc_nom_AHU_ARU_SCU_W, locator, 'CH3')
    Capex_a_CT_USD, Opex_fixed_CT_USD, Capex_CT_USD = cooling_tower.calc_Cinv_CT(
        Q_nom_CT_VCC_to_AHU_ARU_SCU_W, locator, 'CT1')
    # add costs
    Capex_a_USD[1][0] = Capex_a_CT_USD + Capex_a_VCC_USD
    Capex_total_USD[1][0] = Capex_CT_USD + Capex_VCC_USD
    Opex_a_fixed_USD[1][0] = Opex_fixed_CT_USD + Opex_fixed_VCC_USD
    # 2: single effect ACH + CT + Boiler + SC_FP
    Capex_a_ACH_USD, Opex_fixed_ACH_USD, Capex_ACH_USD = chiller_absorption.calc_Cinv_ACH(
        Qc_nom_AHU_ARU_SCU_W, supply_systems.Absorption_chiller,
        ACH_TYPE_SINGLE)
    Capex_a_CT_USD, Opex_fixed_CT_USD, Capex_CT_USD = cooling_tower.calc_Cinv_CT(
        Q_nom_CT_FP_to_single_ACH_to_AHU_ARU_SCU_W, locator, 'CT1')
    Capex_a_boiler_USD, Opex_fixed_boiler_USD, Capex_boiler_USD = boiler.calc_Cinv_boiler(
        Q_nom_Boiler_FP_to_single_ACH_to_AHU_ARU_SCU_W, 'BO1',
        boiler_cost_data)
    Capex_a_USD[2][
        0] = Capex_a_CT_USD + Capex_a_ACH_USD + Capex_a_boiler_USD + Capex_a_SC_FP_USD
    Capex_total_USD[2][
        0] = Capex_CT_USD + Capex_ACH_USD + Capex_boiler_USD + Capex_SC_FP_USD
    Opex_a_fixed_USD[2][
        0] = Opex_fixed_CT_USD + Opex_fixed_ACH_USD + Opex_fixed_boiler_USD + Opex_SC_FP_USD
    # 3: double effect ACH + CT + Boiler + SC_ET
    Capex_a_ACH_USD, Opex_fixed_ACH_USD, Capex_ACH_USD = chiller_absorption.calc_Cinv_ACH(
        Qc_nom_AHU_ARU_SCU_W, supply_systems.Absorption_chiller,
        ACH_TYPE_SINGLE)
    Capex_a_CT_USD, Opex_fixed_CT_USD, Capex_CT_USD = cooling_tower.calc_Cinv_CT(
        Q_nom_CT_ET_to_single_ACH_to_AHU_ARU_SCU_W, locator, 'CT1')
    Capex_a_burner_USD, Opex_fixed_burner_USD, Capex_burner_USD = burner.calc_Cinv_burner(
        Q_nom_Burner_ET_to_single_ACH_to_AHU_ARU_SCU_W, boiler_cost_data,
        'BO1')
    Capex_a_USD[3][
        0] = Capex_a_CT_USD + Capex_a_ACH_USD + Capex_a_burner_USD + Capex_a_SC_ET_USD
    Capex_total_USD[3][
        0] = Capex_CT_USD + Capex_ACH_USD + Capex_burner_USD + Capex_SC_ET_USD
    Opex_a_fixed_USD[3][
        0] = Opex_fixed_CT_USD + Opex_fixed_ACH_USD + Opex_fixed_burner_USD + Opex_SC_ET_USD
    # these two configurations are only activated when SCU is in use
    if Qc_nom_SCU_W > 0.0:
        # 4: VCC (AHU + ARU) + VCC (SCU) + CT
        Capex_a_VCC_AA_USD, Opex_VCC_AA_USD, Capex_VCC_AA_USD = chiller_vapor_compression.calc_Cinv_VCC(
            Qc_nom_AHU_ARU_W, locator, 'CH3')
        Capex_a_VCC_S_USD, Opex_VCC_S_USD, Capex_VCC_S_USD = chiller_vapor_compression.calc_Cinv_VCC(
            Qc_nom_SCU_W, locator, 'CH3')
        Capex_a_CT_USD, Opex_fixed_CT_USD, Capex_CT_USD = cooling_tower.calc_Cinv_CT(
            Q_nom_CT_VCC_to_AHU_ARU_and_VCC_to_SCU_W, locator, 'CT1')
        Capex_a_USD[4][
            0] = Capex_a_CT_USD + Capex_a_VCC_AA_USD + Capex_a_VCC_S_USD
        Capex_total_USD[4][
            0] = Capex_CT_USD + Capex_VCC_AA_USD + Capex_VCC_S_USD
        Opex_a_fixed_USD[4][
            0] = Opex_fixed_CT_USD + Opex_VCC_AA_USD + Opex_VCC_S_USD

        # 5: VCC (AHU + ARU) + ACH (SCU) + CT + Boiler + SC_FP
        Capex_a_ACH_S_USD, Opex_fixed_ACH_S_USD, Capex_ACH_S_USD = chiller_absorption.calc_Cinv_ACH(
            Qc_nom_SCU_W, supply_systems.Absorption_chiller, ACH_TYPE_SINGLE)
        Capex_a_CT_USD, Opex_fixed_CT_USD, Capex_CT_USD = cooling_tower.calc_Cinv_CT(
            Q_nom_CT_VCC_to_AHU_ARU_and_FP_to_single_ACH_to_SCU_W, locator,
            'CT1')
        Capex_a_boiler_USD, Opex_fixed_boiler_USD, Capex_boiler_USD = boiler.calc_Cinv_boiler(
            Q_nom_boiler_VCC_to_AHU_ARU_and_FP_to_single_ACH_to_SCU_W, 'BO1',
            boiler_cost_data)
        Capex_a_USD[5][0] = Capex_a_CT_USD + Capex_a_VCC_AA_USD + Capex_a_ACH_S_USD + \
                            Capex_a_SC_FP_USD + Capex_a_boiler_USD
        Capex_total_USD[5][0] = Capex_CT_USD + Capex_VCC_AA_USD + Capex_ACH_S_USD + \
                                Capex_SC_FP_USD + Capex_boiler_USD
        Opex_a_fixed_USD[5][0] = Opex_fixed_CT_USD + Opex_VCC_AA_USD + Opex_fixed_ACH_S_USD + \
                                 Opex_SC_FP_USD + Opex_fixed_boiler_USD
    ## write all results from the configurations into TotalCosts, TotalCO2, TotalPrim
    Opex_a_USD, TAC_USD, TotalCO2, TotalPrim = compile_TAC_CO2_Prim(
        Capex_a_USD, Opex_a_fixed_USD, number_of_configurations,
        operation_results)
    ## Determine the best configuration
    Best, indexBest = rank_results(TAC_USD, TotalCO2, TotalPrim,
                                   number_of_configurations)
    # Save results in csv file
    performance_results = {
        "Nominal heating load": operation_results[:, 0],
        "Capacity_DX_AS_W": operation_results[:, 1],
        "Capacity_BaseVCC_AS_W": operation_results[:, 2],
        "Capacity_VCCHT_AS_W": operation_results[:, 3],
        "Capacity_ACH_SC_FP_W": operation_results[:, 4],
        "Capaticy_ACH_SC_ET_W": operation_results[:, 5],
        "Capacity_ACHHT_FP_W": operation_results[:, 6],
        "Capex_a_USD": Capex_a_USD[:, 0],
        "Capex_total_USD": Capex_total_USD[:, 0],
        "Opex_fixed_USD": Opex_a_fixed_USD[:, 0],
        "Opex_var_USD": operation_results[:, 7],
        "GHG_tonCO2": operation_results[:, 8],
        "TAC_USD": TAC_USD[:, 1],
        "Best configuration": Best[:, 0],
        "system_COP": operation_results[:, 9],
    }
    performance_results_df = pd.DataFrame(performance_results)
    performance_results_df.to_csv(
        locator.get_optimization_decentralized_folder_building_result_cooling(
            building_name),
        index=False)
    # save activation for the best supply system configuration
    best_activation_df = pd.DataFrame.from_dict(cooling_dispatch[indexBest])  #
    best_activation_df.to_csv(
        locator.
        get_optimization_decentralized_folder_building_cooling_activation(
            building_name),
        index=False)
def addCosts(buildList, locator, master_to_slave_vars, Q_uncovered_design_W,
             Q_uncovered_annual_W, solar_features, network_features, gv,
             config, prices, lca):
    """
    Computes additional costs / GHG emisions / primary energy needs
    for the individual
    addCosts = additional costs
    addCO2 = GHG emissions
    addPrm = primary energy needs
    :param DHN_barcode: parameter indicating if the building is connected or not
    :param buildList: list of buildings in the district
    :param locator: input locator set to scenario
    :param master_to_slave_vars: class containing the features of a specific individual
    :param Q_uncovered_design_W: hourly max of the heating uncovered demand
    :param Q_uncovered_annual_W: total heating uncovered
    :param solar_features: solar features
    :param network_features: network features
    :param gv: global variables
    :type indCombi: string
    :type buildList: list
    :type locator: string
    :type master_to_slave_vars: class
    :type Q_uncovered_design_W: float
    :type Q_uncovered_annual_W: float
    :type solar_features: class
    :type network_features: class
    :type gv: class

    :return: returns the objectives addCosts, addCO2, addPrim
    :rtype: tuple
    """
    DHN_barcode = master_to_slave_vars.DHN_barcode
    DCN_barcode = master_to_slave_vars.DCN_barcode
    addcosts_Capex_a_USD = 0
    addcosts_Opex_fixed_USD = 0
    addcosts_Capex_USD = 0
    addCO2 = 0
    addPrim = 0
    nBuildinNtw = 0

    # Add the features from the disconnected buildings
    CostDiscBuild = 0
    CO2DiscBuild = 0
    PrimDiscBuild = 0
    Capex_Disconnected = 0
    Opex_Disconnected = 0
    Capex_a_furnace_USD = 0
    Capex_a_CHP_USD = 0
    Capex_a_Boiler_USD = 0
    Capex_a_Boiler_peak_USD = 0
    Capex_a_Lake_USD = 0
    Capex_a_Sewage_USD = 0
    Capex_a_GHP_USD = 0
    Capex_a_PV_USD = 0
    Capex_a_SC_ET_USD = 0
    Capex_a_SC_FP_USD = 0
    Capex_a_PVT_USD = 0
    Capex_a_Boiler_backup_USD = 0
    Capex_a_HEX = 0
    Capex_a_storage_HP = 0
    Capex_a_HP_storage_USD = 0
    Opex_fixed_SC = 0
    Opex_fixed_PVT_USD = 0
    Opex_fixed_HP_PVT_USD = 0
    Opex_fixed_furnace_USD = 0
    Opex_fixed_CHP_USD = 0
    Opex_fixed_Boiler_USD = 0
    Opex_fixed_Boiler_peak_USD = 0
    Opex_fixed_Boiler_backup_USD = 0
    Opex_fixed_Lake_USD = 0
    Opex_fixed_wasteserver_HEX_USD = 0
    Opex_fixed_wasteserver_HP_USD = 0
    Opex_fixed_PV_USD = 0
    Opex_fixed_GHP_USD = 0
    Opex_fixed_storage_USD = 0
    Opex_fixed_Sewage_USD = 0
    Opex_fixed_HP_storage_USD = 0
    StorageInvC = 0
    NetworkCost_a_USD = 0
    SubstHEXCost_capex = 0
    SubstHEXCost_opex = 0
    PVTHEXCost_Capex = 0
    PVTHEXCost_Opex = 0
    SCHEXCost_Capex = 0
    SCHEXCost_Opex = 0
    pumpCosts = 0
    GasConnectionInvCost = 0
    cost_PV_disconnected = 0
    CO2_PV_disconnected = 0
    Eprim_PV_disconnected = 0
    Capex_furnace_USD = 0
    Capex_CHP_USD = 0
    Capex_Boiler_USD = 0
    Capex_Boiler_peak_USD = 0
    Capex_Lake_USD = 0
    Capex_Sewage_USD = 0
    Capex_GHP = 0
    Capex_PV_USD = 0
    Capex_SC = 0
    Capex_PVT_USD = 0
    Capex_Boiler_backup_USD = 0
    Capex_HEX = 0
    Capex_storage_HP = 0
    Capex_HP_storage = 0
    Capex_SC_ET_USD = 0
    Capex_SC_FP_USD = 0
    Capex_PVT_USD = 0
    Capex_Boiler_backup_USD = 0
    Capex_HP_storage_USD = 0
    Capex_storage_HP = 0
    Capex_CHP_USD = 0
    Capex_furnace_USD = 0
    Capex_Boiler_USD = 0
    Capex_Boiler_peak_USD = 0
    Capex_Lake_USD = 0
    Capex_Sewage_USD = 0
    Capex_pump_USD = 0

    if config.district_heating_network:
        for (index, building_name) in zip(DHN_barcode, buildList):
            if index == "0":
                df = pd.read_csv(
                    locator.
                    get_optimization_decentralized_folder_building_result_heating(
                        building_name))
                dfBest = df[df["Best configuration"] == 1]
                CostDiscBuild += dfBest["Total Costs [CHF]"].iloc[0]  # [CHF]
                CO2DiscBuild += dfBest["CO2 Emissions [kgCO2-eq]"].iloc[
                    0]  # [kg CO2]
                PrimDiscBuild += dfBest[
                    "Primary Energy Needs [MJoil-eq]"].iloc[0]  # [MJ-oil-eq]
                Capex_Disconnected += dfBest[
                    "Annualized Investment Costs [CHF]"].iloc[0]
                Opex_Disconnected += dfBest["Operation Costs [CHF]"].iloc[0]
            else:
                nBuildinNtw += 1
    if config.district_cooling_network:
        PV_barcode = ''
        for (index, building_name) in zip(DCN_barcode, buildList):
            if index == "0":  # choose the best decentralized configuration
                df = pd.read_csv(
                    locator.
                    get_optimization_decentralized_folder_building_result_cooling(
                        building_name, configuration='AHU_ARU_SCU'))
                dfBest = df[df["Best configuration"] == 1]
                CostDiscBuild += dfBest["Total Costs [CHF]"].iloc[0]  # [CHF]
                CO2DiscBuild += dfBest["CO2 Emissions [kgCO2-eq]"].iloc[
                    0]  # [kg CO2]
                PrimDiscBuild += dfBest[
                    "Primary Energy Needs [MJoil-eq]"].iloc[0]  # [MJ-oil-eq]
                Capex_Disconnected += dfBest[
                    "Annualized Investment Costs [CHF]"].iloc[0]
                Opex_Disconnected += dfBest["Operation Costs [CHF]"].iloc[0]
                to_PV = 1
                if dfBest["single effect ACH to AHU_ARU_SCU Share (FP)"].iloc[
                        0] == 1:
                    to_PV = 0
                if dfBest["single effect ACH to AHU_ARU_SCU Share (ET)"].iloc[
                        0] == 1:
                    to_PV = 0
                if dfBest["single effect ACH to SCU Share (FP)"].iloc[0] == 1:
                    to_PV = 0

            else:  # adding costs for buildings in which the centralized plant provides a part of the load requirements
                DCN_unit_configuration = master_to_slave_vars.DCN_supplyunits
                if DCN_unit_configuration == 1:  # corresponds to AHU in the central plant, so remaining load need to be provided by decentralized plant
                    decentralized_configuration = 'ARU_SCU'
                    df = pd.read_csv(
                        locator.
                        get_optimization_decentralized_folder_building_result_cooling(
                            building_name, decentralized_configuration))
                    dfBest = df[df["Best configuration"] == 1]
                    CostDiscBuild += dfBest["Total Costs [CHF]"].iloc[
                        0]  # [CHF]
                    CO2DiscBuild += dfBest["CO2 Emissions [kgCO2-eq]"].iloc[
                        0]  # [kg CO2]
                    PrimDiscBuild += dfBest[
                        "Primary Energy Needs [MJoil-eq]"].iloc[
                            0]  # [MJ-oil-eq]
                    Capex_Disconnected += dfBest[
                        "Annualized Investment Costs [CHF]"].iloc[0]
                    Opex_Disconnected += dfBest["Operation Costs [CHF]"].iloc[
                        0]
                    to_PV = 1
                    if dfBest["single effect ACH to ARU_SCU Share (FP)"].iloc[
                            0] == 1:
                        to_PV = 0
                    if dfBest["single effect ACH to ARU_SCU Share (ET)"].iloc[
                            0] == 1:
                        to_PV = 0

                if DCN_unit_configuration == 2:  # corresponds to ARU in the central plant, so remaining load need to be provided by decentralized plant
                    decentralized_configuration = 'AHU_SCU'
                    df = pd.read_csv(
                        locator.
                        get_optimization_decentralized_folder_building_result_cooling(
                            building_name, decentralized_configuration))
                    dfBest = df[df["Best configuration"] == 1]
                    CostDiscBuild += dfBest["Total Costs [CHF]"].iloc[
                        0]  # [CHF]
                    CO2DiscBuild += dfBest["CO2 Emissions [kgCO2-eq]"].iloc[
                        0]  # [kg CO2]
                    PrimDiscBuild += dfBest[
                        "Primary Energy Needs [MJoil-eq]"].iloc[
                            0]  # [MJ-oil-eq]
                    Capex_Disconnected += dfBest[
                        "Annualized Investment Costs [CHF]"].iloc[0]
                    Opex_Disconnected += dfBest["Operation Costs [CHF]"].iloc[
                        0]
                    to_PV = 1
                    if dfBest["single effect ACH to AHU_SCU Share (FP)"].iloc[
                            0] == 1:
                        to_PV = 0
                    if dfBest["single effect ACH to AHU_SCU Share (ET)"].iloc[
                            0] == 1:
                        to_PV = 0

                if DCN_unit_configuration == 3:  # corresponds to SCU in the central plant, so remaining load need to be provided by decentralized plant
                    decentralized_configuration = 'AHU_ARU'
                    df = pd.read_csv(
                        locator.
                        get_optimization_decentralized_folder_building_result_cooling(
                            building_name, decentralized_configuration))
                    dfBest = df[df["Best configuration"] == 1]
                    CostDiscBuild += dfBest["Total Costs [CHF]"].iloc[
                        0]  # [CHF]
                    CO2DiscBuild += dfBest["CO2 Emissions [kgCO2-eq]"].iloc[
                        0]  # [kg CO2]
                    PrimDiscBuild += dfBest[
                        "Primary Energy Needs [MJoil-eq]"].iloc[
                            0]  # [MJ-oil-eq]
                    Capex_Disconnected += dfBest[
                        "Annualized Investment Costs [CHF]"].iloc[0]
                    Opex_Disconnected += dfBest["Operation Costs [CHF]"].iloc[
                        0]
                    to_PV = 1
                    if dfBest["single effect ACH to AHU_ARU Share (FP)"].iloc[
                            0] == 1:
                        to_PV = 0
                    if dfBest["single effect ACH to AHU_ARU Share (ET)"].iloc[
                            0] == 1:
                        to_PV = 0

                if DCN_unit_configuration == 4:  # corresponds to AHU + ARU in the central plant, so remaining load need to be provided by decentralized plant
                    decentralized_configuration = 'SCU'
                    df = pd.read_csv(
                        locator.
                        get_optimization_decentralized_folder_building_result_cooling(
                            building_name, decentralized_configuration))
                    dfBest = df[df["Best configuration"] == 1]
                    CostDiscBuild += dfBest["Total Costs [CHF]"].iloc[
                        0]  # [CHF]
                    CO2DiscBuild += dfBest["CO2 Emissions [kgCO2-eq]"].iloc[
                        0]  # [kg CO2]
                    PrimDiscBuild += dfBest[
                        "Primary Energy Needs [MJoil-eq]"].iloc[
                            0]  # [MJ-oil-eq]
                    Capex_Disconnected += dfBest[
                        "Annualized Investment Costs [CHF]"].iloc[0]
                    Opex_Disconnected += dfBest["Operation Costs [CHF]"].iloc[
                        0]
                    to_PV = 1
                    if dfBest["single effect ACH to SCU Share (FP)"].iloc[
                            0] == 1:
                        to_PV = 0
                    if dfBest["single effect ACH to SCU Share (ET)"].iloc[
                            0] == 1:
                        to_PV = 0

                if DCN_unit_configuration == 5:  # corresponds to AHU + SCU in the central plant, so remaining load need to be provided by decentralized plant
                    decentralized_configuration = 'ARU'
                    df = pd.read_csv(
                        locator.
                        get_optimization_decentralized_folder_building_result_cooling(
                            building_name, decentralized_configuration))
                    dfBest = df[df["Best configuration"] == 1]
                    CostDiscBuild += dfBest["Total Costs [CHF]"].iloc[
                        0]  # [CHF]
                    CO2DiscBuild += dfBest["CO2 Emissions [kgCO2-eq]"].iloc[
                        0]  # [kg CO2]
                    PrimDiscBuild += dfBest[
                        "Primary Energy Needs [MJoil-eq]"].iloc[
                            0]  # [MJ-oil-eq]
                    Capex_Disconnected += dfBest[
                        "Annualized Investment Costs [CHF]"].iloc[0]
                    Opex_Disconnected += dfBest["Operation Costs [CHF]"].iloc[
                        0]
                    to_PV = 1
                    if dfBest["single effect ACH to ARU Share (FP)"].iloc[
                            0] == 1:
                        to_PV = 0
                    if dfBest["single effect ACH to ARU Share (ET)"].iloc[
                            0] == 1:
                        to_PV = 0

                if DCN_unit_configuration == 6:  # corresponds to ARU + SCU in the central plant, so remaining load need to be provided by decentralized plant
                    decentralized_configuration = 'AHU'
                    df = pd.read_csv(
                        locator.
                        get_optimization_decentralized_folder_building_result_cooling(
                            building_name, decentralized_configuration))
                    dfBest = df[df["Best configuration"] == 1]
                    CostDiscBuild += dfBest["Total Costs [CHF]"].iloc[
                        0]  # [CHF]
                    CO2DiscBuild += dfBest["CO2 Emissions [kgCO2-eq]"].iloc[
                        0]  # [kg CO2]
                    PrimDiscBuild += dfBest[
                        "Primary Energy Needs [MJoil-eq]"].iloc[
                            0]  # [MJ-oil-eq]
                    Capex_Disconnected += dfBest[
                        "Annualized Investment Costs [CHF]"].iloc[0]
                    Opex_Disconnected += dfBest["Operation Costs [CHF]"].iloc[
                        0]
                    to_PV = 1
                    if dfBest["single effect ACH to AHU Share (FP)"].iloc[
                            0] == 1:
                        to_PV = 0
                    if dfBest["single effect ACH to AHU Share (ET)"].iloc[
                            0] == 1:
                        to_PV = 0

                if DCN_unit_configuration == 7:  # corresponds to AHU + ARU + SCU from central plant
                    to_PV = 1

                nBuildinNtw += 1
            PV_barcode = PV_barcode + str(to_PV)

    addcosts_Capex_a_USD += CostDiscBuild
    addCO2 += CO2DiscBuild
    addPrim += PrimDiscBuild

    # Solar technologies

    PV_installed_area_m2 = master_to_slave_vars.SOLAR_PART_PV * solar_features.A_PV_m2  # kW
    Capex_a_PV_USD, Opex_fixed_PV_USD, Capex_PV_USD = pv.calc_Cinv_pv(
        PV_installed_area_m2, locator, config)
    addcosts_Capex_a_USD += Capex_a_PV_USD
    addcosts_Opex_fixed_USD += Opex_fixed_PV_USD
    addcosts_Capex_USD += Capex_PV_USD

    SC_ET_area_m2 = master_to_slave_vars.SOLAR_PART_SC_ET * solar_features.A_SC_ET_m2
    Capex_a_SC_ET_USD, Opex_fixed_SC_ET_USD, Capex_SC_ET_USD = stc.calc_Cinv_SC(
        SC_ET_area_m2, locator, config, 'ET')
    addcosts_Capex_a_USD += Capex_a_SC_ET_USD
    addcosts_Opex_fixed_USD += Opex_fixed_SC_ET_USD
    addcosts_Capex_USD += Capex_SC_ET_USD

    SC_FP_area_m2 = master_to_slave_vars.SOLAR_PART_SC_FP * solar_features.A_SC_FP_m2
    Capex_a_SC_FP_USD, Opex_fixed_SC_FP_USD, Capex_SC_FP_USD = stc.calc_Cinv_SC(
        SC_FP_area_m2, locator, config, 'FP')
    addcosts_Capex_a_USD += Capex_a_SC_FP_USD
    addcosts_Opex_fixed_USD += Opex_fixed_SC_FP_USD
    addcosts_Capex_USD += Capex_SC_FP_USD

    PVT_peak_kW = master_to_slave_vars.SOLAR_PART_PVT * solar_features.A_PVT_m2 * N_PVT  # kW
    Capex_a_PVT_USD, Opex_fixed_PVT_USD, Capex_PVT_USD = pvt.calc_Cinv_PVT(
        PVT_peak_kW, locator, config)
    addcosts_Capex_a_USD += Capex_a_PVT_USD
    addcosts_Opex_fixed_USD += Opex_fixed_PVT_USD
    addcosts_Capex_USD += Capex_PVT_USD

    # Add the features for the distribution

    if DHN_barcode.count("1") > 0 and config.district_heating_network:
        os.chdir(
            locator.get_optimization_slave_results_folder(
                master_to_slave_vars.generation_number))
        # Add the investment costs of the energy systems
        # Furnace
        if master_to_slave_vars.Furnace_on == 1:
            P_design_W = master_to_slave_vars.Furnace_Q_max_W

            fNameSlavePP = locator.get_optimization_slave_heating_activation_pattern_heating(
                master_to_slave_vars.configKey,
                master_to_slave_vars.individual_number,
                master_to_slave_vars.generation_number)
            dfFurnace = pd.read_csv(fNameSlavePP, usecols=["Q_Furnace_W"])
            arrayFurnace_W = np.array(dfFurnace)

            Q_annual_W = 0
            for i in range(int(np.shape(arrayFurnace_W)[0])):
                Q_annual_W += arrayFurnace_W[i][0]

            Capex_a_furnace_USD, Opex_fixed_furnace_USD, Capex_furnace_USD = furnace.calc_Cinv_furnace(
                P_design_W, Q_annual_W, config, locator, 'FU1')
            addcosts_Capex_a_USD += Capex_a_furnace_USD
            addcosts_Opex_fixed_USD += Opex_fixed_furnace_USD
            addcosts_Capex_USD += Capex_furnace_USD

        # CC
        if master_to_slave_vars.CC_on == 1:
            CC_size_W = master_to_slave_vars.CC_GT_SIZE_W
            Capex_a_CHP_USD, Opex_fixed_CHP_USD, Capex_CHP_USD = chp.calc_Cinv_CCGT(
                CC_size_W, locator, config)
            addcosts_Capex_a_USD += Capex_a_CHP_USD
            addcosts_Opex_fixed_USD += Opex_fixed_CHP_USD
            addcosts_Capex_USD += Capex_CHP_USD

        # Boiler Base
        if master_to_slave_vars.Boiler_on == 1:
            Q_design_W = master_to_slave_vars.Boiler_Q_max_W

            fNameSlavePP = locator.get_optimization_slave_heating_activation_pattern(
                master_to_slave_vars.individual_number,
                master_to_slave_vars.generation_number)
            dfBoilerBase = pd.read_csv(fNameSlavePP,
                                       usecols=["Q_BaseBoiler_W"])
            arrayBoilerBase_W = np.array(dfBoilerBase)

            Q_annual_W = 0
            for i in range(int(np.shape(arrayBoilerBase_W)[0])):
                Q_annual_W += arrayBoilerBase_W[i][0]

            Capex_a_Boiler_USD, Opex_fixed_Boiler_USD, Capex_Boiler_USD = boiler.calc_Cinv_boiler(
                Q_design_W, locator, config, 'BO1')
            addcosts_Capex_a_USD += Capex_a_Boiler_USD
            addcosts_Opex_fixed_USD += Opex_fixed_Boiler_USD
            addcosts_Capex_USD += Capex_Boiler_USD

        # Boiler Peak
        if master_to_slave_vars.BoilerPeak_on == 1:
            Q_design_W = master_to_slave_vars.BoilerPeak_Q_max_W

            fNameSlavePP = locator.get_optimization_slave_heating_activation_pattern(
                master_to_slave_vars.individual_number,
                master_to_slave_vars.generation_number)
            dfBoilerPeak = pd.read_csv(fNameSlavePP,
                                       usecols=["Q_PeakBoiler_W"])
            arrayBoilerPeak_W = np.array(dfBoilerPeak)

            Q_annual_W = 0
            for i in range(int(np.shape(arrayBoilerPeak_W)[0])):
                Q_annual_W += arrayBoilerPeak_W[i][0]
            Capex_a_Boiler_peak_USD, Opex_fixed_Boiler_peak_USD, Capex_Boiler_peak_USD = boiler.calc_Cinv_boiler(
                Q_design_W, locator, config, 'BO1')
            addcosts_Capex_a_USD += Capex_a_Boiler_peak_USD
            addcosts_Opex_fixed_USD += Opex_fixed_Boiler_peak_USD
            addcosts_Capex_USD += Capex_Boiler_peak_USD

        # HP Lake
        if master_to_slave_vars.HP_Lake_on == 1:
            HP_Size_W = master_to_slave_vars.HPLake_maxSize_W
            Capex_a_Lake_USD, Opex_fixed_Lake_USD, Capex_Lake_USD = hp.calc_Cinv_HP(
                HP_Size_W, locator, config, 'HP2')
            addcosts_Capex_a_USD += Capex_a_Lake_USD
            addcosts_Opex_fixed_USD += Opex_fixed_Lake_USD
            addcosts_Capex_USD += Capex_Lake_USD

        # HP Sewage
        if master_to_slave_vars.HP_Sew_on == 1:
            HP_Size_W = master_to_slave_vars.HPSew_maxSize_W
            Capex_a_Sewage_USD, Opex_fixed_Sewage_USD, Capex_Sewage_USD = hp.calc_Cinv_HP(
                HP_Size_W, locator, config, 'HP2')
            addcosts_Capex_a_USD += Capex_a_Sewage_USD
            addcosts_Opex_fixed_USD += Opex_fixed_Sewage_USD
            addcosts_Capex_USD += Capex_Sewage_USD

        # GHP
        if master_to_slave_vars.GHP_on == 1:
            fNameSlavePP = locator.get_optimization_slave_electricity_activation_pattern_heating(
                master_to_slave_vars.individual_number,
                master_to_slave_vars.generation_number)
            dfGHP = pd.read_csv(fNameSlavePP, usecols=["E_used_GHP_W"])
            arrayGHP_W = np.array(dfGHP)

            GHP_Enom_W = np.amax(arrayGHP_W)
            Capex_a_GHP_USD, Opex_fixed_GHP_USD, Capex_GHP_USD = hp.calc_Cinv_GHP(
                GHP_Enom_W, locator, config)
            addcosts_Capex_a_USD += Capex_a_GHP_USD * prices.EURO_TO_CHF
            addcosts_Opex_fixed_USD += Opex_fixed_GHP_USD * prices.EURO_TO_CHF
            addcosts_Capex_USD += Capex_GHP_USD

        # Back-up boiler
        Capex_a_Boiler_backup_USD, Opex_fixed_Boiler_backup_USD, Capex_Boiler_backup_USD = boiler.calc_Cinv_boiler(
            Q_uncovered_design_W, locator, config, 'BO1')
        addcosts_Capex_a_USD += Capex_a_Boiler_backup_USD
        addcosts_Opex_fixed_USD += Opex_fixed_Boiler_backup_USD
        addcosts_Capex_USD += Capex_Boiler_backup_USD
        master_to_slave_vars.BoilerBackup_Q_max_W = Q_uncovered_design_W

        # Hex and HP for Heat recovery
        if master_to_slave_vars.WasteServersHeatRecovery == 1:
            df = pd.read_csv(os.path.join(
                locator.get_optimization_network_results_folder(),
                master_to_slave_vars.network_data_file_heating),
                             usecols=["Qcdata_netw_total_kWh"])
            array = np.array(df)
            Q_HEX_max_kWh = np.amax(array)
            Capex_a_wasteserver_HEX_USD, Opex_fixed_wasteserver_HEX_USD, Capex_wasteserver_HEX_USD = hex.calc_Cinv_HEX(
                Q_HEX_max_kWh, locator, config, 'HEX1')
            addcosts_Capex_a_USD += (Capex_a_wasteserver_HEX_USD)
            addcosts_Opex_fixed_USD += Opex_fixed_wasteserver_HEX_USD
            addcosts_Capex_USD += Capex_wasteserver_HEX_USD

            df = pd.read_csv(
                locator.get_optimization_slave_storage_operation_data(
                    master_to_slave_vars.individual_number,
                    master_to_slave_vars.generation_number),
                usecols=["HPServerHeatDesignArray_kWh"])
            array = np.array(df)
            Q_HP_max_kWh = np.amax(array)
            Capex_a_wasteserver_HP_USD, Opex_fixed_wasteserver_HP_USD, Capex_wasteserver_HP_USD = hp.calc_Cinv_HP(
                Q_HP_max_kWh, locator, config, 'HP2')
            addcosts_Capex_a_USD += (Capex_a_wasteserver_HP_USD)
            addcosts_Opex_fixed_USD += Opex_fixed_wasteserver_HP_USD
            addcosts_Capex_USD += Capex_wasteserver_HP_USD

        # Heat pump from solar to DH
        df = pd.read_csv(
            locator.get_optimization_slave_storage_operation_data(
                master_to_slave_vars.individual_number,
                master_to_slave_vars.generation_number),
            usecols=["HPScDesignArray_Wh", "HPpvt_designArray_Wh"])
        array = np.array(df)
        Q_HP_max_PVT_wh = np.amax(array[:, 1])
        Q_HP_max_SC_Wh = np.amax(array[:, 0])
        Capex_a_HP_PVT_USD, Opex_fixed_HP_PVT_USD, Capex_HP_PVT_USD = hp.calc_Cinv_HP(
            Q_HP_max_PVT_wh, locator, config, 'HP2')
        Capex_a_storage_HP += (Capex_a_HP_PVT_USD)
        addcosts_Opex_fixed_USD += Opex_fixed_HP_PVT_USD
        addcosts_Capex_USD += Capex_HP_PVT_USD

        Capex_a_HP_SC_USD, Opex_fixed_HP_SC_USD, Capex_HP_SC_USD = hp.calc_Cinv_HP(
            Q_HP_max_SC_Wh, locator, config, 'HP2')
        Capex_a_storage_HP += (Capex_a_HP_SC_USD)
        addcosts_Opex_fixed_USD += Opex_fixed_HP_SC_USD
        addcosts_Capex_USD += Capex_HP_SC_USD

        # HP for storage operation for charging from solar and discharging to DH
        df = pd.read_csv(locator.get_optimization_slave_storage_operation_data(
            master_to_slave_vars.individual_number,
            master_to_slave_vars.generation_number),
                         usecols=[
                             "E_aux_ch_W", "E_aux_dech_W",
                             "Q_from_storage_used_W", "Q_to_storage_W"
                         ])
        array = np.array(df)
        Q_HP_max_storage_W = 0
        for i in range(DAYS_IN_YEAR * HOURS_IN_DAY):
            if array[i][0] > 0:
                Q_HP_max_storage_W = max(Q_HP_max_storage_W,
                                         array[i][3] + array[i][0])
            elif array[i][1] > 0:
                Q_HP_max_storage_W = max(Q_HP_max_storage_W,
                                         array[i][2] + array[i][1])

        Capex_a_HP_storage_USD, Opex_fixed_HP_storage_USD, Capex_HP_storage_USD = hp.calc_Cinv_HP(
            Q_HP_max_storage_W, locator, config, 'HP2')
        addcosts_Capex_a_USD += (Capex_a_HP_storage_USD)
        addcosts_Opex_fixed_USD += Opex_fixed_HP_storage_USD
        addcosts_Capex_USD += Capex_HP_storage_USD

        # Storage
        df = pd.read_csv(locator.get_optimization_slave_storage_operation_data(
            master_to_slave_vars.individual_number,
            master_to_slave_vars.generation_number),
                         usecols=["Storage_Size_m3"],
                         nrows=1)
        StorageVol_m3 = np.array(df)[0][0]
        Capex_a_storage_USD, Opex_fixed_storage_USD, Capex_storage_USD = storage.calc_Cinv_storage(
            StorageVol_m3, locator, config, 'TES2')
        addcosts_Capex_a_USD += Capex_a_storage_USD
        addcosts_Opex_fixed_USD += Opex_fixed_storage_USD
        addcosts_Capex_USD += Capex_storage_USD

        # Costs from distribution configuration
        if gv.ZernezFlag == 1:
            NetworkCost_a_USD, NetworkCost_USD = network.calc_Cinv_network_linear(
                gv.NetworkLengthZernez, gv)
            NetworkCost_a_USD = NetworkCost_a_USD * nBuildinNtw / len(
                buildList)
            NetworkCost_USD = NetworkCost_USD * nBuildinNtw / len(buildList)
        else:
            NetworkCost_USD = network_features.pipesCosts_DHN_USD
            NetworkCost_USD = NetworkCost_USD * nBuildinNtw / len(buildList)
            NetworkCost_a_USD = NetworkCost_USD * gv.PipeInterestRate * (
                1 + gv.PipeInterestRate)**gv.PipeLifeTime / (
                    (1 + gv.PipeInterestRate)**gv.PipeLifeTime - 1)
        addcosts_Capex_a_USD += NetworkCost_a_USD
        addcosts_Capex_USD += NetworkCost_USD

        # HEX (1 per building in ntw)
        for (index, building_name) in zip(DHN_barcode, buildList):
            if index == "1":
                df = pd.read_csv(
                    locator.get_optimization_substations_results_file(
                        building_name),
                    usecols=["Q_dhw_W", "Q_heating_W"])
                subsArray = np.array(df)

                Q_max_W = np.amax(subsArray[:, 0] + subsArray[:, 1])
                Capex_a_HEX_building_USD, Opex_fixed_HEX_building_USD, Capex_HEX_building_USD = hex.calc_Cinv_HEX(
                    Q_max_W, locator, config, 'HEX1')
                addcosts_Capex_a_USD += Capex_a_HEX_building_USD
                addcosts_Opex_fixed_USD += Opex_fixed_HEX_building_USD
                addcosts_Capex_USD += Capex_HEX_building_USD

        # HEX for solar
        roof_area_m2 = np.array(
            pd.read_csv(locator.get_total_demand(), usecols=["Aroof_m2"]))

        areaAvail = 0
        for i in range(len(DHN_barcode)):
            index = DHN_barcode[i]
            if index == "1":
                areaAvail += roof_area_m2[i][0]

        for i in range(len(DHN_barcode)):
            index = DHN_barcode[i]
            if index == "1":
                share = roof_area_m2[i][0] / areaAvail
                #print share, "solar area share", buildList[i]

                Q_max_SC_ET_Wh = solar_features.Q_nom_SC_ET_Wh * master_to_slave_vars.SOLAR_PART_SC_ET * share
                Capex_a_HEX_SC_ET_USD, Opex_fixed_HEX_SC_ET_USD, Capex_HEX_SC_ET_USD = hex.calc_Cinv_HEX(
                    Q_max_SC_ET_Wh, locator, config, 'HEX1')
                addcosts_Capex_a_USD += Capex_a_HEX_SC_ET_USD
                addcosts_Opex_fixed_USD += Opex_fixed_HEX_SC_ET_USD
                addcosts_Capex_USD += Capex_HEX_SC_ET_USD

                Q_max_SC_FP_Wh = solar_features.Q_nom_SC_FP_Wh * master_to_slave_vars.SOLAR_PART_SC_FP * share
                Capex_a_HEX_SC_FP_USD, Opex_fixed_HEX_SC_FP_USD, Capex_HEX_SC_FP_USD = hex.calc_Cinv_HEX(
                    Q_max_SC_FP_Wh, locator, config, 'HEX1')
                addcosts_Capex_a_USD += Capex_a_HEX_SC_FP_USD
                addcosts_Opex_fixed_USD += Opex_fixed_HEX_SC_FP_USD
                addcosts_Capex_USD += Capex_HEX_SC_FP_USD

                Q_max_PVT_Wh = solar_features.Q_nom_PVT_Wh * master_to_slave_vars.SOLAR_PART_PVT * share
                Capex_a_HEX_PVT_USD, Opex_fixed_HEX_PVT_USD, Capex_HEX_PVT_USD = hex.calc_Cinv_HEX(
                    Q_max_PVT_Wh, locator, config, 'HEX1')
                addcosts_Capex_a_USD += Capex_a_HEX_PVT_USD
                addcosts_Opex_fixed_USD += Opex_fixed_HEX_PVT_USD
                addcosts_Capex_USD += Capex_HEX_PVT_USD

    # Pump operation costs
    Capex_a_pump_USD, Opex_fixed_pump_USD, Opex_var_pump_USD, Capex_pump_USD = pumps.calc_Ctot_pump(
        master_to_slave_vars, network_features, gv, locator, lca, config)
    addcosts_Capex_a_USD += Capex_a_pump_USD
    addcosts_Opex_fixed_USD += Opex_fixed_pump_USD
    addcosts_Capex_USD += Capex_pump_USD

    # import gas consumption data from:
    if DHN_barcode.count("1") > 0 and config.district_heating_network:
        # import gas consumption data from:
        EgasPrimaryDataframe_W = pd.read_csv(
            locator.get_optimization_slave_natural_gas_imports(
                master_to_slave_vars.individual_number,
                master_to_slave_vars.generation_number))
        E_gas_primary_peak_power_W = np.amax(
            EgasPrimaryDataframe_W['NG_total_W'])
        GasConnectionInvCost = ngas.calc_Cinv_gas(E_gas_primary_peak_power_W,
                                                  gv)
    elif DCN_barcode.count("1") > 0 and config.district_cooling_network:
        EgasPrimaryDataframe_W = pd.read_csv(
            locator.get_optimization_slave_natural_gas_imports(
                master_to_slave_vars.individual_number,
                master_to_slave_vars.generation_number))
        E_gas_primary_peak_power_W = np.amax(
            EgasPrimaryDataframe_W['NG_total_W'])
        GasConnectionInvCost = ngas.calc_Cinv_gas(E_gas_primary_peak_power_W,
                                                  gv)
    else:
        GasConnectionInvCost = 0.0

    addcosts_Capex_a_USD += GasConnectionInvCost
    # Save data
    results = pd.DataFrame({
        "Capex_a_SC_ET_USD": [Capex_a_SC_ET_USD],
        "Capex_a_SC_FP_USD": [Capex_a_SC_FP_USD],
        "Opex_fixed_SC": [Opex_fixed_SC],
        "Capex_a_PVT": [Capex_a_PVT_USD],
        "Opex_fixed_PVT": [Opex_fixed_PVT_USD],
        "Capex_a_Boiler_backup": [Capex_a_Boiler_backup_USD],
        "Opex_fixed_Boiler_backup": [Opex_fixed_Boiler_backup_USD],
        "Capex_a_storage_HEX": [Capex_a_HP_storage_USD],
        "Opex_fixed_storage_HEX": [Opex_fixed_HP_storage_USD],
        "Capex_a_storage_HP": [Capex_a_storage_HP],
        "Capex_a_CHP": [Capex_a_CHP_USD],
        "Opex_fixed_CHP": [Opex_fixed_CHP_USD],
        "StorageInvC": [StorageInvC],
        "StorageCostSum": [StorageInvC + Capex_a_storage_HP + Capex_a_HEX],
        "NetworkCost": [NetworkCost_a_USD],
        "SubstHEXCost": [SubstHEXCost_capex],
        "DHNInvestCost": [addcosts_Capex_a_USD - CostDiscBuild],
        "PVTHEXCost_Capex": [PVTHEXCost_Capex],
        "CostDiscBuild": [CostDiscBuild],
        "CO2DiscBuild": [CO2DiscBuild],
        "PrimDiscBuild": [PrimDiscBuild],
        "Capex_a_furnace": [Capex_a_furnace_USD],
        "Opex_fixed_furnace": [Opex_fixed_furnace_USD],
        "Capex_a_Boiler": [Capex_a_Boiler_USD],
        "Opex_fixed_Boiler": [Opex_fixed_Boiler_USD],
        "Capex_a_Boiler_peak": [Capex_a_Boiler_peak_USD],
        "Opex_fixed_Boiler_peak": [Opex_fixed_Boiler_peak_USD],
        "Capex_Disconnected": [Capex_Disconnected],
        "Opex_Disconnected": [Opex_Disconnected],
        "Capex_a_Lake": [Capex_a_Lake_USD],
        "Opex_fixed_Lake": [Opex_fixed_Lake_USD],
        "Capex_a_Sewage": [Capex_a_Sewage_USD],
        "Opex_fixed_Sewage": [Opex_fixed_Sewage_USD],
        "SCHEXCost_Capex": [SCHEXCost_Capex],
        "Capex_a_pump": [Capex_a_pump_USD],
        "Opex_fixed_pump": [Opex_fixed_pump_USD],
        "Opex_var_pump": [Opex_var_pump_USD],
        "Sum_CAPEX": [addcosts_Capex_a_USD],
        "Sum_OPEX_fixed": [addcosts_Opex_fixed_USD],
        "GasConnectionInvCa": [GasConnectionInvCost],
        "CO2_PV_disconnected": [CO2_PV_disconnected],
        "cost_PV_disconnected": [cost_PV_disconnected],
        "Eprim_PV_disconnected": [Eprim_PV_disconnected],
        "Capex_SC_ET_USD": [Capex_SC_ET_USD],
        "Capex_SC_FP_USD": [Capex_SC_FP_USD],
        "Capex_PVT": [Capex_PVT_USD],
        "Capex_Boiler_backup": [Capex_Boiler_backup_USD],
        "Capex_storage_HEX": [Capex_HP_storage_USD],
        "Capex_storage_HP": [Capex_storage_HP],
        "Capex_CHP": [Capex_CHP_USD],
        "Capex_furnace": [Capex_furnace_USD],
        "Capex_Boiler_base": [Capex_Boiler_USD],
        "Capex_Boiler_peak": [Capex_Boiler_peak_USD],
        "Capex_Lake": [Capex_Lake_USD],
        "Capex_Sewage": [Capex_Sewage_USD],
        "Capex_pump": [Capex_pump_USD],
    })
    results.to_csv(locator.get_optimization_slave_investment_cost_detailed(
        master_to_slave_vars.individual_number,
        master_to_slave_vars.generation_number),
                   sep=',')
    return (addcosts_Capex_a_USD + addcosts_Opex_fixed_USD, addCO2, addPrim)
Beispiel #3
0
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"
Beispiel #4
0
def calc_generation_costs_heating(
    locator,
    master_to_slave_vars,
    config,
    storage_activation_data,
):
    """
    Computes costs / GHG emisions / primary energy needs
    for the individual
    addCosts = additional costs
    addCO2 = GHG emissions
    addPrm = primary energy needs
    :param DHN_barcode: parameter indicating if the building is connected or not
    :param buildList: list of buildings in the district
    :param locator: input locator set to scenario
    :param master_to_slave_vars: class containing the features of a specific individual
    :param Q_uncovered_design_W: hourly max of the heating uncovered demand
    :param Q_uncovered_annual_W: total heating uncovered
    :param solar_features: solar features
    :param thermal_network: network features
    :type indCombi: string
    :type buildList: list
    :type locator: string
    :type master_to_slave_vars: class
    :type Q_uncovered_design_W: float
    :type Q_uncovered_annual_W: float
    :type solar_features: class
    :type thermal_network: class

    :return: returns the objectives addCosts, addCO2, addPrim
    :rtype: tuple
    """

    thermal_network = pd.read_csv(
        locator.get_optimization_thermal_network_data_file(
            master_to_slave_vars.network_data_file_heating))

    # CCGT
    if master_to_slave_vars.CC_on == 1:
        CC_size_W = master_to_slave_vars.CCGT_SIZE_W
        Capex_a_CHP_NG_USD, Opex_fixed_CHP_NG_USD, Capex_CHP_NG_USD = chp.calc_Cinv_CCGT(
            CC_size_W, locator, config)
    else:
        Capex_a_CHP_NG_USD = 0.0
        Opex_fixed_CHP_NG_USD = 0.0
        Capex_CHP_NG_USD = 0.0

    # DRY BIOMASS
    if master_to_slave_vars.Furnace_dry_on == 1:
        Dry_Furnace_size_W = master_to_slave_vars.DBFurnace_Q_max_W
        Capex_a_furnace_dry_USD, \
        Opex_fixed_furnace_dry_USD, \
        Capex_furnace_dry_USD = furnace.calc_Cinv_furnace(Dry_Furnace_size_W, locator, 'FU1')
    else:
        Capex_furnace_dry_USD = 0.0
        Capex_a_furnace_dry_USD = 0.0
        Opex_fixed_furnace_dry_USD = 0.0

    # WET BIOMASS
    if master_to_slave_vars.Furnace_wet_on == 1:
        Wet_Furnace_size_W = master_to_slave_vars.WBFurnace_Q_max_W
        Capex_a_furnace_wet_USD, \
        Opex_fixed_furnace_wet_USD, \
        Capex_furnace_wet_USD = furnace.calc_Cinv_furnace(Wet_Furnace_size_W, locator, 'FU1')
    else:
        Capex_a_furnace_wet_USD = 0.0
        Opex_fixed_furnace_wet_USD = 0.0
        Capex_furnace_wet_USD = 0.0

    # BOILER BASE LOAD
    if master_to_slave_vars.Boiler_on == 1:
        Q_design_W = master_to_slave_vars.Boiler_Q_max_W
        Capex_a_BaseBoiler_NG_USD, \
        Opex_fixed_BaseBoiler_NG_USD, \
        Capex_BaseBoiler_NG_USD = boiler.calc_Cinv_boiler(Q_design_W, locator, config, 'BO1')
    else:
        Capex_a_BaseBoiler_NG_USD = 0.0
        Opex_fixed_BaseBoiler_NG_USD = 0.0
        Capex_BaseBoiler_NG_USD = 0.0

    # BOILER PEAK LOAD
    if master_to_slave_vars.BoilerPeak_on == 1:
        Q_design_W = master_to_slave_vars.BoilerPeak_Q_max_W
        Capex_a_PeakBoiler_NG_USD, \
        Opex_fixed_PeakBoiler_NG_USD, \
        Capex_PeakBoiler_NG_USD = boiler.calc_Cinv_boiler(Q_design_W, locator, config, 'BO1')
    else:
        Capex_a_PeakBoiler_NG_USD = 0.0
        Opex_fixed_PeakBoiler_NG_USD = 0.0
        Capex_PeakBoiler_NG_USD = 0.0

    # HEATPUMP LAKE
    if master_to_slave_vars.HPLake_on == 1:
        HP_Size_W = master_to_slave_vars.HPLake_maxSize_W
        Capex_a_Lake_USD, \
        Opex_fixed_Lake_USD, \
        Capex_Lake_USD = hp.calc_Cinv_HP(HP_Size_W, locator, 'HP2')
    else:
        Capex_a_Lake_USD = 0.0
        Opex_fixed_Lake_USD = 0.0
        Capex_Lake_USD = 0.0

    # HEATPUMP_SEWAGE
    if master_to_slave_vars.HPSew_on == 1:
        HP_Size_W = master_to_slave_vars.HPSew_maxSize_W
        Capex_a_Sewage_USD, \
        Opex_fixed_Sewage_USD, \
        Capex_Sewage_USD = hp.calc_Cinv_HP(HP_Size_W, locator, 'HP2')
    else:
        Capex_a_Sewage_USD = 0.0
        Opex_fixed_Sewage_USD = 0.0
        Capex_Sewage_USD = 0.0

    # GROUND HEAT PUMP
    if master_to_slave_vars.GHP_on == 1:
        GHP_Enom_W = master_to_slave_vars.GHP_maxSize_W
        Capex_a_GHP_USD, \
        Opex_fixed_GHP_USD, \
        Capex_GHP_USD = hp.calc_Cinv_GHP(GHP_Enom_W, locator, config)
    else:
        Capex_a_GHP_USD = 0.0
        Opex_fixed_GHP_USD = 0.0
        Capex_GHP_USD = 0.0

    # BACK-UP BOILER
    if master_to_slave_vars.BackupBoiler_on != 0:
        Q_backup_W = master_to_slave_vars.BackupBoiler_size_W
        Capex_a_BackupBoiler_NG_USD, \
        Opex_fixed_BackupBoiler_NG_USD, \
        Capex_BackupBoiler_NG_USD = boiler.calc_Cinv_boiler(Q_backup_W, locator, config, 'BO1')
    else:
        Capex_a_BackupBoiler_NG_USD = 0.0
        Opex_fixed_BackupBoiler_NG_USD = 0.0
        Capex_BackupBoiler_NG_USD = 0.0

    # DATA CENTRE SOURCE HEAT PUMP
    if master_to_slave_vars.WasteServersHeatRecovery == 1:
        Q_HEX_max_Wh = thermal_network["Qcdata_netw_total_kWh"].max(
        ) * 1000  # convert to Wh
        Capex_a_wasteserver_HEX_USD, Opex_fixed_wasteserver_HEX_USD, Capex_wasteserver_HEX_USD = hex.calc_Cinv_HEX(
            Q_HEX_max_Wh, locator, config, 'HEX1')

        Q_HP_max_Wh = storage_activation_data["Q_HP_Server_W"].max()
        Capex_a_wasteserver_HP_USD, Opex_fixed_wasteserver_HP_USD, Capex_wasteserver_HP_USD = hp.calc_Cinv_HP(
            Q_HP_max_Wh, locator, 'HP2')
    else:
        Capex_a_wasteserver_HEX_USD = 0.0
        Opex_fixed_wasteserver_HEX_USD = 0.0
        Capex_wasteserver_HEX_USD = 0.0
        Capex_a_wasteserver_HP_USD = 0.0
        Opex_fixed_wasteserver_HP_USD = 0.0
        Capex_wasteserver_HP_USD = 0.0

    # SOLAR TECHNOLOGIES
    # ADD COSTS AND EMISSIONS DUE TO SOLAR TECHNOLOGIES
    SC_ET_area_m2 = master_to_slave_vars.A_SC_ET_m2
    Capex_a_SC_ET_USD, \
    Opex_fixed_SC_ET_USD, \
    Capex_SC_ET_USD = stc.calc_Cinv_SC(SC_ET_area_m2, locator,
                                       'ET')

    SC_FP_area_m2 = master_to_slave_vars.A_SC_FP_m2
    Capex_a_SC_FP_USD, \
    Opex_fixed_SC_FP_USD, \
    Capex_SC_FP_USD = stc.calc_Cinv_SC(SC_FP_area_m2, locator,
                                       'FP')

    PVT_peak_kW = master_to_slave_vars.A_PVT_m2 * N_PVT  # kW
    Capex_a_PVT_USD, \
    Opex_fixed_PVT_USD, \
    Capex_PVT_USD = pvt.calc_Cinv_PVT(PVT_peak_kW, locator, config)

    # HEATPUMP FOR SOLAR UPGRADE TO DISTRICT HEATING
    Q_HP_max_PVT_wh = storage_activation_data["Q_HP_PVT_W"].max()
    Capex_a_HP_PVT_USD, \
    Opex_fixed_HP_PVT_USD, \
    Capex_HP_PVT_USD = hp.calc_Cinv_HP(Q_HP_max_PVT_wh, locator, 'HP2')

    # hack split into two technologies
    Q_HP_max_SC_ET_Wh = storage_activation_data["Q_HP_SC_ET_W"].max()
    Capex_a_HP_SC_ET_USD, \
    Opex_fixed_HP_SC_ET_USD, \
    Capex_HP_SC_ET_USD = hp.calc_Cinv_HP(Q_HP_max_SC_ET_Wh, locator, 'HP2')

    Q_HP_max_SC_FP_Wh = storage_activation_data["Q_HP_SC_FP_W"].max()
    Capex_a_HP_SC_FP_USD, \
    Opex_fixed_HP_SC_FP_USD, \
    Capex_HP_SC_FP_USD = hp.calc_Cinv_HP(Q_HP_max_SC_FP_Wh, locator, 'HP2')

    # HEAT EXCHANGER FOR SOLAR COLLECTORS
    Q_max_SC_ET_Wh = (storage_activation_data["Q_SC_ET_gen_directload_W"] +
                      storage_activation_data["Q_SC_ET_gen_storage_W"]).max()
    Capex_a_HEX_SC_ET_USD, \
    Opex_fixed_HEX_SC_ET_USD, \
    Capex_HEX_SC_ET_USD = hex.calc_Cinv_HEX(Q_max_SC_ET_Wh, locator, config, 'HEX1')

    Q_max_SC_FP_Wh = (storage_activation_data["Q_SC_FP_gen_directload_W"] +
                      storage_activation_data["Q_SC_FP_gen_storage_W"]).max()
    Capex_a_HEX_SC_FP_USD, \
    Opex_fixed_HEX_SC_FP_USD, \
    Capex_HEX_SC_FP_USD = hex.calc_Cinv_HEX(Q_max_SC_FP_Wh, locator, config, 'HEX1')

    Q_max_PVT_Wh = (storage_activation_data["Q_PVT_gen_directload_W"] +
                    storage_activation_data["Q_PVT_gen_storage_W"]).max()
    Capex_a_HEX_PVT_USD, \
    Opex_fixed_HEX_PVT_USD, \
    Capex_HEX_PVT_USD = hex.calc_Cinv_HEX(Q_max_PVT_Wh, locator, config, 'HEX1')

    performance_costs = {
        "Capex_a_SC_ET_connected_USD":
        Capex_a_SC_ET_USD + Capex_a_HP_SC_ET_USD + Capex_a_HEX_SC_ET_USD,
        "Capex_a_SC_FP_connected_USD":
        Capex_a_SC_FP_USD + Capex_a_HP_SC_FP_USD + Capex_a_HEX_SC_FP_USD,
        "Capex_a_PVT_connected_USD":
        Capex_a_PVT_USD + Capex_a_HP_PVT_USD + Capex_a_HEX_PVT_USD,
        "Capex_a_HP_Server_connected_USD":
        Capex_a_wasteserver_HP_USD + Capex_a_wasteserver_HEX_USD,
        "Capex_a_HP_Sewage_connected_USD": Capex_a_Sewage_USD,
        "Capex_a_HP_Lake_connected_USD": Capex_a_Lake_USD,
        "Capex_a_GHP_connected_USD": Capex_a_GHP_USD,
        "Capex_a_CHP_NG_connected_USD": Capex_a_CHP_NG_USD,
        "Capex_a_Furnace_wet_connected_USD": Capex_a_furnace_wet_USD,
        "Capex_a_Furnace_dry_connected_USD": Capex_a_furnace_dry_USD,
        "Capex_a_BaseBoiler_NG_connected_USD": Capex_a_BaseBoiler_NG_USD,
        "Capex_a_PeakBoiler_NG_connected_USD": Capex_a_PeakBoiler_NG_USD,
        "Capex_a_BackupBoiler_NG_connected_USD": Capex_a_BackupBoiler_NG_USD,

        # total_capex
        "Capex_total_SC_ET_connected_USD":
        Capex_SC_ET_USD + Capex_HP_SC_ET_USD + Capex_HEX_SC_ET_USD,
        "Capex_total_SC_FP_connected_USD":
        Capex_SC_FP_USD + Capex_HP_SC_FP_USD + Capex_HEX_SC_FP_USD,
        "Capex_total_PVT_connected_USD":
        Capex_PVT_USD + Capex_HP_PVT_USD + Capex_HEX_PVT_USD,
        "Capex_total_HP_Server_connected_USD":
        Capex_wasteserver_HP_USD + Capex_wasteserver_HEX_USD,
        "Capex_total_HP_Sewage_connected_USD": Capex_Sewage_USD,
        "Capex_total_HP_Lake_connected_USD": Capex_Lake_USD,
        "Capex_total_GHP_connected_USD": Capex_GHP_USD,
        "Capex_total_CHP_NG_connected_USD": Capex_CHP_NG_USD,
        "Capex_total_Furnace_wet_connected_USD": Capex_furnace_wet_USD,
        "Capex_total_Furnace_dry_connected_USD": Capex_furnace_dry_USD,
        "Capex_total_BaseBoiler_NG_connected_USD": Capex_BaseBoiler_NG_USD,
        "Capex_total_PeakBoiler_NG_connected_USD": Capex_PeakBoiler_NG_USD,
        "Capex_total_BackupBoiler_NG_connected_USD": Capex_BackupBoiler_NG_USD,

        # opex fixed costs
        "Opex_fixed_SC_ET_connected_USD": Opex_fixed_SC_ET_USD,
        "Opex_fixed_SC_FP_connected_USD": Opex_fixed_SC_FP_USD,
        "Opex_fixed_PVT_connected_USD": Opex_fixed_PVT_USD,
        "Opex_fixed_HP_Server_connected_USD":
        Opex_fixed_wasteserver_HP_USD + Opex_fixed_wasteserver_HEX_USD,
        "Opex_fixed_HP_Sewage_connected_USD": Opex_fixed_Sewage_USD,
        "Opex_fixed_HP_Lake_connected_USD": Opex_fixed_Lake_USD,
        "Opex_fixed_GHP_connected_USD": Opex_fixed_GHP_USD,
        "Opex_fixed_CHP_NG_connected_USD": Opex_fixed_CHP_NG_USD,
        "Opex_fixed_Furnace_wet_connected_USD": Opex_fixed_furnace_wet_USD,
        "Opex_fixed_Furnace_dry_connected_USD": Opex_fixed_furnace_dry_USD,
        "Opex_fixed_BaseBoiler_NG_connected_USD": Opex_fixed_BaseBoiler_NG_USD,
        "Opex_fixed_PeakBoiler_NG_connected_USD": Opex_fixed_PeakBoiler_NG_USD,
        "Opex_fixed_BackupBoiler_NG_connected_USD":
        Opex_fixed_BackupBoiler_NG_USD,
    }

    return performance_costs
Beispiel #5
0
def addCosts(DHN_barcode, DCN_barcode, buildList, locator,
             master_to_slave_vars, Q_uncovered_design_W, Q_uncovered_annual_W,
             solarFeat, ntwFeat, gv, config, prices, lca):
    """
    Computes additional costs / GHG emisions / primary energy needs
    for the individual
    addCosts = additional costs
    addCO2 = GHG emissions
    addPrm = primary energy needs
    :param DHN_barcode: parameter indicating if the building is connected or not
    :param buildList: list of buildings in the district
    :param locator: input locator set to scenario
    :param master_to_slave_vars: class containing the features of a specific individual
    :param Q_uncovered_design_W: hourly max of the heating uncovered demand
    :param Q_uncovered_annual_W: total heating uncovered
    :param solarFeat: solar features
    :param ntwFeat: network features
    :param gv: global variables
    :type indCombi: string
    :type buildList: list
    :type locator: string
    :type master_to_slave_vars: class
    :type Q_uncovered_design_W: float
    :type Q_uncovered_annual_W: float
    :type solarFeat: class
    :type ntwFeat: class
    :type gv: class

    :return: returns the objectives addCosts, addCO2, addPrim
    :rtype: tuple
    """
    addcosts_Capex_a = 0
    addcosts_Opex_fixed = 0
    addCO2 = 0
    addPrim = 0
    nBuildinNtw = 0

    # Add the features from the disconnected buildings
    CostDiscBuild = 0
    CO2DiscBuild = 0
    PrimDiscBuild = 0
    Capex_Disconnected = 0
    Opex_Disconnected = 0
    Capex_a_furnace = 0
    Capex_a_CHP = 0
    Capex_a_Boiler = 0
    Capex_a_Boiler_peak = 0
    Capex_a_Lake = 0
    Capex_a_Sewage = 0
    Capex_a_GHP = 0
    Capex_a_PV = 0
    Capex_a_SC = 0
    Capex_a_PVT = 0
    Capex_a_Boiler_backup = 0
    Capex_a_HEX = 0
    Capex_a_storage_HP = 0
    Capex_a_HP_storage = 0
    Opex_fixed_SC = 0
    Opex_fixed_PVT = 0
    Opex_fixed_HP_PVT = 0
    Opex_fixed_furnace = 0
    Opex_fixed_CHP = 0
    Opex_fixed_Boiler = 0
    Opex_fixed_Boiler_peak = 0
    Opex_fixed_Boiler_backup = 0
    Opex_fixed_Lake = 0
    Opex_fixed_wasteserver_HEX = 0
    Opex_fixed_wasteserver_HP = 0
    Opex_fixed_PV = 0
    Opex_fixed_GHP = 0
    Opex_fixed_storage = 0
    Opex_fixed_Sewage = 0
    Opex_fixed_HP_storage = 0
    StorageInvC = 0
    NetworkCost = 0
    SubstHEXCost_capex = 0
    SubstHEXCost_opex = 0
    PVTHEXCost_Capex = 0
    PVTHEXCost_Opex = 0
    SCHEXCost_Capex = 0
    SCHEXCost_Opex = 0
    pumpCosts = 0
    GasConnectionInvCost = 0
    cost_PV_disconnected = 0
    CO2_PV_disconnected = 0
    Eprim_PV_disconnected = 0

    if config.optimization.isheating:
        for (index, building_name) in zip(DHN_barcode, buildList):
            if index == "0":
                df = pd.read_csv(
                    locator.
                    get_optimization_disconnected_folder_building_result_heating(
                        building_name))
                dfBest = df[df["Best configuration"] == 1]
                CostDiscBuild += dfBest["Total Costs [CHF]"].iloc[0]  # [CHF]
                CO2DiscBuild += dfBest["CO2 Emissions [kgCO2-eq]"].iloc[
                    0]  # [kg CO2]
                PrimDiscBuild += dfBest[
                    "Primary Energy Needs [MJoil-eq]"].iloc[0]  # [MJ-oil-eq]
                Capex_Disconnected += dfBest[
                    "Annualized Investment Costs [CHF]"].iloc[0]
                Opex_Disconnected += dfBest["Operation Costs [CHF]"].iloc[0]
            else:
                nBuildinNtw += 1
    if config.optimization.iscooling:
        PV_barcode = ''
        for (index, building_name) in zip(DCN_barcode, buildList):
            if index == "0":  # choose the best decentralized configuration
                df = pd.read_csv(
                    locator.
                    get_optimization_disconnected_folder_building_result_cooling(
                        building_name, configuration='AHU_ARU_SCU'))
                dfBest = df[df["Best configuration"] == 1]
                CostDiscBuild += dfBest["Total Costs [CHF]"].iloc[0]  # [CHF]
                CO2DiscBuild += dfBest["CO2 Emissions [kgCO2-eq]"].iloc[
                    0]  # [kg CO2]
                PrimDiscBuild += dfBest[
                    "Primary Energy Needs [MJoil-eq]"].iloc[0]  # [MJ-oil-eq]
                Capex_Disconnected += dfBest[
                    "Annualized Investment Costs [CHF]"].iloc[0]
                Opex_Disconnected += dfBest["Operation Costs [CHF]"].iloc[0]
                to_PV = 1
                if dfBest["single effect ACH to AHU_ARU_SCU Share (FP)"].iloc[
                        0] == 1:
                    to_PV = 0
                if dfBest["single effect ACH to AHU_ARU_SCU Share (ET)"].iloc[
                        0] == 1:
                    to_PV = 0
                if dfBest["single effect ACH to SCU Share (FP)"].iloc[0] == 1:
                    to_PV = 0

            else:  # adding costs for buildings in which the centralized plant provides a part of the load requirements
                DCN_unit_configuration = master_to_slave_vars.DCN_supplyunits
                if DCN_unit_configuration == 1:  # corresponds to AHU in the central plant, so remaining load need to be provided by decentralized plant
                    decentralized_configuration = 'ARU_SCU'
                    df = pd.read_csv(
                        locator.
                        get_optimization_disconnected_folder_building_result_cooling(
                            building_name, decentralized_configuration))
                    dfBest = df[df["Best configuration"] == 1]
                    CostDiscBuild += dfBest["Total Costs [CHF]"].iloc[
                        0]  # [CHF]
                    CO2DiscBuild += dfBest["CO2 Emissions [kgCO2-eq]"].iloc[
                        0]  # [kg CO2]
                    PrimDiscBuild += dfBest[
                        "Primary Energy Needs [MJoil-eq]"].iloc[
                            0]  # [MJ-oil-eq]
                    Capex_Disconnected += dfBest[
                        "Annualized Investment Costs [CHF]"].iloc[0]
                    Opex_Disconnected += dfBest["Operation Costs [CHF]"].iloc[
                        0]
                    to_PV = 1
                    if dfBest["single effect ACH to ARU_SCU Share (FP)"].iloc[
                            0] == 1:
                        to_PV = 0
                    if dfBest["single effect ACH to ARU_SCU Share (ET)"].iloc[
                            0] == 1:
                        to_PV = 0

                if DCN_unit_configuration == 2:  # corresponds to ARU in the central plant, so remaining load need to be provided by decentralized plant
                    decentralized_configuration = 'AHU_SCU'
                    df = pd.read_csv(
                        locator.
                        get_optimization_disconnected_folder_building_result_cooling(
                            building_name, decentralized_configuration))
                    dfBest = df[df["Best configuration"] == 1]
                    CostDiscBuild += dfBest["Total Costs [CHF]"].iloc[
                        0]  # [CHF]
                    CO2DiscBuild += dfBest["CO2 Emissions [kgCO2-eq]"].iloc[
                        0]  # [kg CO2]
                    PrimDiscBuild += dfBest[
                        "Primary Energy Needs [MJoil-eq]"].iloc[
                            0]  # [MJ-oil-eq]
                    Capex_Disconnected += dfBest[
                        "Annualized Investment Costs [CHF]"].iloc[0]
                    Opex_Disconnected += dfBest["Operation Costs [CHF]"].iloc[
                        0]
                    to_PV = 1
                    if dfBest["single effect ACH to AHU_SCU Share (FP)"].iloc[
                            0] == 1:
                        to_PV = 0
                    if dfBest["single effect ACH to AHU_SCU Share (ET)"].iloc[
                            0] == 1:
                        to_PV = 0

                if DCN_unit_configuration == 3:  # corresponds to SCU in the central plant, so remaining load need to be provided by decentralized plant
                    decentralized_configuration = 'AHU_ARU'
                    df = pd.read_csv(
                        locator.
                        get_optimization_disconnected_folder_building_result_cooling(
                            building_name, decentralized_configuration))
                    dfBest = df[df["Best configuration"] == 1]
                    CostDiscBuild += dfBest["Total Costs [CHF]"].iloc[
                        0]  # [CHF]
                    CO2DiscBuild += dfBest["CO2 Emissions [kgCO2-eq]"].iloc[
                        0]  # [kg CO2]
                    PrimDiscBuild += dfBest[
                        "Primary Energy Needs [MJoil-eq]"].iloc[
                            0]  # [MJ-oil-eq]
                    Capex_Disconnected += dfBest[
                        "Annualized Investment Costs [CHF]"].iloc[0]
                    Opex_Disconnected += dfBest["Operation Costs [CHF]"].iloc[
                        0]
                    to_PV = 1
                    if dfBest["single effect ACH to AHU_ARU Share (FP)"].iloc[
                            0] == 1:
                        to_PV = 0
                    if dfBest["single effect ACH to AHU_ARU Share (ET)"].iloc[
                            0] == 1:
                        to_PV = 0

                if DCN_unit_configuration == 4:  # corresponds to AHU + ARU in the central plant, so remaining load need to be provided by decentralized plant
                    decentralized_configuration = 'SCU'
                    df = pd.read_csv(
                        locator.
                        get_optimization_disconnected_folder_building_result_cooling(
                            building_name, decentralized_configuration))
                    dfBest = df[df["Best configuration"] == 1]
                    CostDiscBuild += dfBest["Total Costs [CHF]"].iloc[
                        0]  # [CHF]
                    CO2DiscBuild += dfBest["CO2 Emissions [kgCO2-eq]"].iloc[
                        0]  # [kg CO2]
                    PrimDiscBuild += dfBest[
                        "Primary Energy Needs [MJoil-eq]"].iloc[
                            0]  # [MJ-oil-eq]
                    Capex_Disconnected += dfBest[
                        "Annualized Investment Costs [CHF]"].iloc[0]
                    Opex_Disconnected += dfBest["Operation Costs [CHF]"].iloc[
                        0]
                    to_PV = 1
                    if dfBest["single effect ACH to SCU Share (FP)"].iloc[
                            0] == 1:
                        to_PV = 0
                    if dfBest["single effect ACH to SCU Share (ET)"].iloc[
                            0] == 1:
                        to_PV = 0

                if DCN_unit_configuration == 5:  # corresponds to AHU + SCU in the central plant, so remaining load need to be provided by decentralized plant
                    decentralized_configuration = 'ARU'
                    df = pd.read_csv(
                        locator.
                        get_optimization_disconnected_folder_building_result_cooling(
                            building_name, decentralized_configuration))
                    dfBest = df[df["Best configuration"] == 1]
                    CostDiscBuild += dfBest["Total Costs [CHF]"].iloc[
                        0]  # [CHF]
                    CO2DiscBuild += dfBest["CO2 Emissions [kgCO2-eq]"].iloc[
                        0]  # [kg CO2]
                    PrimDiscBuild += dfBest[
                        "Primary Energy Needs [MJoil-eq]"].iloc[
                            0]  # [MJ-oil-eq]
                    Capex_Disconnected += dfBest[
                        "Annualized Investment Costs [CHF]"].iloc[0]
                    Opex_Disconnected += dfBest["Operation Costs [CHF]"].iloc[
                        0]
                    to_PV = 1
                    if dfBest["single effect ACH to ARU Share (FP)"].iloc[
                            0] == 1:
                        to_PV = 0
                    if dfBest["single effect ACH to ARU Share (ET)"].iloc[
                            0] == 1:
                        to_PV = 0

                if DCN_unit_configuration == 6:  # corresponds to ARU + SCU in the central plant, so remaining load need to be provided by decentralized plant
                    decentralized_configuration = 'AHU'
                    df = pd.read_csv(
                        locator.
                        get_optimization_disconnected_folder_building_result_cooling(
                            building_name, decentralized_configuration))
                    dfBest = df[df["Best configuration"] == 1]
                    CostDiscBuild += dfBest["Total Costs [CHF]"].iloc[
                        0]  # [CHF]
                    CO2DiscBuild += dfBest["CO2 Emissions [kgCO2-eq]"].iloc[
                        0]  # [kg CO2]
                    PrimDiscBuild += dfBest[
                        "Primary Energy Needs [MJoil-eq]"].iloc[
                            0]  # [MJ-oil-eq]
                    Capex_Disconnected += dfBest[
                        "Annualized Investment Costs [CHF]"].iloc[0]
                    Opex_Disconnected += dfBest["Operation Costs [CHF]"].iloc[
                        0]
                    to_PV = 1
                    if dfBest["single effect ACH to AHU Share (FP)"].iloc[
                            0] == 1:
                        to_PV = 0
                    if dfBest["single effect ACH to AHU Share (ET)"].iloc[
                            0] == 1:
                        to_PV = 0

                if DCN_unit_configuration == 7:  # corresponds to AHU + ARU + SCU from central plant
                    to_PV = 1

                nBuildinNtw += 1
            PV_barcode = PV_barcode + str(to_PV)

    addcosts_Capex_a += CostDiscBuild
    addCO2 += CO2DiscBuild
    addPrim += PrimDiscBuild

    if not config.optimization.isheating:
        if PV_barcode.count("1") > 0:
            df1 = pd.DataFrame({'A': []})
            for (i, index) in enumerate(PV_barcode):
                if index == str(1):
                    if df1.empty:
                        data = pd.read_csv(locator.PV_results(buildList[i]))
                        df1 = data
                    else:
                        data = pd.read_csv(locator.PV_results(buildList[i]))
                        df1 = df1 + data
            if not df1.empty:
                df1.to_csv(locator.PV_network(PV_barcode),
                           index=True,
                           float_format='%.2f')

            solar_data = pd.read_csv(locator.PV_network(PV_barcode),
                                     usecols=['E_PV_gen_kWh', 'Area_PV_m2'],
                                     nrows=8760)
            E_PV_sum_kW = np.sum(solar_data['E_PV_gen_kWh'])
            E_PV_W = solar_data['E_PV_gen_kWh'] * 1000
            Area_AvailablePV_m2 = np.max(solar_data['Area_PV_m2'])
            Q_PowerPeakAvailablePV_kW = Area_AvailablePV_m2 * ETA_AREA_TO_PEAK
            KEV_RpPerkWhPV = calc_Crem_pv(Q_PowerPeakAvailablePV_kW * 1000.0)
            KEV_total = KEV_RpPerkWhPV / 100 * np.sum(E_PV_sum_kW)

            addcosts_Capex_a = addcosts_Capex_a - KEV_total
            addCO2 = addCO2 - (E_PV_sum_kW * 1000 *
                               (lca.EL_PV_TO_CO2 - lca.EL_TO_CO2_GREEN) *
                               WH_TO_J / 1.0E6)
            addPrim = addPrim - (E_PV_sum_kW * 1000 *
                                 (lca.EL_PV_TO_OIL_EQ - lca.EL_TO_OIL_EQ_GREEN)
                                 * WH_TO_J / 1.0E6)

            cost_PV_disconnected = KEV_total
            CO2_PV_disconnected = (E_PV_sum_kW * 1000 *
                                   (lca.EL_PV_TO_CO2 - lca.EL_TO_CO2_GREEN) *
                                   WH_TO_J / 1.0E6)
            Eprim_PV_disconnected = (
                E_PV_sum_kW * 1000 *
                (lca.EL_PV_TO_OIL_EQ - lca.EL_TO_OIL_EQ_GREEN) * WH_TO_J /
                1.0E6)

            network_data = pd.read_csv(
                locator.get_optimization_network_data_folder(
                    master_to_slave_vars.network_data_file_cooling))

            E_total_req_W = np.array(network_data['Electr_netw_total_W'])
            cooling_data = pd.read_csv(
                locator.get_optimization_slave_cooling_activation_pattern(
                    master_to_slave_vars.individual_number,
                    master_to_slave_vars.generation_number))

            E_from_CHP_W = np.array(cooling_data[
                'E_gen_CCGT_associated_with_absorption_chillers_W'])
            E_CHP_to_directload_W = np.zeros(8760)
            E_CHP_to_grid_W = np.zeros(8760)
            E_PV_to_directload_W = np.zeros(8760)
            E_PV_to_grid_W = np.zeros(8760)
            E_from_grid_W = np.zeros(8760)

            for hour in range(8760):
                E_hour_W = E_total_req_W[hour]
                if E_hour_W > 0:
                    if E_PV_W[hour] > E_hour_W:
                        E_PV_to_directload_W[hour] = E_hour_W
                        E_PV_to_grid_W[
                            hour] = E_PV_W[hour] - E_total_req_W[hour]
                        E_hour_W = 0
                    else:
                        E_hour_W = E_hour_W - E_PV_W[hour]
                        E_PV_to_directload_W[hour] = E_PV_W[hour]

                    if E_from_CHP_W[hour] > E_hour_W:
                        E_CHP_to_directload_W[hour] = E_hour_W
                        E_CHP_to_grid_W[hour] = E_from_CHP_W[hour] - E_hour_W
                        E_hour_W = 0
                    else:
                        E_hour_W = E_hour_W - E_from_CHP_W[hour]
                        E_CHP_to_directload_W[hour] = E_from_CHP_W[hour]

                    E_from_grid_W[hour] = E_hour_W

            date = network_data.DATE.values
            results = pd.DataFrame({
                "DATE":
                date,
                "E_total_req_W":
                E_total_req_W,
                "E_PV_W":
                solar_data['E_PV_gen_kWh'] * 1000,
                "Area_PV_m2":
                solar_data['Area_PV_m2'],
                "KEV":
                KEV_RpPerkWhPV / 100 * solar_data['E_PV_gen_kWh'],
                "E_from_grid_W":
                E_from_grid_W,
                "E_PV_to_directload_W":
                E_PV_to_directload_W,
                "E_CHP_to_directload_W":
                E_CHP_to_directload_W,
                "E_CHP_to_grid_W":
                E_CHP_to_grid_W,
                "E_PV_to_grid_W":
                E_PV_to_grid_W
            })

            results.to_csv(
                locator.
                get_optimization_slave_electricity_activation_pattern_cooling(
                    master_to_slave_vars.individual_number,
                    master_to_slave_vars.generation_number),
                index=False)

    # Add the features for the distribution

    if DHN_barcode.count("1") > 0 and config.optimization.isheating:
        os.chdir(
            locator.get_optimization_slave_results_folder(
                master_to_slave_vars.generation_number))
        # Add the investment costs of the energy systems
        # Furnace
        if master_to_slave_vars.Furnace_on == 1:
            P_design_W = master_to_slave_vars.Furnace_Q_max

            fNameSlavePP = locator.get_optimization_slave_heating_activation_pattern_heating(
                master_to_slave_vars.configKey,
                master_to_slave_vars.individual_number,
                master_to_slave_vars.generation_number)
            dfFurnace = pd.read_csv(fNameSlavePP, usecols=["Q_Furnace_W"])
            arrayFurnace_W = np.array(dfFurnace)

            Q_annual_W = 0
            for i in range(int(np.shape(arrayFurnace_W)[0])):
                Q_annual_W += arrayFurnace_W[i][0]

            Capex_a_furnace, Opex_fixed_furnace = furnace.calc_Cinv_furnace(
                P_design_W, Q_annual_W, config, locator, 'FU1')
            addcosts_Capex_a += Capex_a_furnace
            addcosts_Opex_fixed += Opex_fixed_furnace

        # CC
        if master_to_slave_vars.CC_on == 1:
            CC_size_W = master_to_slave_vars.CC_GT_SIZE
            Capex_a_CHP, Opex_fixed_CHP = chp.calc_Cinv_CCGT(
                CC_size_W, locator, config)
            addcosts_Capex_a += Capex_a_CHP
            addcosts_Opex_fixed += Opex_fixed_CHP

        # Boiler Base
        if master_to_slave_vars.Boiler_on == 1:
            Q_design_W = master_to_slave_vars.Boiler_Q_max

            fNameSlavePP = locator.get_optimization_slave_heating_activation_pattern(
                master_to_slave_vars.individual_number,
                master_to_slave_vars.generation_number)
            dfBoilerBase = pd.read_csv(fNameSlavePP,
                                       usecols=["Q_BaseBoiler_W"])
            arrayBoilerBase_W = np.array(dfBoilerBase)

            Q_annual_W = 0
            for i in range(int(np.shape(arrayBoilerBase_W)[0])):
                Q_annual_W += arrayBoilerBase_W[i][0]

            Capex_a_Boiler, Opex_fixed_Boiler = boiler.calc_Cinv_boiler(
                Q_design_W, locator, config, 'BO1')
            addcosts_Capex_a += Capex_a_Boiler
            addcosts_Opex_fixed += Opex_fixed_Boiler

        # Boiler Peak
        if master_to_slave_vars.BoilerPeak_on == 1:
            Q_design_W = master_to_slave_vars.BoilerPeak_Q_max

            fNameSlavePP = locator.get_optimization_slave_heating_activation_pattern(
                master_to_slave_vars.individual_number,
                master_to_slave_vars.generation_number)
            dfBoilerPeak = pd.read_csv(fNameSlavePP,
                                       usecols=["Q_PeakBoiler_W"])
            arrayBoilerPeak_W = np.array(dfBoilerPeak)

            Q_annual_W = 0
            for i in range(int(np.shape(arrayBoilerPeak_W)[0])):
                Q_annual_W += arrayBoilerPeak_W[i][0]
            Capex_a_Boiler_peak, Opex_fixed_Boiler_peak = boiler.calc_Cinv_boiler(
                Q_design_W, locator, config, 'BO1')
            addcosts_Capex_a += Capex_a_Boiler_peak
            addcosts_Opex_fixed += Opex_fixed_Boiler_peak

        # HP Lake
        if master_to_slave_vars.HP_Lake_on == 1:
            HP_Size_W = master_to_slave_vars.HPLake_maxSize
            Capex_a_Lake, Opex_fixed_Lake = hp.calc_Cinv_HP(
                HP_Size_W, locator, config, 'HP2')
            addcosts_Capex_a += Capex_a_Lake
            addcosts_Opex_fixed += Opex_fixed_Lake

        # HP Sewage
        if master_to_slave_vars.HP_Sew_on == 1:
            HP_Size_W = master_to_slave_vars.HPSew_maxSize
            Capex_a_Sewage, Opex_fixed_Sewage = hp.calc_Cinv_HP(
                HP_Size_W, locator, config, 'HP2')
            addcosts_Capex_a += Capex_a_Sewage
            addcosts_Opex_fixed += Opex_fixed_Sewage

        # GHP
        if master_to_slave_vars.GHP_on == 1:
            fNameSlavePP = locator.get_optimization_slave_electricity_activation_pattern_heating(
                master_to_slave_vars.individual_number,
                master_to_slave_vars.generation_number)
            dfGHP = pd.read_csv(fNameSlavePP, usecols=["E_GHP_req_W"])
            arrayGHP_W = np.array(dfGHP)

            GHP_Enom_W = np.amax(arrayGHP_W)
            Capex_a_GHP, Opex_fixed_GHP = hp.calc_Cinv_GHP(
                GHP_Enom_W, locator, config)
            addcosts_Capex_a += Capex_a_GHP * prices.EURO_TO_CHF
            addcosts_Opex_fixed += Opex_fixed_GHP * prices.EURO_TO_CHF

        # Solar technologies

        PV_installed_area_m2 = master_to_slave_vars.SOLAR_PART_PV * solarFeat.A_PV_m2  #kW
        Capex_a_PV, Opex_fixed_PV = pv.calc_Cinv_pv(PV_installed_area_m2,
                                                    locator, config)
        addcosts_Capex_a += Capex_a_PV
        addcosts_Opex_fixed += Opex_fixed_PV

        SC_ET_area_m2 = master_to_slave_vars.SOLAR_PART_SC_ET * solarFeat.A_SC_ET_m2
        Capex_a_SC_ET, Opex_fixed_SC_ET = stc.calc_Cinv_SC(
            SC_ET_area_m2, locator, config, 'ET')
        addcosts_Capex_a += Capex_a_SC_ET
        addcosts_Opex_fixed += Opex_fixed_SC_ET

        SC_FP_area_m2 = master_to_slave_vars.SOLAR_PART_SC_FP * solarFeat.A_SC_FP_m2
        Capex_a_SC_FP, Opex_fixed_SC_FP = stc.calc_Cinv_SC(
            SC_FP_area_m2, locator, config, 'FP')
        addcosts_Capex_a += Capex_a_SC_FP
        addcosts_Opex_fixed += Opex_fixed_SC_FP

        PVT_peak_kW = master_to_slave_vars.SOLAR_PART_PVT * solarFeat.A_PVT_m2 * N_PVT  #kW
        Capex_a_PVT, Opex_fixed_PVT = pvt.calc_Cinv_PVT(
            PVT_peak_kW, locator, config)
        addcosts_Capex_a += Capex_a_PVT
        addcosts_Opex_fixed += Opex_fixed_PVT

        # Back-up boiler
        Capex_a_Boiler_backup, Opex_fixed_Boiler_backup = boiler.calc_Cinv_boiler(
            Q_uncovered_design_W, locator, config, 'BO1')
        addcosts_Capex_a += Capex_a_Boiler_backup
        addcosts_Opex_fixed += Opex_fixed_Boiler_backup

        # Hex and HP for Heat recovery
        if master_to_slave_vars.WasteServersHeatRecovery == 1:
            df = pd.read_csv(os.path.join(
                locator.get_optimization_network_results_folder(),
                master_to_slave_vars.network_data_file_heating),
                             usecols=["Qcdata_netw_total_kWh"])
            array = np.array(df)
            Q_HEX_max_kWh = np.amax(array)
            Capex_a_wasteserver_HEX, Opex_fixed_wasteserver_HEX = hex.calc_Cinv_HEX(
                Q_HEX_max_kWh, locator, config, 'HEX1')
            addcosts_Capex_a += (Capex_a_wasteserver_HEX)
            addcosts_Opex_fixed += Opex_fixed_wasteserver_HEX

            df = pd.read_csv(
                locator.get_optimization_slave_storage_operation_data(
                    master_to_slave_vars.individual_number,
                    master_to_slave_vars.generation_number),
                usecols=["HPServerHeatDesignArray_kWh"])
            array = np.array(df)
            Q_HP_max_kWh = np.amax(array)
            Capex_a_wasteserver_HP, Opex_fixed_wasteserver_HP = hp.calc_Cinv_HP(
                Q_HP_max_kWh, locator, config, 'HP2')
            addcosts_Capex_a += (Capex_a_wasteserver_HP)
            addcosts_Opex_fixed += Opex_fixed_wasteserver_HP

        # if master_to_slave_vars.WasteCompressorHeatRecovery == 1:
        #     df = pd.read_csv(
        #         os.path.join(locator.get_optimization_network_results_folder(), master_to_slave_vars.network_data_file_heating),
        #         usecols=["Ecaf_netw_total_kWh"])
        #     array = np.array(df)
        #     Q_HEX_max_kWh = np.amax(array)
        #
        #     Capex_a_wastecompressor_HEX, Opex_fixed_wastecompressor_HEX = hex.calc_Cinv_HEX(Q_HEX_max_kWh, locator,
        #                                                                                     config, 'HEX1')
        #     addcosts_Capex_a += (Capex_a_wastecompressor_HEX)
        #     addcosts_Opex_fixed += Opex_fixed_wastecompressor_HEX
        #     df = pd.read_csv(
        #         locator.get_optimization_slave_storage_operation_data(master_to_slave_vars.individual_number,
        #                                                               master_to_slave_vars.generation_number),
        #         usecols=["HPCompAirDesignArray_kWh"])
        #     array = np.array(df)
        #     Q_HP_max_kWh = np.amax(array)
        #     Capex_a_wastecompressor_HP, Opex_fixed_wastecompressor_HP = hp.calc_Cinv_HP(Q_HP_max_kWh, locator, config, 'HP2')
        #     addcosts_Capex_a += (Capex_a_wastecompressor_HP)
        #     addcosts_Opex_fixed += Opex_fixed_wastecompressor_HP

        # Heat pump from solar to DH
        df = pd.read_csv(
            locator.get_optimization_slave_storage_operation_data(
                master_to_slave_vars.individual_number,
                master_to_slave_vars.generation_number),
            usecols=["HPScDesignArray_Wh", "HPpvt_designArray_Wh"])
        array = np.array(df)
        Q_HP_max_PVT_wh = np.amax(array[:, 1])
        Q_HP_max_SC_Wh = np.amax(array[:, 0])
        Capex_a_HP_PVT, Opex_fixed_HP_PVT = hp.calc_Cinv_HP(
            Q_HP_max_PVT_wh, locator, config, 'HP2')
        Capex_a_storage_HP += (Capex_a_HP_PVT)
        addcosts_Opex_fixed += Opex_fixed_HP_PVT

        Capex_a_HP_SC, Opex_fixed_HP_SC = hp.calc_Cinv_HP(
            Q_HP_max_SC_Wh, locator, config, 'HP2')
        Capex_a_storage_HP += (Capex_a_HP_SC)
        addcosts_Opex_fixed += Opex_fixed_HP_SC

        # HP for storage operation for charging from solar and discharging to DH
        df = pd.read_csv(locator.get_optimization_slave_storage_operation_data(
            master_to_slave_vars.individual_number,
            master_to_slave_vars.generation_number),
                         usecols=[
                             "E_aux_ch_W", "E_aux_dech_W",
                             "Q_from_storage_used_W", "Q_to_storage_W"
                         ])
        array = np.array(df)
        Q_HP_max_storage_W = 0
        for i in range(DAYS_IN_YEAR * HOURS_IN_DAY):
            if array[i][0] > 0:
                Q_HP_max_storage_W = max(Q_HP_max_storage_W,
                                         array[i][3] + array[i][0])
            elif array[i][1] > 0:
                Q_HP_max_storage_W = max(Q_HP_max_storage_W,
                                         array[i][2] + array[i][1])

        Capex_a_HP_storage, Opex_fixed_HP_storage = hp.calc_Cinv_HP(
            Q_HP_max_storage_W, locator, config, 'HP2')
        addcosts_Capex_a += (Capex_a_HP_storage)
        addcosts_Opex_fixed += Opex_fixed_HP_storage

        # Storage
        df = pd.read_csv(locator.get_optimization_slave_storage_operation_data(
            master_to_slave_vars.individual_number,
            master_to_slave_vars.generation_number),
                         usecols=["Storage_Size_m3"],
                         nrows=1)
        StorageVol_m3 = np.array(df)[0][0]
        Capex_a_storage, Opex_fixed_storage = storage.calc_Cinv_storage(
            StorageVol_m3, locator, config, 'TES2')
        addcosts_Capex_a += Capex_a_storage
        addcosts_Opex_fixed += Opex_fixed_storage

        # Costs from distribution configuration
        if gv.ZernezFlag == 1:
            NetworkCost += network.calc_Cinv_network_linear(
                gv.NetworkLengthZernez, gv) * nBuildinNtw / len(buildList)
        else:
            NetworkCost += ntwFeat.pipesCosts_DHN * nBuildinNtw / len(
                buildList)
        addcosts_Capex_a += NetworkCost

        # HEX (1 per building in ntw)
        for (index, building_name) in zip(DHN_barcode, buildList):
            if index == "1":
                df = pd.read_csv(
                    locator.get_optimization_substations_results_file(
                        building_name),
                    usecols=["Q_dhw_W", "Q_heating_W"])
                subsArray = np.array(df)

                Q_max_W = np.amax(subsArray[:, 0] + subsArray[:, 1])
                Capex_a_HEX_building, Opex_fixed_HEX_building = hex.calc_Cinv_HEX(
                    Q_max_W, locator, config, 'HEX1')
                addcosts_Capex_a += Capex_a_HEX_building
                addcosts_Opex_fixed += Opex_fixed_HEX_building

        # HEX for solar
        roof_area_m2 = np.array(
            pd.read_csv(locator.get_total_demand(), usecols=["Aroof_m2"]))

        areaAvail = 0
        for i in range(len(DHN_barcode)):
            index = DHN_barcode[i]
            if index == "1":
                areaAvail += roof_area_m2[i][0]

        for i in range(len(DHN_barcode)):
            index = DHN_barcode[i]
            if index == "1":
                share = roof_area_m2[i][0] / areaAvail
                #print share, "solar area share", buildList[i]

                Q_max_SC_ET_Wh = solarFeat.Q_nom_SC_ET_Wh * master_to_slave_vars.SOLAR_PART_SC_ET * share
                Capex_a_HEX_SC_ET, Opex_fixed_HEX_SC_ET = hex.calc_Cinv_HEX(
                    Q_max_SC_ET_Wh, locator, config, 'HEX1')
                addcosts_Capex_a += Capex_a_HEX_SC_ET
                addcosts_Opex_fixed += Opex_fixed_HEX_SC_ET

                Q_max_SC_FP_Wh = solarFeat.Q_nom_SC_FP_Wh * master_to_slave_vars.SOLAR_PART_SC_FP * share
                Capex_a_HEX_SC_FP, Opex_fixed_HEX_SC_FP = hex.calc_Cinv_HEX(
                    Q_max_SC_FP_Wh, locator, config, 'HEX1')
                addcosts_Capex_a += Capex_a_HEX_SC_FP
                addcosts_Opex_fixed += Opex_fixed_HEX_SC_FP

                Q_max_PVT_Wh = solarFeat.Q_nom_PVT_Wh * master_to_slave_vars.SOLAR_PART_PVT * share
                Capex_a_HEX_PVT, Opex_fixed_HEX_PVT = hex.calc_Cinv_HEX(
                    Q_max_PVT_Wh, locator, config, 'HEX1')
                addcosts_Capex_a += Capex_a_HEX_PVT
                addcosts_Opex_fixed += Opex_fixed_HEX_PVT

    # Pump operation costs
    Capex_a_pump, Opex_fixed_pump, Opex_var_pump = pumps.calc_Ctot_pump(
        master_to_slave_vars, ntwFeat, gv, locator, lca, config)
    addcosts_Capex_a += Capex_a_pump
    addcosts_Opex_fixed += Opex_fixed_pump

    # import gas consumption data from:
    if DHN_barcode.count("1") > 0 and config.optimization.isheating:
        # import gas consumption data from:
        EgasPrimaryDataframe_W = pd.read_csv(
            locator.get_optimization_slave_cost_prime_primary_energy_data(
                master_to_slave_vars.individual_number,
                master_to_slave_vars.generation_number),
            usecols=["E_gas_PrimaryPeakPower_W"])
        E_gas_primary_peak_power_W = float(np.array(EgasPrimaryDataframe_W))
        GasConnectionInvCost = ngas.calc_Cinv_gas(E_gas_primary_peak_power_W,
                                                  gv)
    else:
        GasConnectionInvCost = 0.0

    addcosts_Capex_a += GasConnectionInvCost
    # Save data
    results = pd.DataFrame({
        "Capex_a_SC": [Capex_a_SC],
        "Opex_fixed_SC": [Opex_fixed_SC],
        "Capex_a_PVT": [Capex_a_PVT],
        "Opex_fixed_PVT": [Opex_fixed_PVT],
        "Capex_a_Boiler_backup": [Capex_a_Boiler_backup],
        "Opex_fixed_Boiler_backup": [Opex_fixed_Boiler_backup],
        "Capex_a_storage_HEX": [Capex_a_HP_storage],
        "Opex_fixed_storage_HEX": [Opex_fixed_HP_storage],
        "Capex_a_storage_HP": [Capex_a_storage_HP],
        "Capex_a_CHP": [Capex_a_CHP],
        "Opex_fixed_CHP": [Opex_fixed_CHP],
        "StorageInvC": [StorageInvC],
        "StorageCostSum": [StorageInvC + Capex_a_storage_HP + Capex_a_HEX],
        "NetworkCost": [NetworkCost],
        "SubstHEXCost": [SubstHEXCost_capex],
        "DHNInvestCost": [addcosts_Capex_a - CostDiscBuild],
        "PVTHEXCost_Capex": [PVTHEXCost_Capex],
        "CostDiscBuild": [CostDiscBuild],
        "CO2DiscBuild": [CO2DiscBuild],
        "PrimDiscBuild": [PrimDiscBuild],
        "Capex_a_furnace": [Capex_a_furnace],
        "Opex_fixed_furnace": [Opex_fixed_furnace],
        "Capex_a_Boiler": [Capex_a_Boiler],
        "Opex_fixed_Boiler": [Opex_fixed_Boiler],
        "Capex_a_Boiler_peak": [Capex_a_Boiler_peak],
        "Opex_fixed_Boiler_peak": [Opex_fixed_Boiler_peak],
        "Capex_Disconnected": [Capex_Disconnected],
        "Opex_Disconnected": [Opex_Disconnected],
        "Capex_a_Lake": [Capex_a_Lake],
        "Opex_fixed_Lake": [Opex_fixed_Lake],
        "Capex_a_Sewage": [Capex_a_Sewage],
        "Opex_fixed_Sewage": [Opex_fixed_Sewage],
        "SCHEXCost_Capex": [SCHEXCost_Capex],
        "Capex_a_pump": [Capex_a_pump],
        "Opex_fixed_pump": [Opex_fixed_pump],
        "Opex_var_pump": [Opex_var_pump],
        "Sum_CAPEX": [addcosts_Capex_a],
        "Sum_OPEX_fixed": [addcosts_Opex_fixed],
        "GasConnectionInvCa": [GasConnectionInvCost],
        "CO2_PV_disconnected": [CO2_PV_disconnected],
        "cost_PV_disconnected": [cost_PV_disconnected],
        "Eprim_PV_disconnected": [Eprim_PV_disconnected]
    })
    results.to_csv(locator.get_optimization_slave_investment_cost_detailed(
        master_to_slave_vars.individual_number,
        master_to_slave_vars.generation_number),
                   sep=',')
    return (addcosts_Capex_a + addcosts_Opex_fixed, addCO2, addPrim)