def calc_Ctot_cs_building_scale_buildings(network_info):
    """
    Caculates the space cooling cost of disconnected buildings.
    The calculation for partially disconnected buildings is done in calc_Ctot_cs_building_scale_loads.
    :param network_info: an object storing information of the current network
    :return:
    """
    ## Calculate disconnected heat load costs
    dis_opex = 0.0
    dis_capex = 0.0
    if len(network_info.disconnected_buildings_index) > 0:  # we have disconnected buildings
        # Make sure files to read in exist
        for building_index, building in enumerate(network_info.building_names):  # iterate through all buildings
            Opex_var_system = 0.0
            if building_index in network_info.disconnected_buildings_index:  # disconnected building
                # Read in demand of building
                building_demand = pd.read_csv(network_info.locator.get_demand_results_file(building))
                # sum up demand of all loads
                demand_hourly_kWh = building_demand['Qcs_sys_scu_kWh'].abs() + \
                                    building_demand['Qcs_sys_ahu_kWh'].abs() + \
                                    building_demand['Qcs_sys_aru_kWh'].abs()
                # calculate peak demand
                peak_demand_kW = demand_hourly_kWh.abs().max()
                print('Calculate cost of disconnected building production at building ', building)
                if network_info.yearly_cost_calculations:
                    demand_annual_kWh = demand_hourly_kWh.sum()
                    # calculate plant COP according to the cold water supply temperature in SG context
                    supplied_systems = find_supplied_systems_annual(network_info, building_demand,
                                                                    ['ahu', 'aru', 'scu'], dis_build=True)
                    COP_chiller_system, COP_chiller = VCCModel.calc_VCC_COP(network_info.weather_data, supplied_systems,
                                                                            centralized=False)
                    # calculate cost of producing cooling
                    Opex_var_system = demand_annual_kWh / COP_chiller_system * 1000 * network_info.prices.ELEC_PRICE
                    # calculate chiller heat rejection via CT
                    Q_peak_CT_kW = calc_CT_load_from_chiller_load(COP_chiller, peak_demand_kW)
                else:
                    Q_CT_kW = [0] * HOURS_IN_YEAR
                    for t in range(HOURS_IN_YEAR):
                        supplied_systems = find_supplied_systems_t(network_info, t, building_demand,
                                                                   ['ahu', 'aru', 'scu'], dis_build=True)
                        # calculate COP of plant operation in this hour based on supplied loads
                        # calculate plant COP according to the cold water supply temperature in SG context
                        COP_chiller_system, COP_chiller = VCCModel.calc_VCC_COP(network_info.weather_data, supplied_systems,
                                                                                centralized=False)
                        # calculate cost of producing cooling
                        Opex_var_system += abs(demand_hourly_kWh[
                                                  t]) / COP_chiller_system * 1000 * network_info.prices.ELEC_PRICE
                        # calculate chiller heat rejection via CT
                        Q_CT_kW[t] = calc_CT_load_from_chiller_load(COP_chiller, abs(demand_hourly_kWh[t]))
                    Q_peak_CT_kW = max(Q_CT_kW)

                # calculate cost of chiller and cooling tower at building level
                Capex_a_chiller_USD, Opex_fixed_chiller, _ = VCCModel.calc_Cinv_VCC(peak_demand_kW * 1000, network_info.locator, 'CH3')
                Capex_a_CT_USD, Opex_fixed_CT, _ = CTModel.calc_Cinv_CT(Q_peak_CT_kW * 1000, network_info.locator, 'CT1')
                # sum up costs
                dis_opex += Opex_var_system + Opex_fixed_chiller + Opex_fixed_CT
                dis_capex += Capex_a_chiller_USD + Capex_a_CT_USD

    dis_total = dis_opex + dis_capex
    return dis_total, dis_opex, dis_capex
Exemple #2
0
def calc_Ctot_cs_building_scale_loads(network_info):
    """
    Calculates the space cooling cost of disconnected loads at the building level.
    The calculation for entirely disconnected buildings is done in calc_Ctot_cs_building_scale_buildings.
    :param Thermal_Network network_info: an object storing information of the current network
    :return:
    """
    disconnected_systems = []
    dis_opex = 0
    dis_capex = 0
    '''
        for system in optimal_network.full_heating_systems:
            if system not in optimal_network.config.thermal_network.substation_heating_systems:
                disconnected_systems.append(system)
        # Make sure files to read in exist
        for system in disconnected_systems:
            for building in optimal_network.building_names:
                assert optimal_network.locator.get_optimization_building_scale_folder_building_result_heating(building), "Missing diconnected building files. Please run disconnected_buildings_heating first."
            # Read in disconnected cost of all buildings
                disconnected_cost = optimal_network.locator.get_optimization_building_scale_folder_building_result_heating(building)
    '''
    if network_info.network_type == 'DC':
        supplied_systems = []
        # iterate through all possible cooling systems
        for system in network_info.full_cooling_systems:

            if system not in network_info.substation_cooling_systems:
                # add system to list of loads that are supplied at building level
                disconnected_systems.append(system)
        if len(disconnected_systems) > 0:
            # check if we have any disconnected systems
            system_string = find_cooling_systems_string(disconnected_systems)
            # iterate through all buildings
            for building_index, building in enumerate(
                    network_info.building_names):
                Opex_var_system = 0.0
                if building_index not in network_info.disconnected_buildings_index:
                    # if this building is disconnected it will be calculated separately
                    # Read in building demand
                    building_demand = pd.read_csv(
                        network_info.locator.get_demand_results_file(building))
                    if not system_string:
                        # this means there are no disconnected loads. Shouldn't happen but is a fail-safe
                        peak_demand_kW = 0.0
                        disconnected_demand_t_sum = 0.0
                    else:
                        for system_index, system in enumerate(
                                system_string
                        ):  # iterate through all disconnected loads
                            # go through all systems and sum up demand values
                            if system_index == 0:
                                disconnected_demand_t = building_demand[system]
                            else:
                                disconnected_demand_t = disconnected_demand_t + building_demand[
                                    system]
                        peak_demand_kW = disconnected_demand_t.abs().max(
                        )  # calculate peak demand of all disconnected systems
                        disconnected_demand_t_sum = disconnected_demand_t.abs(
                        ).sum()
                    print 'Calculate cost of disconnected loads in building ', building
                    if network_info.yearly_cost_calculations:
                        supplied_systems = find_supplied_systems_annual(
                            network_info, building_demand, supplied_systems)
                        COP_chiller_system, COP_chiller = VCCModel.calc_VCC_COP(
                            network_info.weather_data,
                            system_string,
                            centralized=False)
                        # calculate cost of producing cooling
                        Opex_var_system += disconnected_demand_t_sum / COP_chiller_system * 1000 * network_info.prices.ELEC_PRICE
                        # calculate chiller heat rejection via CT
                        Q_peak_CT_kW = calc_CT_load_from_chiller_load(
                            COP_chiller, peak_demand_kW)
                    else:
                        Q_CT_kW = [0] * HOURS_IN_YEAR
                        for t in range(HOURS_IN_YEAR):
                            # calculate COP of chiller and CT operation in this hour based on supplied loads
                            # calculate chiller COP according to the cold water supply temperature in SG context
                            supplied_systems = find_supplied_systems_t(
                                network_info, t, building_demand,
                                supplied_systems)
                            if len(supplied_systems) > 0:
                                COP_chiller_system, COP_chiller = VCCModel.calc_VCC_COP(
                                    network_info.weather_data,
                                    supplied_systems,
                                    centralized=False)
                                # calculate cost of producing cooling
                                Opex_var_system += abs(
                                    disconnected_demand_t[t]
                                ) / COP_chiller_system * 1000 * network_info.prices.ELEC_PRICE
                                # calculate chiller heat rejection via CT
                                Q_CT_kW[t] = calc_CT_load_from_chiller_load(
                                    COP_chiller, abs(disconnected_demand_t[t]))
                        Q_peak_CT_kW = max(Q_CT_kW)

                    # calculate disconnected systems cost of disconnected loads. Assumes that all these loads are supplied by one chiller, unless this exceeds maximum chiller capacity of database
                    Capex_a_chiller_USD, Opex_fixed_chiller, _ = VCCModel.calc_Cinv_VCC(
                        peak_demand_kW * 1000, network_info.locator, 'CH3')
                    Capex_a_CT_USD, Opex_fixed_CT, _ = CTModel.calc_Cinv_CT(
                        Q_peak_CT_kW * 1000, network_info.locator, 'CT1')
                    # sum up costs
                    dis_opex += Opex_var_system + Opex_fixed_chiller + Opex_fixed_CT
                    dis_capex += Capex_a_chiller_USD + Capex_a_CT_USD

    dis_total = dis_opex + dis_capex
    return dis_total, dis_opex, dis_capex
Exemple #3
0
def calc_Ctot_cooling_plants(network_info):
    """
    Calculates costs of centralized cooling plants (chillers and cooling towers).

    :param NetworkInfo network_info: an object storing information of the current network
    :return:
    """

    # read in plant heat requirement
    plant_heat_hourly_kWh = pd.read_csv(
        network_info.locator.get_thermal_network_plant_heat_requirement_file(
            network_info.network_type, network_info.network_names))
    # read in number of plants
    number_of_plants = len(plant_heat_hourly_kWh.columns)

    plant_heat_original_kWh = plant_heat_hourly_kWh.copy()
    plant_heat_peak_kW_list = plant_heat_hourly_kWh.abs().max(
        axis=0).values  # calculate peak demand
    plant_heat_sum_kWh_list = plant_heat_hourly_kWh.abs().sum(
    ).values  # calculate aggregated demand

    Opex_var_plant = 0.0
    Opex_fixed_plant = 0.0
    Capex_a_chiller = 0.0
    Capex_a_CT = 0.0

    # calculate cost of chiller heat production and chiller capex and opex
    for plant_number in range(number_of_plants):  # iterate through all plants
        if number_of_plants > 1:
            plant_heat_peak_kW = plant_heat_peak_kW_list[plant_number]
        else:
            plant_heat_peak_kW = plant_heat_peak_kW_list[0]
        plant_heat_yearly_kWh = plant_heat_sum_kWh_list[plant_number]
        print 'Annual plant heat production:', round(plant_heat_yearly_kWh,
                                                     0), '[kWh]'

        # Read in building demand
        building_demand = {}
        for building in network_info.building_names:
            building_demand[building] = pd.read_csv(
                network_info.locator.get_demand_results_file(building))

        Capex_a_chiller_USD = 0.0
        Opex_fixed_chiller = 0.0
        Capex_a_CT_USD = 0.0
        Opex_fixed_CT = 0.0

        if plant_heat_peak_kW > 0:  # we have non 0 demand
            peak_demand_W = plant_heat_peak_kW * 1000  # convert to W
            print 'Calculating cost of heat production at plant number: ', (
                plant_number + 1)
            if network_info.config.thermal_network_optimization.yearly_cost_calculations:
                # calculates operation costs with yearly approximation

                # check which systems are supplied by cooling plants, this is either defined by the optimization
                # or given as a user input from config.
                supplied_systems = find_supplied_systems_annual(
                    network_info, building_demand,
                    network_info.full_cooling_systems)

                # calculate the COP based on the actually supplied demands.
                COP_plant, COP_chiller = VCCModel.calc_VCC_COP(
                    network_info.weather_data,
                    supplied_systems,
                    centralized=True)
                Opex_var_plant += abs(
                    plant_heat_yearly_kWh
                ) / COP_plant * 1000 * network_info.prices.ELEC_PRICE
            else:
                # calculates operation costs with hourly simulation
                for t in range(HOURS_IN_YEAR):
                    #     calculate COP of plant operation in this hour based on supplied loads
                    #     Depending on the demand of that hour, the COP will change.
                    #     E.g. supplied systems = ahu, aru:
                    #     t = 10 we have demand for ahu and aru, so the COP is calculated using ahu and aru
                    #     t = 11 we only have ahu demand, so COP is calculated using ahu only
                    #     t = 12 we only have aru demand, so COP is calculated using aru only
                    #     ... etc.
                    supplied_systems = find_supplied_systems_t(
                        network_info, t, building_demand,
                        network_info.full_cooling_systems)
                    COP_plant, COP_chiller = VCCModel.calc_VCC_COP(
                        network_info.weather_data,
                        supplied_systems,
                        centralized=True)
                    # calculate cost of producing cooling
                    column_name = plant_heat_original_kWh.columns[plant_number]
                    Opex_var_plant += abs(
                        plant_heat_original_kWh[column_name][t]
                    ) / COP_plant * 1000 * network_info.prices.ELEC_PRICE

            # calculate equipment cost of chiller and cooling tower

            Capex_a_chiller_USD, Opex_fixed_chiller, _ = VCCModel.calc_Cinv_VCC(
                peak_demand_W, network_info.locator, 'CH1')
            Capex_a_CT_USD, Opex_fixed_CT, _ = CTModel.calc_Cinv_CT(
                peak_demand_W, network_info.locator, 'CT1')
        # sum over all plants
        Capex_a_chiller += Capex_a_chiller_USD
        Capex_a_CT += Capex_a_CT_USD
        Opex_fixed_plant += Opex_fixed_chiller + Opex_fixed_CT

    return Opex_fixed_plant, Opex_var_plant, Capex_a_chiller, Capex_a_CT
def coolingMain(locator, configKey, ntwFeat, HRdata, gv):
    """
    Computes the parameters for the cooling of the complete DCN
    
    Parameters
    ----------
    locator : string
        path to res folder
    configKey : string
        configuration key for the DHN
    ntwFeat : class ntwFeatures
    HRdata : inf
        0 if no data heat recovery, 1 if so
    
    Returns
    -------
    (costs, co2, prim) : tuple
    
    """

    ############# Recover the cooling needs

    # Space cooling previously aggregated in the substation routine
    df = pd.read_csv(
        locator.pathNtwRes + "/Network_summary_result_all.csv",
        usecols=["T_sst_cool_return_netw_total", "mdot_cool_netw_total"])
    coolArray = np.nan_to_num(np.array(df))
    TsupCool = gv.TsupCool

    # Data center cooling, (treated separately for each building)
    df = pd.read_csv(locator.get_total_demand(),
                     usecols=["Name", "Qcdataf_MWhyr"])
    arrayData = np.array(df)

    # Ice hockey rings, (treated separately for each building)
    df = pd.read_csv(locator.get_total_demand(),
                     usecols=["Name", "Qcref_MWhyr"])
    arrayQice = np.array(df)

    ############# Recover the heat already taken from the lake by the heat pumps
    try:
        os.chdir(locator.pathSlaveRes)
        fNameSlaveRes = configKey + "PPActivationPattern.csv"

        dfSlave = pd.read_csv(fNameSlaveRes, usecols=["Qcold_HPLake"])

        QlakeArray = np.array(dfSlave)
        Qlake = np.sum(QlakeArray)

    except:
        Qlake = 0

    Qavail = gv.DeltaU + Qlake
    print Qavail, "Qavail"

    ############# Output results
    costs = ntwFeat.pipesCosts_DCN
    CO2 = 0
    prim = 0

    nBuild = int(np.shape(arrayData)[0])
    nHour = int(np.shape(coolArray)[0])
    CTLoad = np.zeros(nHour)
    VCCnom = 0

    calFactor = 0
    TotalCool = 0

    ############ Function for cooling operation
    def coolOperation(dataArray, el, QavailIni, TempSup=0):
        toTotalCool = 0
        toCalfactor = 0
        toCosts = 0
        toCO2 = 0
        toPrim = 0

        QavailCopy = QavailIni
        VCCnomIni = 0

        for i in range(el):

            if TempSup > 0:
                Tsup = TempSup
                Tret = dataArray[i][-2]
                mdot = abs(dataArray[i][-1])
            else:
                Tsup = dataArray[i][-3] + 273
                Tret = dataArray[i][-2] + 273
                mdot = abs(dataArray[i][-1] * 1E3 / gv.cp)

            Qneed = abs(mdot * gv.cp * (Tret - Tsup))
            toTotalCool += Qneed

            if QavailCopy - Qneed >= 0:  # Free cooling possible from the lake
                QavailCopy -= Qneed

                # Delta P from linearization after network optimization
                deltaP = 2 * (gv.DeltaP_Coeff * mdot + gv.DeltaP_Origin)

                toCalfactor += deltaP * mdot / 1000 / gv.etaPump
                toCosts += deltaP * mdot / 1000 * gv.ELEC_PRICE / gv.etaPump
                toCO2 += deltaP * mdot / 1000 * gv.EL_TO_CO2 / gv.etaPump * 0.0036
                toPrim += deltaP * mdot / 1000 * gv.EL_TO_OIL_EQ / gv.etaPump * 0.0036

            else:
                print "Lake exhausted !"
                wdot, qhotdot = VCCModel.calc_VCC(mdot, Tsup, Tret, gv)
                if Qneed > VCCnomIni:
                    VCCnomIni = Qneed * (1 + gv.Qmargin_Disc)

                toCosts += wdot * gv.ELEC_PRICE
                toCO2 += wdot * gv.EL_TO_CO2 * 3600E-6
                toPrim += wdot * gv.EL_TO_OIL_EQ * 3600E-6

                CTLoad[i] += qhotdot

        return toCosts, toCO2, toPrim, toCalfactor, toTotalCool, QavailCopy, VCCnomIni

    ########## Cooling operation with Circulating pump and VCC

    print "Space cooling operation"
    toCosts, toCO2, toPrim, toCalfactor, toTotalCool, QavailCopy, VCCnomIni = coolOperation(
        coolArray, nHour, Qavail, TempSup=TsupCool)
    costs += toCosts
    CO2 += toCO2
    prim += toPrim
    calFactor += toCalfactor
    TotalCool += toTotalCool
    VCCnom = max(VCCnom, VCCnomIni)
    Qavail = QavailCopy
    print Qavail, "Qavail after space cooling"

    mdotMax = np.amax(coolArray[:, 1])
    costs += PumpModel.Pump_Cost(2 * ntwFeat.DeltaP_DCN, mdotMax, gv.etaPump,
                                 gv)

    if HRdata == 0:
        print "Data centers cooling operation"
        for i in range(nBuild):
            if arrayData[i][1] > 0:
                buildName = arrayData[i][0]
                print buildName
                df = pd.read_csv(
                    locator.get_demand_results_file(buildName),
                    usecols=["Tsdata_C", "Trdata_C", "mcpdata_kWC"])
                arrayBuild = np.array(df)

                mdotMaxData = abs(np.amax(arrayBuild[:, -1]) / gv.cp * 1E3)
                costs += PumpModel.Pump_Cost(2 * ntwFeat.DeltaP_DCN,
                                             mdotMaxData, gv.etaPump, gv)

                toCosts, toCO2, toPrim, toCalfactor, toTotalCool, QavailCopy, VCCnomIni = coolOperation(
                    arrayBuild, nHour, Qavail)
                costs += toCosts
                CO2 += toCO2
                prim += toPrim
                calFactor += toCalfactor
                TotalCool += toTotalCool
                VCCnom = max(VCCnom, VCCnomIni)
                Qavail = QavailCopy
                print Qavail, "Qavail after data center"

    print "refrigeration cooling operation"
    for i in range(nBuild):
        if arrayQice[i][1] > 0:
            buildName = arrayQice[i][0]
            print buildName
            df = pd.read_csv(locator.pathRaw + "/" + buildName + ".csv",
                             usecols=["Tsref_C", "Trref_C", "mcpref_kWC"])
            arrayBuild = np.array(df)

            mdotMaxice = abs(np.amax(arrayBuild[:, -1]) / gv.cp * 1E3)
            costs += PumpModel.Pump_Cost(2 * ntwFeat.DeltaP_DCN, mdotMaxice,
                                         gv.etaPump, gv)

            toCosts, toCO2, toPrim, toCalfactor, toTotalCool, QavailCopy, VCCnomIni = coolOperation(
                arrayBuild, nHour, Qavail)
            costs += toCosts
            CO2 += toCO2
            prim += toPrim
            calFactor += toCalfactor
            TotalCool += toTotalCool
            VCCnom = max(VCCnom, VCCnomIni)
            Qavail = QavailCopy
            print Qavail, "Qavail after ice"

    print costs, CO2, prim, "operation for cooling"
    print TotalCool, "TotalCool"

    ########## Operation of the cooling tower
    CTnom = np.amax(CTLoad)
    costCopy = costs
    if CTnom > 0:
        for i in range(nHour):
            wdot = CTModel.calc_CT(CTLoad[i], CTnom, gv)

            costs += wdot * gv.ELEC_PRICE
            CO2 += wdot * gv.EL_TO_CO2 * 3600E-6
            prim += wdot * gv.EL_TO_OIL_EQ * 3600E-6

        print costs - costCopy, "costs after operation of CT"

    ########## Add investment costs

    costs += VCCModel.calc_Cinv_VCC(VCCnom, gv)
    print VCCModel.calc_Cinv_VCC(VCCnom, gv), "InvC VCC"
    costs += CTModel.calc_Cinv_CT(CTnom, gv)
    print CTModel.calc_Cinv_CT(CTnom, gv), "InvC CT"

    ########### Adjust and add the pumps for filtering and pre-treatment of the water
    calibration = calFactor / 50976000
    print calibration, "adjusting factor"

    extraElec = (127865400 + 85243600) * calibration
    costs += extraElec * gv.ELEC_PRICE
    CO2 += extraElec * gv.EL_TO_CO2 * 3600E-6
    prim += extraElec * gv.EL_TO_OIL_EQ * 3600E-6

    return (costs, CO2, prim)
Exemple #5
0
def preprocessing_cost_data(locator, data_raw, individual, generations,
                            data_address, config):

    string_network = data_raw['network'].loc[individual].values[0]
    total_demand = pd.read_csv(locator.get_total_demand())
    building_names = total_demand.Name.values
    individual_barcode_list = data_raw['individual_barcode'].loc[
        individual].values[0]

    # The current structure of CEA has the following columns saved, in future, this will be slightly changed and
    # correspondingly these columns_of_saved_files needs to be changed
    columns_of_saved_files = [
        'CHP/Furnace', 'CHP/Furnace Share', 'Base Boiler', 'Base Boiler Share',
        'Peak Boiler', 'Peak Boiler Share', 'Heating Lake',
        'Heating Lake Share', 'Heating Sewage', 'Heating Sewage Share', 'GHP',
        'GHP Share', 'Data Centre', 'Compressed Air', 'PV', 'PV Area Share',
        'PVT', 'PVT Area Share', 'SC_ET', 'SC_ET Area Share', 'SC_FP',
        'SC_FP Area Share', 'DHN Temperature', 'DHN unit configuration',
        'Lake Cooling', 'Lake Cooling Share', 'VCC Cooling',
        'VCC Cooling Share', 'Absorption Chiller', 'Absorption Chiller Share',
        'Storage', 'Storage Share', 'DCN Temperature', 'DCN unit configuration'
    ]
    for i in building_names:  # DHN
        columns_of_saved_files.append(str(i) + ' DHN')

    for i in building_names:  # DCN
        columns_of_saved_files.append(str(i) + ' DCN')

    df_current_individual = pd.DataFrame(
        np.zeros(shape=(1, len(columns_of_saved_files))),
        columns=columns_of_saved_files)
    for i, ind in enumerate((columns_of_saved_files)):
        df_current_individual[ind] = individual_barcode_list[i]

    data_address = data_address[data_address['individual_list'] == individual]

    generation_number = data_address['generation_number_address'].values[0]
    individual_number = data_address['individual_number_address'].values[0]
    # get data about the activation patterns of these buildings (main units)

    if config.multi_criteria.network_type == 'DH':
        building_demands_df = pd.read_csv(
            locator.get_optimization_network_results_summary(
                string_network)).set_index("DATE")
        data_activation_path = os.path.join(
            locator.get_optimization_slave_heating_activation_pattern(
                individual_number, generation_number))
        df_heating = pd.read_csv(data_activation_path).set_index("DATE")

        data_activation_path = os.path.join(
            locator.
            get_optimization_slave_electricity_activation_pattern_heating(
                individual_number, generation_number))
        df_electricity = pd.read_csv(data_activation_path).set_index("DATE")

        # get data about the activation patterns of these buildings (storage)
        data_storage_path = os.path.join(
            locator.get_optimization_slave_storage_operation_data(
                individual_number, generation_number))
        df_SO = pd.read_csv(data_storage_path).set_index("DATE")

        # join into one database
        data_processed = df_heating.join(df_electricity).join(df_SO).join(
            building_demands_df)

    elif config.multi_criteria.network_type == 'DC':

        data_costs = pd.read_csv(
            os.path.join(
                locator.
                get_optimization_slave_investment_cost_detailed_cooling(
                    individual_number, generation_number)))
        data_cooling = pd.read_csv(
            os.path.join(
                locator.get_optimization_slave_cooling_activation_pattern(
                    individual_number, generation_number)))
        data_electricity = pd.read_csv(
            os.path.join(
                locator.
                get_optimization_slave_electricity_activation_pattern_cooling(
                    individual_number, generation_number)))

        # Total CAPEX calculations
        # Absorption Chiller
        Absorption_chiller_cost_data = pd.read_excel(
            locator.get_supply_systems(config.region),
            sheetname="Absorption_chiller",
            usecols=[
                'type', 'code', 'cap_min', 'cap_max', 'a', 'b', 'c', 'd', 'e',
                'IR_%', 'LT_yr', 'O&M_%'
            ])
        Absorption_chiller_cost_data = Absorption_chiller_cost_data[
            Absorption_chiller_cost_data['type'] == 'double']
        max_ACH_chiller_size = max(
            Absorption_chiller_cost_data['cap_max'].values)
        Inv_IR = (Absorption_chiller_cost_data.iloc[0]['IR_%']) / 100
        Inv_LT = Absorption_chiller_cost_data.iloc[0]['LT_yr']
        Q_ACH_max_W = data_cooling['Q_from_ACH_W'].max()
        Q_ACH_max_W = Q_ACH_max_W * (1 + SIZING_MARGIN)
        number_of_ACH_chillers = max(
            int(ceil(Q_ACH_max_W / max_ACH_chiller_size)), 1)
        Q_nom_ACH_W = Q_ACH_max_W / number_of_ACH_chillers
        Capex_a_ACH, Opex_fixed_ACH = calc_Cinv(Q_nom_ACH_W, locator, 'double',
                                                config)
        Capex_total_ACH = (Capex_a_ACH * ((1 + Inv_IR)**Inv_LT - 1) /
                           (Inv_IR) *
                           (1 + Inv_IR)**Inv_LT) * number_of_ACH_chillers
        data_costs['Capex_total_ACH'] = Capex_total_ACH
        data_costs['Opex_total_ACH'] = np.sum(
            data_cooling['Opex_var_ACH']) + data_costs['Opex_fixed_ACH']

        # VCC
        VCC_cost_data = pd.read_excel(locator.get_supply_systems(
            config.region),
                                      sheetname="Chiller")
        VCC_cost_data = VCC_cost_data[VCC_cost_data['code'] == 'CH3']
        max_VCC_chiller_size = max(VCC_cost_data['cap_max'].values)
        Inv_IR = (VCC_cost_data.iloc[0]['IR_%']) / 100
        Inv_LT = VCC_cost_data.iloc[0]['LT_yr']
        Q_VCC_max_W = data_cooling['Q_from_VCC_W'].max()
        Q_VCC_max_W = Q_VCC_max_W * (1 + SIZING_MARGIN)
        number_of_VCC_chillers = max(
            int(ceil(Q_VCC_max_W / max_VCC_chiller_size)), 1)
        Q_nom_VCC_W = Q_VCC_max_W / number_of_VCC_chillers
        Capex_a_VCC, Opex_fixed_VCC = calc_Cinv_VCC(Q_nom_VCC_W, locator,
                                                    config, 'CH3')
        Capex_total_VCC = (Capex_a_VCC * ((1 + Inv_IR)**Inv_LT - 1) /
                           (Inv_IR) *
                           (1 + Inv_IR)**Inv_LT) * number_of_VCC_chillers
        data_costs['Capex_total_VCC'] = Capex_total_VCC
        data_costs['Opex_total_VCC'] = np.sum(
            data_cooling['Opex_var_VCC']) + data_costs['Opex_fixed_VCC']

        # VCC Backup
        Q_VCC_backup_max_W = data_cooling['Q_from_VCC_backup_W'].max()
        Q_VCC_backup_max_W = Q_VCC_backup_max_W * (1 + SIZING_MARGIN)
        number_of_VCC_backup_chillers = max(
            int(ceil(Q_VCC_backup_max_W / max_VCC_chiller_size)), 1)
        Q_nom_VCC_backup_W = Q_VCC_backup_max_W / number_of_VCC_backup_chillers
        Capex_a_VCC_backup, Opex_fixed_VCC_backup = calc_Cinv_VCC(
            Q_nom_VCC_backup_W, locator, config, 'CH3')
        Capex_total_VCC_backup = (
            Capex_a_VCC_backup * ((1 + Inv_IR)**Inv_LT - 1) / (Inv_IR) *
            (1 + Inv_IR)**Inv_LT) * number_of_VCC_backup_chillers
        data_costs['Capex_total_VCC_backup'] = Capex_total_VCC_backup
        data_costs['Opex_total_VCC_backup'] = np.sum(
            data_cooling['Opex_var_VCC_backup']
        ) + data_costs['Opex_fixed_VCC_backup']

        # Storage Tank
        storage_cost_data = pd.read_excel(locator.get_supply_systems(
            config.region),
                                          sheetname="TES")
        storage_cost_data = storage_cost_data[storage_cost_data['code'] ==
                                              'TES2']
        Inv_IR = (storage_cost_data.iloc[0]['IR_%']) / 100
        Inv_LT = storage_cost_data.iloc[0]['LT_yr']
        Capex_a_storage_tank = data_costs['Capex_a_Tank'][0]
        Capex_total_storage_tank = (Capex_a_storage_tank *
                                    ((1 + Inv_IR)**Inv_LT - 1) / (Inv_IR) *
                                    (1 + Inv_IR)**Inv_LT)
        data_costs['Capex_total_storage_tank'] = Capex_total_storage_tank
        data_costs['Opex_total_storage_tank'] = np.sum(
            data_cooling['Opex_var_VCC_backup']
        ) + data_costs['Opex_fixed_Tank']

        # Cooling Tower
        CT_cost_data = pd.read_excel(locator.get_supply_systems(config.region),
                                     sheetname="CT")
        CT_cost_data = CT_cost_data[CT_cost_data['code'] == 'CT1']
        max_CT_size = max(CT_cost_data['cap_max'].values)
        Inv_IR = (CT_cost_data.iloc[0]['IR_%']) / 100
        Inv_LT = CT_cost_data.iloc[0]['LT_yr']
        Qc_CT_max_W = data_cooling['Qc_CT_associated_with_all_chillers_W'].max(
        )
        number_of_CT = max(int(ceil(Qc_CT_max_W / max_CT_size)), 1)
        Qnom_CT_W = Qc_CT_max_W / number_of_CT
        Capex_a_CT, Opex_fixed_CT = calc_Cinv_CT(Qnom_CT_W, locator, config,
                                                 'CT1')
        Capex_total_CT = (Capex_a_CT * ((1 + Inv_IR)**Inv_LT - 1) / (Inv_IR) *
                          (1 + Inv_IR)**Inv_LT) * number_of_CT
        data_costs['Capex_total_CT'] = Capex_total_CT
        data_costs['Opex_total_CT'] = np.sum(
            data_cooling['Opex_var_CT']) + data_costs['Opex_fixed_CT']

        # CCGT
        CCGT_cost_data = pd.read_excel(locator.get_supply_systems(
            config.region),
                                       sheetname="CCGT")
        technology_code = list(set(CCGT_cost_data['code']))
        CCGT_cost_data = CCGT_cost_data[CCGT_cost_data['code'] ==
                                        technology_code[0]]
        Inv_IR = (CCGT_cost_data.iloc[0]['IR_%']) / 100
        Inv_LT = CCGT_cost_data.iloc[0]['LT_yr']
        Capex_a_CCGT = data_costs['Capex_a_CCGT'][0]
        Capex_total_CCGT = (Capex_a_CCGT * ((1 + Inv_IR)**Inv_LT - 1) /
                            (Inv_IR) * (1 + Inv_IR)**Inv_LT)
        data_costs['Capex_total_CCGT'] = Capex_total_CCGT
        data_costs['Opex_total_CCGT'] = np.sum(
            data_cooling['Opex_var_CCGT']) + data_costs['Opex_fixed_CCGT']

        # pump
        config.restricted_to = None  # FIXME: remove this later
        config.thermal_network.network_type = config.multi_criteria.network_type
        config.thermal_network.network_names = []
        network_features = network_opt.network_opt_main(config, locator)
        DCN_barcode = ""
        for name in building_names:
            DCN_barcode += str(df_current_individual[name + ' DCN'][0])
        if df_current_individual['Data Centre'][0] == 1:
            df = pd.read_csv(
                locator.get_optimization_network_data_folder(
                    "Network_summary_result_" + hex(int(str(DCN_barcode), 2)) +
                    ".csv"),
                usecols=[
                    "mdot_cool_space_cooling_and_refrigeration_netw_all_kgpers"
                ])
        else:
            df = pd.read_csv(
                locator.get_optimization_network_data_folder(
                    "Network_summary_result_" + hex(int(str(DCN_barcode), 2)) +
                    ".csv"),
                usecols=[
                    "mdot_cool_space_cooling_data_center_and_refrigeration_netw_all_kgpers"
                ])
        mdotA_kgpers = np.array(df)
        mdotnMax_kgpers = np.amax(mdotA_kgpers)
        deltaPmax = np.max((network_features.DeltaP_DCN) *
                           DCN_barcode.count("1") / len(DCN_barcode))
        E_pumping_required_W = mdotnMax_kgpers * deltaPmax / DENSITY_OF_WATER_AT_60_DEGREES_KGPERM3
        P_motor_tot_W = E_pumping_required_W / PUMP_ETA  # electricty to run the motor
        Pump_max_kW = 375.0
        Pump_min_kW = 0.5
        nPumps = int(np.ceil(P_motor_tot_W / 1000.0 / Pump_max_kW))
        # if the nominal load (electric) > 375kW, a new pump is installed
        Pump_Array_W = np.zeros((nPumps))
        Pump_Remain_W = P_motor_tot_W
        Capex_total_pumps = 0
        Capex_a_total_pumps = 0
        for pump_i in range(nPumps):
            # calculate pump nominal capacity
            Pump_Array_W[pump_i] = min(Pump_Remain_W, Pump_max_kW * 1000)
            if Pump_Array_W[pump_i] < Pump_min_kW * 1000:
                Pump_Array_W[pump_i] = Pump_min_kW * 1000
            Pump_Remain_W -= Pump_Array_W[pump_i]
            pump_cost_data = pd.read_excel(locator.get_supply_systems(
                config.region),
                                           sheetname="Pump")
            pump_cost_data = pump_cost_data[pump_cost_data['code'] == 'PU1']
            # if the Q_design is below the lowest capacity available for the technology, then it is replaced by the least
            # capacity for the corresponding technology from the database
            if Pump_Array_W[pump_i] < pump_cost_data.iloc[0]['cap_min']:
                Pump_Array_W[pump_i] = pump_cost_data.iloc[0]['cap_min']
            pump_cost_data = pump_cost_data[
                (pump_cost_data['cap_min'] <= Pump_Array_W[pump_i])
                & (pump_cost_data['cap_max'] > Pump_Array_W[pump_i])]
            Inv_a = pump_cost_data.iloc[0]['a']
            Inv_b = pump_cost_data.iloc[0]['b']
            Inv_c = pump_cost_data.iloc[0]['c']
            Inv_d = pump_cost_data.iloc[0]['d']
            Inv_e = pump_cost_data.iloc[0]['e']
            Inv_IR = (pump_cost_data.iloc[0]['IR_%']) / 100
            Inv_LT = pump_cost_data.iloc[0]['LT_yr']
            Inv_OM = pump_cost_data.iloc[0]['O&M_%'] / 100
            InvC = Inv_a + Inv_b * (Pump_Array_W[pump_i])**Inv_c + (
                Inv_d + Inv_e * Pump_Array_W[pump_i]) * log(
                    Pump_Array_W[pump_i])
            Capex_total_pumps += InvC
            Capex_a_total_pumps += InvC * (Inv_IR) * (1 + Inv_IR)**Inv_LT / (
                (1 + Inv_IR)**Inv_LT - 1)
        data_costs['Capex_total_pumps'] = Capex_total_pumps
        data_costs['Opex_total_pumps'] = data_costs[
            'Opex_fixed_pump'] + data_costs['Opex_fixed_pump']

        # PV
        pv_installed_area = data_electricity['Area_PV_m2'].max()
        Capex_a_PV, Opex_fixed_PV = calc_Cinv_pv(pv_installed_area, locator,
                                                 config)
        pv_annual_production_kWh = (data_electricity['E_PV_W'].sum()) / 1000
        Opex_a_PV = calc_opex_PV(pv_annual_production_kWh, pv_installed_area)
        PV_cost_data = pd.read_excel(locator.get_supply_systems(config.region),
                                     sheetname="PV")
        technology_code = list(set(PV_cost_data['code']))
        PV_cost_data[PV_cost_data['code'] == technology_code[0]]
        Inv_IR = (PV_cost_data.iloc[0]['IR_%']) / 100
        Inv_LT = PV_cost_data.iloc[0]['LT_yr']
        Capex_total_PV = (Capex_a_PV * ((1 + Inv_IR)**Inv_LT - 1) / (Inv_IR) *
                          (1 + Inv_IR)**Inv_LT)
        data_costs['Capex_total_PV'] = Capex_total_PV
        data_costs['Opex_total_PV'] = Opex_a_PV + Opex_fixed_PV

        # Disconnected Buildings
        Capex_total_disconnected = 0
        Opex_total_disconnected = 0
        Capex_a_total_disconnected = 0

        for (index, building_name) in zip(DCN_barcode, building_names):
            if index is '0':
                df = pd.read_csv(
                    locator.
                    get_optimization_disconnected_folder_building_result_cooling(
                        building_name, configuration='AHU_ARU_SCU'))
                dfBest = df[df["Best configuration"] == 1]

                if dfBest['VCC to AHU_ARU_SCU Share'].iloc[
                        0] == 1:  #FIXME: Check for other options
                    Inv_IR = (VCC_cost_data.iloc[0]['IR_%']) / 100
                    Inv_LT = VCC_cost_data.iloc[0]['LT_yr']

                if dfBest['single effect ACH to AHU_ARU_SCU Share (FP)'].iloc[
                        0] == 1:
                    Inv_IR = (
                        Absorption_chiller_cost_data.iloc[0]['IR_%']) / 100
                    Inv_LT = Absorption_chiller_cost_data.iloc[0]['LT_yr']

                Opex_total_disconnected += dfBest[
                    "Operation Costs [CHF]"].iloc[0]
                Capex_a_total_disconnected += dfBest[
                    "Annualized Investment Costs [CHF]"].iloc[0]
                Capex_total_disconnected += (
                    dfBest["Annualized Investment Costs [CHF]"].iloc[0] *
                    ((1 + Inv_IR)**Inv_LT - 1) / (Inv_IR) *
                    (1 + Inv_IR)**Inv_LT)
        data_costs[
            'Capex_total_disconnected_Mio'] = Capex_total_disconnected / 1000000
        data_costs[
            'Opex_total_disconnected_Mio'] = Opex_total_disconnected / 1000000
        data_costs[
            'Capex_a_disconnected_Mio'] = Capex_a_total_disconnected / 1000000

        data_costs['costs_Mio'] = data_raw['population']['costs_Mio'][
            individual]
        data_costs['emissions_kiloton'] = data_raw['population'][
            'emissions_kiloton'][individual]
        data_costs['prim_energy_TJ'] = data_raw['population'][
            'prim_energy_TJ'][individual]

        # Electricity Details/Renewable Share
        total_electricity_demand_decentralized_W = np.zeros(8760)

        DCN_barcode = ""
        for name in building_names:  # identifying the DCN code
            DCN_barcode += str(
                int(df_current_individual[name + ' DCN'].values[0]))
        for i, name in zip(
                DCN_barcode, building_names
        ):  # adding the electricity demand from the decentralized buildings
            if i is '0':
                building_demand = pd.read_csv(
                    locator.get_demand_results_folder() + '//' + name + ".csv",
                    usecols=['E_sys_kWh'])

                total_electricity_demand_decentralized_W += building_demand[
                    'E_sys_kWh'] * 1000

        lca = lca_calculations(locator, config)

        data_electricity_processed = electricity_import_and_exports(
            generation_number, individual_number, locator, config)

        data_costs['Network_electricity_demand_GW'] = (
            data_electricity['E_total_req_W'].sum()) / 1000000000  # GW
        data_costs['Decentralized_electricity_demand_GW'] = (
            data_electricity_processed['E_decentralized_appliances_W'].sum()
        ) / 1000000000  # GW
        data_costs['Total_electricity_demand_GW'] = (
            data_electricity_processed['E_total_req_W'].sum()
        ) / 1000000000  # GW

        renewable_share_electricity = (data_electricity_processed['E_PV_to_directload_W'].sum() +
                                       data_electricity_processed['E_PV_to_grid_W'].sum()) * 100 / \
                                      (data_costs['Total_electricity_demand_GW'] * 1000000000)
        data_costs['renewable_share_electricity'] = renewable_share_electricity

        data_costs['Electricity_Costs_Mio'] = (
            (data_electricity_processed['E_from_grid_W'].sum() +
             data_electricity_processed['E_total_to_grid_W_negative'].sum()) *
            lca.ELEC_PRICE) / 1000000

        data_costs['Capex_a_total_Mio'] = (Capex_a_ACH * number_of_ACH_chillers + Capex_a_VCC * number_of_VCC_chillers + \
                    Capex_a_VCC_backup * number_of_VCC_backup_chillers + Capex_a_CT * number_of_CT + Capex_a_storage_tank + \
                    Capex_a_total_pumps + Capex_a_CCGT + Capex_a_PV + Capex_a_total_disconnected) / 1000000

        data_costs['Capex_a_ACH'] = Capex_a_ACH * number_of_ACH_chillers
        data_costs['Capex_a_VCC'] = Capex_a_VCC * number_of_VCC_chillers
        data_costs[
            'Capex_a_VCC_backup'] = Capex_a_VCC_backup * number_of_VCC_backup_chillers
        data_costs['Capex_a_CT'] = Capex_a_CT * number_of_CT
        data_costs['Capex_a_storage_tank'] = Capex_a_storage_tank
        data_costs['Capex_a_total_pumps'] = Capex_a_total_pumps
        data_costs['Capex_a_CCGT'] = Capex_a_CCGT
        data_costs['Capex_a_PV'] = Capex_a_PV

        data_costs['Capex_total_Mio'] = (data_costs['Capex_total_ACH'] + data_costs['Capex_total_VCC'] + data_costs['Capex_total_VCC_backup'] + \
                                    data_costs['Capex_total_storage_tank'] + data_costs['Capex_total_CT'] + data_costs['Capex_total_CCGT'] + \
                                    data_costs['Capex_total_pumps'] + data_costs['Capex_total_PV'] + Capex_total_disconnected) / 1000000

        data_costs['Opex_total_Mio'] = ((data_costs['Opex_total_ACH'] + data_costs['Opex_total_VCC'] + data_costs['Opex_total_VCC_backup'] + \
                                   data_costs['Opex_total_storage_tank'] + data_costs['Opex_total_CT'] + data_costs['Opex_total_CCGT'] + \
                                   data_costs['Opex_total_pumps'] + Opex_total_disconnected) / 1000000) + data_costs['Electricity_Costs_Mio']

        data_costs['TAC_Mio'] = data_costs['Capex_a_total_Mio'] + data_costs[
            'Opex_total_Mio']

    return data_costs
def cooling_calculations_of_DC_buildings(locator, master_to_slave_vars, ntwFeat, prices, lca, config, reduced_timesteps_flag):
    """
    Computes the parameters for the cooling of the complete DCN

    :param locator: path to res folder
    :param ntwFeat: network features
    :param prices: Prices imported from the database
    :type locator: string
    :type ntwFeat: class
    :type prices: class
    :return: costs, co2, prim
    :rtype: tuple
    """

    ############# Recover the cooling needs
    # Cooling demands in a neighborhood are divided into three categories currently. They are
    # 1. Space Cooling in buildings
    # 2. Data center Cooling
    # 3. Refrigeration Needs
    # Data center cooling can also be done by recovering the heat and heating other demands during the same time
    # whereas Space cooling and refrigeration needs are to be provided by District Cooling Network or decentralized cooling
    # Currently, all the buildings are assumed to be connected to DCN
    # In the following code, the cooling demands of Space cooling and refrigeration are first satisfied by using Lake and VCC
    # This is then followed by checking of the Heat recovery from Data Centre, if it is allowed, then the corresponding
    # cooling demand is ignored. If not, the corresponding coolind demand is also satisfied by DCN.

    t0 = time.time()
    DCN_barcode = master_to_slave_vars.DCN_barcode
    print ('Cooling Main is Running')

    # Space cooling previously aggregated in the substation routine
    if master_to_slave_vars.WasteServersHeatRecovery == 1:
        df = pd.read_csv(locator.get_optimization_network_data_folder(master_to_slave_vars.network_data_file_cooling),
                     usecols=["T_DCNf_space_cooling_and_refrigeration_sup_K", "T_DCNf_space_cooling_and_refrigeration_re_K",
                              "mdot_cool_space_cooling_and_refrigeration_netw_all_kgpers"])
        df = df.fillna(0)
        T_sup_K = df['T_DCNf_space_cooling_and_refrigeration_sup_K'].values
        T_re_K = df['T_DCNf_space_cooling_and_refrigeration_re_K'].values
        mdot_kgpers = df['mdot_cool_space_cooling_and_refrigeration_netw_all_kgpers'].values
    else:
        df = pd.read_csv(locator.get_optimization_network_data_folder(master_to_slave_vars.network_data_file_cooling),
                     usecols=["T_DCNf_space_cooling_data_center_and_refrigeration_sup_K",
                              "T_DCNf_space_cooling_data_center_and_refrigeration_re_K",
                              "mdot_cool_space_cooling_data_center_and_refrigeration_netw_all_kgpers"])
        df = df.fillna(0)
        T_sup_K = df['T_DCNf_space_cooling_data_center_and_refrigeration_sup_K'].values
        T_re_K = df['T_DCNf_space_cooling_data_center_and_refrigeration_re_K'].values
        mdot_kgpers = df['mdot_cool_space_cooling_data_center_and_refrigeration_netw_all_kgpers'].values
    DCN_operation_parameters = df.fillna(0)
    DCN_operation_parameters_array = DCN_operation_parameters.values

    Qc_DCN_W = np.array(
        pd.read_csv(locator.get_optimization_network_data_folder(master_to_slave_vars.network_data_file_cooling),
                    usecols=["Q_DCNf_space_cooling_and_refrigeration_W",
                             "Q_DCNf_space_cooling_data_center_and_refrigeration_W"]))  # importing the cooling demands of DCN (space cooling + refrigeration)
    # Data center cooling, (treated separately for each building)
    df = pd.read_csv(locator.get_total_demand(), usecols=["Name", "Qcdata_sys_MWhyr"])
    arrayData = np.array(df)

    # total cooling requirements based on the Heat Recovery Flag
    Q_cooling_req_W = np.zeros(8760)
    if master_to_slave_vars.WasteServersHeatRecovery == 0:
        for hour in range(8760):  # summing cooling loads of space cooling, refrigeration and data center
            Q_cooling_req_W[hour] = Qc_DCN_W[hour][1]
    else:
        for hour in range(8760):  # only including cooling loads of space cooling and refrigeration
            Q_cooling_req_W[hour] = Qc_DCN_W[hour][0]

    ############# Recover the heat already taken from the Lake by the heat pumps
    if config.district_heating_network:
        try:
            dfSlave = pd.read_csv(
                locator.get_optimization_slave_heating_activation_pattern(master_to_slave_vars.individual_number,
                                                                          master_to_slave_vars.generation_number),
                usecols=["Q_coldsource_HPLake_W"])
            Q_Lake_Array_W = np.array(dfSlave)

        except:
            Q_Lake_Array_W = [0]
    else:
        Q_Lake_Array_W = [0]

    ### input parameters
    Qc_VCC_max_W = master_to_slave_vars.VCC_cooling_size_W
    Qc_ACH_max_W = master_to_slave_vars.Absorption_chiller_size_W

    T_ground_K = calculate_ground_temperature(locator, config)

    # sizing cold water storage tank
    if master_to_slave_vars.Storage_cooling_size_W > 0:
        Qc_tank_discharge_peak_W = master_to_slave_vars.Storage_cooling_size_W
        Qc_tank_charge_max_W = (Qc_VCC_max_W + Qc_ACH_max_W) * 0.8  # assume reduced capacity when Tsup is lower
        peak_hour = np.argmax(Q_cooling_req_W)
        area_HEX_tank_discharege_m2, UA_HEX_tank_discharge_WperK, \
        area_HEX_tank_charge_m2, UA_HEX_tank_charge_WperK, \
        V_tank_m3 = storage_tank.calc_storage_tank_properties(DCN_operation_parameters, Qc_tank_charge_max_W,
                                                              Qc_tank_discharge_peak_W, peak_hour, master_to_slave_vars)
    else:
        Qc_tank_discharge_peak_W = 0
        Qc_tank_charge_max_W = 0
        area_HEX_tank_discharege_m2 = 0
        UA_HEX_tank_discharge_WperK = 0
        area_HEX_tank_charge_m2 = 0
        UA_HEX_tank_charge_WperK = 0
        V_tank_m3 = 0

    VCC_cost_data = pd.read_excel(locator.get_supply_systems(config.region), sheetname="Chiller")
    VCC_cost_data = VCC_cost_data[VCC_cost_data['code'] == 'CH3']
    max_VCC_chiller_size = max(VCC_cost_data['cap_max'].values)

    Absorption_chiller_cost_data = pd.read_excel(locator.get_supply_systems(config.region),
                                                 sheetname="Absorption_chiller")
    Absorption_chiller_cost_data = Absorption_chiller_cost_data[Absorption_chiller_cost_data['type'] == ACH_TYPE_DOUBLE]
    max_ACH_chiller_size = max(Absorption_chiller_cost_data['cap_max'].values)


    # deciding the number of chillers and the nominal size based on the maximum chiller size
    Qc_VCC_max_W = Qc_VCC_max_W * (1 + SIZING_MARGIN)
    Qc_ACH_max_W = Qc_ACH_max_W * (1 + SIZING_MARGIN)
    Q_peak_load_W = Q_cooling_req_W.max() * (1 + SIZING_MARGIN)

    Qc_VCC_backup_max_W = (Q_peak_load_W - Qc_ACH_max_W - Qc_VCC_max_W - Qc_tank_discharge_peak_W)

    if Qc_VCC_backup_max_W < 0:
        Qc_VCC_backup_max_W = 0

    if Qc_VCC_max_W <= max_VCC_chiller_size:
        Qnom_VCC_W = Qc_VCC_max_W
        number_of_VCC_chillers = 1
    else:
        number_of_VCC_chillers = int(ceil(Qc_VCC_max_W / max_VCC_chiller_size))
        Qnom_VCC_W = Qc_VCC_max_W / number_of_VCC_chillers

    if Qc_VCC_backup_max_W <= max_VCC_chiller_size:
        Qnom_VCC_backup_W = Qc_VCC_backup_max_W
        number_of_VCC_backup_chillers = 1
    else:
        number_of_VCC_backup_chillers = int(ceil(Qc_VCC_backup_max_W / max_VCC_chiller_size))
        Qnom_VCC_backup_W = Qc_VCC_backup_max_W / number_of_VCC_backup_chillers

    if Qc_ACH_max_W <= max_ACH_chiller_size:
        Qnom_ACH_W = Qc_ACH_max_W
        number_of_ACH_chillers = 1
    else:
        number_of_ACH_chillers = int(ceil(Qc_ACH_max_W / max_ACH_chiller_size))
        Qnom_ACH_W = Qc_ACH_max_W / number_of_ACH_chillers

    limits = {'Qc_VCC_max_W': Qc_VCC_max_W, 'Qc_ACH_max_W': Qc_ACH_max_W, 'Qc_peak_load_W': Qc_tank_discharge_peak_W,
              'Qnom_VCC_W': Qnom_VCC_W, 'number_of_VCC_chillers': number_of_VCC_chillers,
              'Qnom_ACH_W': Qnom_ACH_W, 'number_of_ACH_chillers': number_of_ACH_chillers,
              'Qnom_VCC_backup_W': Qnom_VCC_backup_W, 'number_of_VCC_backup_chillers': number_of_VCC_backup_chillers,
              'Qc_tank_discharge_peak_W': Qc_tank_discharge_peak_W, 'Qc_tank_charge_max_W': Qc_tank_charge_max_W,
              'V_tank_m3': V_tank_m3, 'T_tank_fully_charged_K': T_TANK_FULLY_CHARGED_K,
              'area_HEX_tank_discharge_m2': area_HEX_tank_discharege_m2,
              'UA_HEX_tank_discharge_WperK': UA_HEX_tank_discharge_WperK,
              'area_HEX_tank_charge_m2': area_HEX_tank_charge_m2,
              'UA_HEX_tank_charge_WperK': UA_HEX_tank_charge_WperK}

    ### input variables
    lake_available_cooling = pd.read_csv(locator.get_lake_potential(), usecols=['lake_potential'])
    Qc_available_from_lake_W = np.sum(lake_available_cooling).values[0] + np.sum(Q_Lake_Array_W)
    Qc_from_lake_cumulative_W = 0
    cooling_resource_potentials = {'T_tank_K': T_TANK_FULLY_DISCHARGED_K,
                                   'Qc_avail_from_lake_W': Qc_available_from_lake_W,
                                   'Qc_from_lake_cumulative_W': Qc_from_lake_cumulative_W}

    ############# Output results
    PipeLifeTime = 40.0  # years, Data from A&W
    PipeInterestRate = 0.05  # 5% interest rate
    network_costs_USD = ntwFeat.pipesCosts_DCN_USD * DCN_barcode.count('1') / master_to_slave_vars.total_buildings
    network_costs_a_USD = network_costs_USD * PipeInterestRate * (1+ PipeInterestRate) ** PipeLifeTime / ((1+PipeInterestRate) ** PipeLifeTime - 1)
    costs_a_USD = network_costs_a_USD
    CO2_kgCO2 = 0
    prim_MJ = 0

    nBuild = int(np.shape(arrayData)[0])
    if reduced_timesteps_flag == False:
        start_t = 0
        stop_t = int(np.shape(DCN_operation_parameters)[0])
    else:
        # timesteps in May
        start_t = 2880
        stop_t = 3624
    timesteps = range(start_t, stop_t)

    calfactor_buildings = np.zeros(8760)
    TotalCool = 0
    Qc_from_Lake_W = np.zeros(8760)
    Qc_from_VCC_W = np.zeros(8760)
    Qc_from_ACH_W = np.zeros(8760)
    Qc_from_storage_tank_W = np.zeros(8760)
    Qc_from_VCC_backup_W = np.zeros(8760)

    Qc_req_from_CT_W = np.zeros(8760)
    Qh_req_from_CCGT_W = np.zeros(8760)
    Qh_from_CCGT_W = np.zeros(8760)
    E_gen_CCGT_W = np.zeros(8760)

    opex_var_Lake_USD = np.zeros(8760)
    opex_var_VCC_USD = np.zeros(8760)
    opex_var_ACH_USD = np.zeros(8760)
    opex_var_VCC_backup_USD = np.zeros(8760)
    opex_var_CCGT_USD = np.zeros(8760)
    opex_var_CT_USD = np.zeros(8760)
    E_used_Lake_W = np.zeros(8760)
    E_used_VCC_W = np.zeros(8760)
    E_used_VCC_backup_W = np.zeros(8760)
    E_used_ACH_W = np.zeros(8760)
    E_used_CT_W = np.zeros(8760)
    co2_Lake_kgCO2 = np.zeros(8760)
    co2_VCC_kgCO2 = np.zeros(8760)
    co2_ACH_kgCO2 = np.zeros(8760)
    co2_VCC_backup_kgCO2 = np.zeros(8760)
    co2_CCGT_kgCO2 = np.zeros(8760)
    co2_CT_kgCO2 = np.zeros(8760)
    prim_energy_Lake_MJ = np.zeros(8760)
    prim_energy_VCC_MJ = np.zeros(8760)
    prim_energy_ACH_MJ = np.zeros(8760)
    prim_energy_VCC_backup_MJ = np.zeros(8760)
    prim_energy_CCGT_MJ = np.zeros(8760)
    prim_energy_CT_MJ = np.zeros(8760)
    NG_used_CCGT_W = np.zeros(8760)
    calfactor_total = 0

    for hour in timesteps:  # cooling supply for all buildings excluding cooling loads from data centers
        performance_indicators_output, \
        Qc_supply_to_DCN, calfactor_output, \
        Qc_CT_W, Qh_CHP_ACH_W, \
        cooling_resource_potentials = cooling_resource_activator(mdot_kgpers[hour], T_sup_K[hour], T_re_K[hour],
                                                                 limits, cooling_resource_potentials,
                                                                 T_ground_K[hour], prices, lca, master_to_slave_vars, config, Q_cooling_req_W[hour], locator)

        print (hour)
        # save results for each time-step
        opex_var_Lake_USD[hour] = performance_indicators_output['Opex_var_Lake_USD']
        opex_var_VCC_USD[hour] = performance_indicators_output['Opex_var_VCC_USD']
        opex_var_ACH_USD[hour] = performance_indicators_output['Opex_var_ACH_USD']
        opex_var_VCC_backup_USD[hour] = performance_indicators_output['Opex_var_VCC_backup_USD']
        E_used_Lake_W[hour] = performance_indicators_output['E_used_Lake_W']
        E_used_VCC_W[hour] = performance_indicators_output['E_used_VCC_W']
        E_used_VCC_backup_W[hour] = performance_indicators_output['E_used_VCC_backup_W']
        E_used_ACH_W[hour] = performance_indicators_output['E_used_ACH_W']
        co2_Lake_kgCO2[hour] = performance_indicators_output['CO2_Lake_kgCO2']
        co2_VCC_kgCO2[hour] = performance_indicators_output['CO2_VCC_kgCO2']
        co2_ACH_kgCO2[hour] = performance_indicators_output['CO2_ACH_kgCO2']
        co2_VCC_backup_kgCO2[hour] = performance_indicators_output['CO2_VCC_backup_kgCO2']
        prim_energy_Lake_MJ[hour] = performance_indicators_output['Primary_Energy_Lake_MJ']
        prim_energy_VCC_MJ[hour] = performance_indicators_output['Primary_Energy_VCC_MJ']
        prim_energy_ACH_MJ[hour] = performance_indicators_output['Primary_Energy_ACH_MJ']
        prim_energy_VCC_backup_MJ[hour] = performance_indicators_output['Primary_Energy_VCC_backup_MJ']
        calfactor_buildings[hour] = calfactor_output
        Qc_from_Lake_W[hour] = Qc_supply_to_DCN['Qc_from_Lake_W']
        Qc_from_storage_tank_W[hour] = Qc_supply_to_DCN['Qc_from_Tank_W']
        Qc_from_VCC_W[hour] = Qc_supply_to_DCN['Qc_from_VCC_W']
        Qc_from_ACH_W[hour] = Qc_supply_to_DCN['Qc_from_ACH_W']
        Qc_from_VCC_backup_W[hour] = Qc_supply_to_DCN['Qc_from_backup_VCC_W']
        Qc_req_from_CT_W[hour] = Qc_CT_W
        Qh_req_from_CCGT_W[hour] = Qh_CHP_ACH_W

    if reduced_timesteps_flag:
        reduced_costs_USD = np.sum(opex_var_Lake_USD) + np.sum(opex_var_VCC_USD) + np.sum(opex_var_ACH_USD) + np.sum(opex_var_VCC_backup_USD)
        reduced_CO2_kgCO2 = np.sum(co2_Lake_kgCO2) + np.sum(co2_Lake_kgCO2) + np.sum(co2_ACH_kgCO2) + np.sum(co2_VCC_backup_kgCO2)
        reduced_prim_MJ = np.sum(prim_energy_Lake_MJ) + np.sum(prim_energy_VCC_MJ) + np.sum(prim_energy_ACH_MJ) + np.sum(
        prim_energy_VCC_backup_MJ)

        costs_a_USD += reduced_costs_USD*(8760/(stop_t-start_t))
        CO2_kgCO2 += reduced_CO2_kgCO2*(8760/(stop_t-start_t))
        prim_MJ += reduced_prim_MJ*(8760/(stop_t-start_t))
    else:
        costs_a_USD += np.sum(opex_var_Lake_USD) + np.sum(opex_var_VCC_USD) + np.sum(opex_var_ACH_USD) + np.sum(opex_var_VCC_backup_USD)
        CO2_kgCO2 += np.sum(co2_Lake_kgCO2) + np.sum(co2_Lake_kgCO2) + np.sum(co2_ACH_kgCO2) + np.sum(co2_VCC_backup_kgCO2)
        prim_MJ += np.sum(prim_energy_Lake_MJ) + np.sum(prim_energy_VCC_MJ) + np.sum(prim_energy_ACH_MJ) + np.sum(
            prim_energy_VCC_backup_MJ)


    calfactor_total += np.sum(calfactor_buildings)
    TotalCool += np.sum(Qc_from_Lake_W) + np.sum(Qc_from_VCC_W) + np.sum(Qc_from_ACH_W) + np.sum(Qc_from_VCC_backup_W) + np.sum(Qc_from_storage_tank_W)
    Q_VCC_nom_W = limits['Qnom_VCC_W']
    Q_ACH_nom_W = limits['Qnom_ACH_W']
    Q_VCC_backup_nom_W = limits['Qnom_VCC_backup_W']
    Q_CT_nom_W = np.amax(Qc_req_from_CT_W)
    Qh_req_from_CCGT_max_W = np.amax(Qh_req_from_CCGT_W) # the required heat output from CCGT at peak
    mdot_Max_kgpers = np.amax(DCN_operation_parameters_array[:, 1])  # sizing of DCN network pumps
    Q_GT_nom_W = 0
    ########## Operation of the cooling tower

    if Q_CT_nom_W > 0:
        for hour in timesteps:
            wdot_CT = CTModel.calc_CT(Qc_req_from_CT_W[hour], Q_CT_nom_W)
            opex_var_CT_USD[hour] = (wdot_CT) * lca.ELEC_PRICE
            co2_CT_kgCO2[hour] = (wdot_CT) * lca.EL_TO_CO2 * 3600E-6
            prim_energy_CT_MJ[hour] = (wdot_CT) * lca.EL_TO_OIL_EQ * 3600E-6
            E_used_CT_W[hour] = wdot_CT

        if reduced_timesteps_flag:
            reduced_costs_USD = np.sum(opex_var_CT_USD)
            reduced_CO2_kgCO2 = np.sum(co2_CT_kgCO2)
            reduced_prim_MJ = np.sum(prim_energy_CT_MJ)

            costs_a_USD += reduced_costs_USD * (8760 / (stop_t - start_t))
            CO2_kgCO2 += reduced_CO2_kgCO2 * (8760 / (stop_t - start_t))
            prim_MJ += reduced_prim_MJ * (8760 / (stop_t - start_t))
        else:
            costs_a_USD += np.sum(opex_var_CT_USD)
            CO2_kgCO2 += np.sum(co2_CT_kgCO2)
            prim_MJ += np.sum(prim_energy_CT_MJ)

    ########## Operation of the CCGT
    if Qh_req_from_CCGT_max_W > 0:
        # Sizing of CCGT
        GT_fuel_type = 'NG'  # assumption for scenarios in SG
        Q_GT_nom_sizing_W = Qh_req_from_CCGT_max_W  # starting guess for the size of GT
        Qh_output_CCGT_max_W = 0  # the heat output of CCGT at currently installed size (Q_GT_nom_sizing_W)
        while (Qh_output_CCGT_max_W - Qh_req_from_CCGT_max_W) <= 0:
            Q_GT_nom_sizing_W += 1000  # update GT size
            # get CCGT performance limits and functions at Q_GT_nom_sizing_W
            CCGT_performances = cogeneration.calc_cop_CCGT(Q_GT_nom_sizing_W, ACH_T_IN_FROM_CHP, GT_fuel_type, prices, lca)
            Qh_output_CCGT_max_W = CCGT_performances['q_output_max_W']

        # unpack CCGT performance functions
        Q_GT_nom_W = Q_GT_nom_sizing_W * (1 + SIZING_MARGIN)  # installed CCGT capacity
        CCGT_performances = cogeneration.calc_cop_CCGT(Q_GT_nom_W, ACH_T_IN_FROM_CHP, GT_fuel_type, prices, lca)
        Q_used_prim_W_CCGT_fn = CCGT_performances['q_input_fn_q_output_W']
        cost_per_Wh_th_CCGT_fn = CCGT_performances[
            'fuel_cost_per_Wh_th_fn_q_output_W']  # gets interpolated cost function
        Qh_output_CCGT_min_W = CCGT_performances['q_output_min_W']
        Qh_output_CCGT_max_W = CCGT_performances['q_output_max_W']
        eta_elec_interpol = CCGT_performances['eta_el_fn_q_input']

        for hour in timesteps:
            if Qh_req_from_CCGT_W[hour] > Qh_output_CCGT_min_W:  # operate above minimal load
                if Qh_req_from_CCGT_W[hour] < Qh_output_CCGT_max_W:  # Normal operation Possible within partload regime
                    cost_per_Wh_th = cost_per_Wh_th_CCGT_fn(Qh_req_from_CCGT_W[hour])
                    Q_used_prim_CCGT_W = Q_used_prim_W_CCGT_fn(Qh_req_from_CCGT_W[hour])
                    Qh_from_CCGT_W[hour] = Qh_req_from_CCGT_W[hour].copy()
                    E_gen_CCGT_W[hour] = np.float(eta_elec_interpol(Q_used_prim_CCGT_W)) * Q_used_prim_CCGT_W
                else:
                    raise ValueError('Incorrect CCGT sizing!')
            else:  # operate at minimum load
                cost_per_Wh_th = cost_per_Wh_th_CCGT_fn(Qh_output_CCGT_min_W)
                Q_used_prim_CCGT_W = Q_used_prim_W_CCGT_fn(Qh_output_CCGT_min_W)
                Qh_from_CCGT_W[hour] = Qh_output_CCGT_min_W
                E_gen_CCGT_W[hour] = np.float(eta_elec_interpol(
                    Qh_output_CCGT_max_W)) * Q_used_prim_CCGT_W

            opex_var_CCGT_USD[hour] = cost_per_Wh_th * Qh_from_CCGT_W[hour] - E_gen_CCGT_W[hour] * lca.ELEC_PRICE
            co2_CCGT_kgCO2[hour] = Q_used_prim_CCGT_W * lca.NG_CC_TO_CO2_STD * WH_TO_J / 1.0E6 - E_gen_CCGT_W[hour] * lca.EL_TO_CO2 * 3600E-6
            prim_energy_CCGT_MJ[hour] = Q_used_prim_CCGT_W * lca.NG_CC_TO_OIL_STD * WH_TO_J / 1.0E6 - E_gen_CCGT_W[hour] * lca.EL_TO_OIL_EQ * 3600E-6
            NG_used_CCGT_W[hour] = Q_used_prim_CCGT_W

        if reduced_timesteps_flag:
            reduced_costs_USD = np.sum(opex_var_CCGT_USD)
            reduced_CO2_kgCO2 = np.sum(co2_CCGT_kgCO2)
            reduced_prim_MJ = np.sum(prim_energy_CCGT_MJ)

            costs_a_USD += reduced_costs_USD * (8760 / (stop_t - start_t))
            CO2_kgCO2 += reduced_CO2_kgCO2 * (8760 / (stop_t - start_t))
            prim_MJ += reduced_prim_MJ * (8760 / (stop_t - start_t))
        else:
            costs_a_USD += np.sum(opex_var_CCGT_USD)
            CO2_kgCO2 += np.sum(co2_CCGT_kgCO2)
            prim_MJ += np.sum(prim_energy_CCGT_MJ)

    ########## Add investment costs

    for i in range(limits['number_of_VCC_chillers']):
        Capex_a_VCC_USD, Opex_fixed_VCC_USD, Capex_VCC_USD = VCCModel.calc_Cinv_VCC(Q_VCC_nom_W, locator, config, 'CH3')
        costs_a_USD += Capex_a_VCC_USD + Opex_fixed_VCC_USD

    for i in range(limits['number_of_VCC_backup_chillers']):
        Capex_a_VCC_backup_USD, Opex_fixed_VCC_backup_USD, Capex_VCC_backup_USD = VCCModel.calc_Cinv_VCC(Q_VCC_backup_nom_W, locator, config, 'CH3')
        costs_a_USD += Capex_a_VCC_backup_USD + Opex_fixed_VCC_backup_USD
    master_to_slave_vars.VCC_backup_cooling_size_W = Q_VCC_backup_nom_W * limits['number_of_VCC_backup_chillers']

    for i in range(limits['number_of_ACH_chillers']):
        Capex_a_ACH_USD, Opex_fixed_ACH_USD, Capex_ACH_USD = chiller_absorption.calc_Cinv_ACH(Q_ACH_nom_W, locator, ACH_TYPE_DOUBLE, config)
        costs_a_USD += Capex_a_ACH_USD + Opex_fixed_ACH_USD

    Capex_a_CCGT_USD, Opex_fixed_CCGT_USD, Capex_CCGT_USD = cogeneration.calc_Cinv_CCGT(Q_GT_nom_W, locator, config)
    costs_a_USD += Capex_a_CCGT_USD + Opex_fixed_CCGT_USD

    Capex_a_Tank_USD, Opex_fixed_Tank_USD, Capex_Tank_USD = thermal_storage.calc_Cinv_storage(V_tank_m3, locator, config, 'TES2')
    costs_a_USD += Capex_a_Tank_USD + Opex_fixed_Tank_USD

    Capex_a_CT_USD, Opex_fixed_CT_USD, Capex_CT_USD = CTModel.calc_Cinv_CT(Q_CT_nom_W, locator, config, 'CT1')

    costs_a_USD += Capex_a_CT_USD + Opex_fixed_CT_USD

    Capex_a_pump_USD, Opex_fixed_pump_USD, Opex_var_pump_USD, Capex_pump_USD = PumpModel.calc_Ctot_pump(master_to_slave_vars, ntwFeat, locator, lca, config)
    costs_a_USD += Capex_a_pump_USD + Opex_fixed_pump_USD + Opex_var_pump_USD

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

    date = network_data.DATE.values
    results = pd.DataFrame({"DATE": date,
                            "Q_total_cooling_W": Q_cooling_req_W,
                            "Opex_var_Lake_USD": opex_var_Lake_USD,
                            "Opex_var_VCC_USD": opex_var_VCC_USD,
                            "Opex_var_ACH_USD": opex_var_ACH_USD,
                            "Opex_var_VCC_backup_USD": opex_var_VCC_backup_USD,
                            "Opex_var_CT_USD": opex_var_CT_USD,
                            "Opex_var_CCGT_USD": opex_var_CCGT_USD,
                            "E_used_Lake_W": E_used_Lake_W,
                            "E_used_VCC_W": E_used_VCC_W,
                            "E_used_VCC_backup_W": E_used_VCC_backup_W,
                            "E_used_ACH_W": E_used_ACH_W,
                            "E_used_CT_W": E_used_CT_W,
                            "NG_used_CCGT_W": NG_used_CCGT_W,
                            "CO2_from_using_Lake": co2_Lake_kgCO2,
                            "CO2_from_using_VCC": co2_VCC_kgCO2,
                            "CO2_from_using_ACH": co2_ACH_kgCO2,
                            "CO2_from_using_VCC_backup": co2_VCC_backup_kgCO2,
                            "CO2_from_using_CT": co2_CT_kgCO2,
                            "CO2_from_using_CCGT": co2_CCGT_kgCO2,
                            "Primary_Energy_from_Lake": prim_energy_Lake_MJ,
                            "Primary_Energy_from_VCC": prim_energy_VCC_MJ,
                            "Primary_Energy_from_ACH": prim_energy_ACH_MJ,
                            "Primary_Energy_from_VCC_backup": prim_energy_VCC_backup_MJ,
                            "Primary_Energy_from_CT": prim_energy_CT_MJ,
                            "Primary_Energy_from_CCGT": prim_energy_CCGT_MJ,
                            "Q_from_Lake_W": Qc_from_Lake_W,
                            "Q_from_VCC_W": Qc_from_VCC_W,
                            "Q_from_ACH_W": Qc_from_ACH_W,
                            "Q_from_VCC_backup_W": Qc_from_VCC_backup_W,
                            "Q_from_storage_tank_W": Qc_from_storage_tank_W,
                            "Qc_CT_associated_with_all_chillers_W": Qc_req_from_CT_W,
                            "Qh_CCGT_associated_with_absorption_chillers_W": Qh_from_CCGT_W,
                            "E_gen_CCGT_associated_with_absorption_chillers_W": E_gen_CCGT_W
                            })

    results.to_csv(locator.get_optimization_slave_cooling_activation_pattern(master_to_slave_vars.individual_number,
                                                                             master_to_slave_vars.generation_number),
                   index=False)
    ########### Adjust and add the pumps for filtering and pre-treatment of the water
    calibration = calfactor_total / 50976000

    extraElec = (127865400 + 85243600) * calibration
    costs_a_USD += extraElec * lca.ELEC_PRICE
    CO2_kgCO2 += extraElec * lca.EL_TO_CO2 * 3600E-6
    prim_MJ += extraElec * lca.EL_TO_OIL_EQ * 3600E-6
    # Converting costs into float64 to avoid longer values
    costs_a_USD = np.float64(costs_a_USD)
    CO2_kgCO2 = np.float64(CO2_kgCO2)
    prim_MJ = np.float64(prim_MJ)

    # Capex_a and Opex_fixed
    results = pd.DataFrame({"Capex_a_VCC_USD": [Capex_a_VCC_USD],
                            "Opex_fixed_VCC_USD": [Opex_fixed_VCC_USD],
                            "Capex_a_VCC_backup_USD": [Capex_a_VCC_backup_USD],
                            "Opex_fixed_VCC_backup_USD": [Opex_fixed_VCC_backup_USD],
                            "Capex_a_ACH_USD": [Capex_a_ACH_USD],
                            "Opex_fixed_ACH_USD": [Opex_fixed_ACH_USD],
                            "Capex_a_CCGT_USD": [Capex_a_CCGT_USD],
                            "Opex_fixed_CCGT_USD": [Opex_fixed_CCGT_USD],
                            "Capex_a_Tank_USD": [Capex_a_Tank_USD],
                            "Opex_fixed_Tank_USD": [Opex_fixed_Tank_USD],
                            "Capex_a_CT_USD": [Capex_a_CT_USD],
                            "Opex_fixed_CT_USD": [Opex_fixed_CT_USD],
                            "Capex_a_pump_USD": [Capex_a_pump_USD],
                            "Opex_fixed_pump_USD": [Opex_fixed_pump_USD],
                            "Opex_var_pump_USD": [Opex_var_pump_USD],
                            "Capex_VCC_USD": [Capex_VCC_USD],
                            "Capex_VCC_backup_USD": [Capex_VCC_backup_USD],
                            "Capex_ACH_USD": [Capex_ACH_USD],
                            "Capex_CCGT_USD": [Capex_CCGT_USD],
                            "Capex_Tank_USD": [Capex_Tank_USD],
                            "Capex_CT_USD": [Capex_CT_USD],
                            "Capex_pump_USD": [Capex_pump_USD]
                            })

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

    # print " Cooling main done (", round(time.time()-t0, 1), " seconds used for this task)"

    # print ('Cooling costs = ' + str(costs))
    # print ('Cooling CO2 = ' + str(CO2))
    # print ('Cooling Eprim = ' + str(prim))

    return (costs_a_USD, CO2_kgCO2, prim_MJ)
Exemple #7
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 coolingMain(locator, configKey, ntwFeat, HRdata, gv):
    """
    Computes the parameters for the cooling of the complete DCN
    
    Parameters
    ----------
    locator : string
        path to res folder
    configKey : string
        configuration key for the DHN
    ntwFeat : class ntwFeatures
    HRdata : inf
        0 if no data heat recovery, 1 if so
    
    Returns
    -------
    (costs, co2, prim) : tuple
    
    """
    
    ############# Recover the cooling needs
    
    # Space cooling previously aggregated in the substation routine
    df = pd.read_csv(locator.pathNtwRes + "/Network_summary_result_all.csv", usecols=["T_sst_cool_return_netw_total", "mdot_cool_netw_total"])
    coolArray = np.nan_to_num( np.array(df) )
    TsupCool = gv.TsupCool
    
    # Data center cooling, (treated separately for each building)
    df = pd.read_csv(locator.get_total_demand(), usecols=["Name", "Qcdataf_MWhyr"])
    arrayData = np.array(df)
    
    # Ice hockey rings, (treated separately for each building)
    df = pd.read_csv(locator.get_total_demand(), usecols=["Name", "Qcref_MWhyr"])
    arrayQice = np.array(df)
    
    
    ############# Recover the heat already taken from the lake by the heat pumps
    try:
        os.chdir(locator.pathSlaveRes)
        fNameSlaveRes = configKey + "PPActivationPattern.csv"
        
        dfSlave = pd.read_csv(fNameSlaveRes, usecols=["Qcold_HPLake"])
        
        QlakeArray = np.array(dfSlave)
        Qlake = np.sum(QlakeArray)
        
    except:
        Qlake = 0
    
    Qavail = gv.DeltaU + Qlake
    print Qavail, "Qavail"
    
    
    ############# Output results
    costs = ntwFeat.pipesCosts_DCN
    CO2 = 0
    prim = 0
    
    nBuild = int( np.shape(arrayData)[0] )
    nHour = int( np.shape(coolArray)[0] )
    CTLoad = np.zeros(nHour)
    VCCnom = 0
    
    calFactor = 0
    TotalCool = 0
    
    
    ############ Function for cooling operation
    def coolOperation(dataArray, el, QavailIni, TempSup = 0):
        toTotalCool = 0
        toCalfactor = 0
        toCosts = 0
        toCO2 = 0
        toPrim = 0
        
        QavailCopy = QavailIni
        VCCnomIni = 0
        
        for i in range(el):
            
            if TempSup > 0:
                Tsup = TempSup
                Tret = dataArray[i][-2]
                mdot = abs ( dataArray[i][-1] )
            else:
                Tsup = dataArray[i][-3] + 273
                Tret = dataArray[i][-2] + 273
                mdot = abs ( dataArray[i][-1] * 1E3 / gv.cp )
            
            Qneed = abs( mdot * gv.cp * (Tret - Tsup) )
            toTotalCool += Qneed
            
            if QavailCopy - Qneed >= 0: # Free cooling possible from the lake
                QavailCopy -= Qneed
                
                # Delta P from linearization after network optimization
                deltaP = 2* (gv.DeltaP_Coeff * mdot + gv.DeltaP_Origin)
                
                toCalfactor += deltaP * mdot / 1000 / gv.etaPump
                toCosts += deltaP * mdot / 1000 * gv.ELEC_PRICE / gv.etaPump
                toCO2 += deltaP * mdot / 1000 * gv.EL_TO_CO2 / gv.etaPump * 0.0036
                toPrim += deltaP * mdot / 1000 * gv.EL_TO_OIL_EQ / gv.etaPump * 0.0036
                
            else:
                print "Lake exhausted !"
                wdot, qhotdot = VCCModel.calc_VCC(mdot, Tsup, Tret, gv)
                if Qneed > VCCnomIni:
                    VCCnomIni = Qneed * (1+gv.Qmargin_Disc)
                
                toCosts += wdot * gv.ELEC_PRICE
                toCO2 += wdot * gv.EL_TO_CO2 * 3600E-6
                toPrim += wdot * gv.EL_TO_OIL_EQ * 3600E-6
                
                CTLoad[i] += qhotdot
    
        return toCosts, toCO2, toPrim, toCalfactor, toTotalCool, QavailCopy, VCCnomIni
    
    
    ########## Cooling operation with Circulating pump and VCC
    
    print "Space cooling operation"
    toCosts, toCO2, toPrim, toCalfactor, toTotalCool, QavailCopy, VCCnomIni = coolOperation(coolArray, nHour, Qavail, TempSup = TsupCool)
    costs += toCosts
    CO2 += toCO2
    prim += toPrim
    calFactor += toCalfactor
    TotalCool += toTotalCool
    VCCnom = max(VCCnom, VCCnomIni)
    Qavail = QavailCopy
    print Qavail, "Qavail after space cooling"

    mdotMax = np.amax(coolArray[:,1])
    costs += PumpModel.Pump_Cost(2*ntwFeat.DeltaP_DCN, mdotMax, gv.etaPump, gv)
    
    if HRdata == 0:
        print "Data centers cooling operation"
        for i in range(nBuild):
            if arrayData[i][1] > 0:
                buildName = arrayData[i][0]
                print buildName
                df = pd.read_csv(locator.get_demand_results_file(buildName), usecols=["Tsdata_C", "Trdata_C", "mcpdata_kWC"])
                arrayBuild = np.array(df)
                
                mdotMaxData = abs( np.amax(arrayBuild[:,-1]) / gv.cp * 1E3)
                costs += PumpModel.Pump_Cost(2*ntwFeat.DeltaP_DCN, mdotMaxData, gv.etaPump, gv)
            
                toCosts, toCO2, toPrim, toCalfactor, toTotalCool, QavailCopy, VCCnomIni = coolOperation(arrayBuild, nHour, Qavail)
                costs += toCosts
                CO2 += toCO2
                prim += toPrim
                calFactor += toCalfactor
                TotalCool += toTotalCool
                VCCnom = max(VCCnom, VCCnomIni)
                Qavail = QavailCopy
                print Qavail, "Qavail after data center"

    print "refrigeration cooling operation"
    for i in range(nBuild):
        if arrayQice[i][1] > 0:
            buildName = arrayQice[i][0]
            print buildName
            df = pd.read_csv(locator.pathRaw + "/" + buildName + ".csv", usecols=["Tsref_C", "Trref_C", "mcpref_kWC"])
            arrayBuild = np.array(df)

            mdotMaxice = abs( np.amax(arrayBuild[:,-1]) / gv.cp * 1E3)
            costs += PumpModel.Pump_Cost(2*ntwFeat.DeltaP_DCN, mdotMaxice, gv.etaPump, gv)
        
            toCosts, toCO2, toPrim, toCalfactor, toTotalCool, QavailCopy, VCCnomIni = coolOperation(arrayBuild, nHour, Qavail)
            costs += toCosts
            CO2 += toCO2
            prim += toPrim
            calFactor += toCalfactor
            TotalCool += toTotalCool
            VCCnom = max(VCCnom, VCCnomIni)
            Qavail = QavailCopy
            print Qavail, "Qavail after ice"
    
    
    print costs, CO2, prim, "operation for cooling"
    print TotalCool, "TotalCool"
    
    
    ########## Operation of the cooling tower
    CTnom = np.amax(CTLoad)
    costCopy = costs
    if CTnom > 0 :
        for i in range(nHour):
            wdot = CTModel.calc_CT(CTLoad[i], CTnom, gv)
            
            costs += wdot * gv.ELEC_PRICE
            CO2 += wdot * gv.EL_TO_CO2 * 3600E-6
            prim += wdot * gv.EL_TO_OIL_EQ * 3600E-6
            
        print costs - costCopy, "costs after operation of CT"
    
    
    ########## Add investment costs  
    
    costs += VCCModel.calc_Cinv_VCC(VCCnom, gv)
    print VCCModel.calc_Cinv_VCC(VCCnom, gv), "InvC VCC"
    costs += CTModel.calc_Cinv_CT(CTnom, gv)
    print CTModel.calc_Cinv_CT(CTnom, gv), "InvC CT"
    

    ########### Adjust and add the pumps for filtering and pre-treatment of the water
    calibration = calFactor / 50976000
    print calibration, "adjusting factor"
    
    extraElec = (127865400 + 85243600) * calibration
    costs += extraElec * gv.ELEC_PRICE
    CO2 += extraElec * gv.EL_TO_CO2 * 3600E-6
    prim += extraElec * gv.EL_TO_OIL_EQ * 3600E-6
    
    
    return (costs, CO2, prim)
    
    
Exemple #9
0
def coolingMain(locator, configKey, ntwFeat, HRdata, gv):
    """
    Computes the parameters for the cooling of the complete DCN

    :param locator: path to res folder
    :param configKey: configuration key for the District Heating Network (DHN)
    :param ntwFeat: network features
    :param HRdata: Heat recovery data, 0 if no heat recovery data, 1 if so
    :param gv: global variables
    :type locator: string
    :type configKey: string
    :type ntwFeat: class
    :type HRdata: int
    :type gv: class
    :return: costs, co2, prim
    :rtype: tuple
    """

    ############# Recover the cooling needs

    # Space cooling previously aggregated in the substation routine
    df = pd.read_csv(os.path.join(
        locator.get_optimization_network_results_folder(),
        "Network_summary_result_all.csv"),
                     usecols=["T_DCNf_re_K", "mdot_cool_netw_total_kgpers"])
    coolArray = np.nan_to_num(np.array(df))
    T_sup_Cool_K = gv.TsupCool

    # Data center cooling, (treated separately for each building)
    df = pd.read_csv(locator.get_total_demand(),
                     usecols=["Name", "Qcdataf_MWhyr"])
    arrayData = np.array(df)

    # Ice hockey rings, (treated separately for each building)
    df = pd.read_csv(locator.get_total_demand(),
                     usecols=["Name", "Qcref_MWhyr"])
    arrayQice = np.array(df)

    ############# Recover the heat already taken from the lake by the heat pumps
    try:
        os.chdir(locator.get_optimization_slave_results_folder())
        fNameSlaveRes = configKey + "PPActivationPattern.csv"

        dfSlave = pd.read_csv(fNameSlaveRes, usecols=["Qcold_HPLake_W"])

        Q_lake_Array_W = np.array(dfSlave)
        Q_lake_W = np.sum(Q_lake_Array_W)

    except:
        Q_lake_W = 0

    Q_avail_W = gv.DeltaU + Q_lake_W
    print Q_avail_W, "Qavail"

    ############# Output results
    costs = ntwFeat.pipesCosts_DCN
    CO2 = 0
    prim = 0

    nBuild = int(np.shape(arrayData)[0])
    nHour = int(np.shape(coolArray)[0])
    CT_Load_W = np.zeros(nHour)
    VCC_nom_W = 0

    calFactor = 0
    TotalCool = 0

    ############ Function for cooling operation
    def coolOperation(dataArray, el, Q_availIni_W, TempSup=0):
        """
        :param dataArray:
        :param el:
        :param Q_availIni_W:
        :param TempSup:
        :type dataArray: list
        :type el:
        :type Q_availIni_W: float?
        :type TempSup:
        :return: toCosts, toCO2, toPrim, toCalfactor, toTotalCool, QavailCopy, VCCnomIni
        :rtype: float, float, float, float, float, float, float
        """
        toTotalCool = 0
        toCalfactor = 0
        toCosts = 0
        toCO2 = 0
        toPrim = 0

        Q_availCopy_W = Q_availIni_W
        VCC_nom_Ini_W = 0

        for i in range(el):

            if TempSup > 0:
                T_sup_K = TempSup
                T_re_K = dataArray[i][-2]
                mdot_kgpers = abs(dataArray[i][-1])
            else:
                T_sup_K = dataArray[i][-3] + 273
                T_re_K = dataArray[i][-2] + 273
                mdot_kgpers = abs(dataArray[i][-1] * 1E3 / gv.cp)

            Q_need_W = abs(mdot_kgpers * gv.cp * (T_re_K - T_sup_K))
            toTotalCool += Q_need_W

            if Q_availCopy_W - Q_need_W >= 0:  # Free cooling possible from the lake
                Q_availCopy_W -= Q_need_W

                # Delta P from linearization after distribution optimization
                deltaP = 2 * (gv.DeltaP_Coeff * mdot_kgpers + gv.DeltaP_Origin)

                toCalfactor += deltaP * mdot_kgpers / 1000 / gv.etaPump
                toCosts += deltaP * mdot_kgpers / 1000 * gv.ELEC_PRICE / gv.etaPump
                toCO2 += deltaP * mdot_kgpers / 1000 * gv.EL_TO_CO2 / gv.etaPump * 0.0036
                toPrim += deltaP * mdot_kgpers / 1000 * gv.EL_TO_OIL_EQ / gv.etaPump * 0.0036

            else:
                print "Lake exhausted !"
                wdot_W, qhotdot_W = VCCModel.calc_VCC(mdot_kgpers, T_sup_K,
                                                      T_re_K, gv)
                if Q_need_W > VCC_nom_Ini_W:
                    VCC_nom_Ini_W = Q_need_W * (1 + gv.Qmargin_Disc)

                toCosts += wdot_W * gv.ELEC_PRICE
                toCO2 += wdot_W * gv.EL_TO_CO2 * 3600E-6
                toPrim += wdot_W * gv.EL_TO_OIL_EQ * 3600E-6

                CT_Load_W[i] += qhotdot_W

        return toCosts, toCO2, toPrim, toCalfactor, toTotalCool, Q_availCopy_W, VCC_nom_Ini_W

    ########## Cooling operation with Circulating pump and VCC

    print "Space cooling operation"
    toCosts, toCO2, toPrim, toCalfactor, toTotalCool, Q_availCopy_W, VCC_nom_Ini_W = coolOperation(
        coolArray, nHour, Q_avail_W, TempSup=T_sup_Cool_K)
    costs += toCosts
    CO2 += toCO2
    prim += toPrim
    calFactor += toCalfactor
    TotalCool += toTotalCool
    VCC_nom_W = max(VCC_nom_W, VCC_nom_Ini_W)
    Q_avail_W = Q_availCopy_W
    print Q_avail_W, "Qavail after space cooling"

    mdot_Max_kgpers = np.amax(coolArray[:, 1])
    costs += PumpModel.Pump_Cost(2 * ntwFeat.DeltaP_DCN, mdot_Max_kgpers,
                                 gv.etaPump, gv)

    if HRdata == 0:
        print "Data centers cooling operation"
        for i in range(nBuild):
            if arrayData[i][1] > 0:
                buildName = arrayData[i][0]
                print buildName
                df = pd.read_csv(locator.get_demand_results_file(buildName),
                                 usecols=[
                                     "Tcdataf_sup_C", "Tcdataf_re_C",
                                     "mcpdataf_kWperC"
                                 ])
                arrayBuild = np.array(df)

                mdot_max_Data_kWperC = abs(
                    np.amax(arrayBuild[:, -1]) / gv.cp * 1E3)
                costs += PumpModel.Pump_Cost(2 * ntwFeat.DeltaP_DCN,
                                             mdot_max_Data_kWperC, gv.etaPump,
                                             gv)

                toCosts, toCO2, toPrim, toCalfactor, toTotalCool, Q_availCopy_W, VCC_nom_Ini_W = coolOperation(
                    arrayBuild, nHour, Q_avail_W)
                costs += toCosts
                CO2 += toCO2
                prim += toPrim
                calFactor += toCalfactor
                TotalCool += toTotalCool
                VCC_nom_W = max(VCC_nom_W, VCC_nom_Ini_W)
                Q_avail_W = Q_availCopy_W
                print Q_avail_W, "Qavail after data center"

    print "refrigeration cooling operation"
    for i in range(nBuild):
        if arrayQice[i][1] > 0:
            buildName = arrayQice[i][0]
            print buildName
            df = pd.read_csv(locator.pathRaw + "/" + buildName + ".csv",
                             usecols=["Tsref_C", "Trref_C", "mcpref_kWperC"])
            arrayBuild = np.array(df)

            mdot_max_ice_kgpers = abs(np.amax(arrayBuild[:, -1]) / gv.cp * 1E3)
            costs += PumpModel.Pump_Cost(2 * ntwFeat.DeltaP_DCN,
                                         mdot_max_ice_kgpers, gv.etaPump, gv)

            toCosts, toCO2, toPrim, toCalfactor, toTotalCool, Q_availCopy_W, VCC_nom_Ini_W = coolOperation(
                arrayBuild, nHour, Q_avail_W)
            costs += toCosts
            CO2 += toCO2
            prim += toPrim
            calFactor += toCalfactor
            TotalCool += toTotalCool
            VCC_nom_W = max(VCC_nom_W, VCC_nom_Ini_W)
            Q_avail_W = Q_availCopy_W
            print Q_avail_W, "Qavail after ice"

    print costs, CO2, prim, "operation for cooling"
    print TotalCool, "TotalCool"

    ########## Operation of the cooling tower
    CT_nom_W = np.amax(CT_Load_W)
    costCopy = costs
    if CT_nom_W > 0:
        for i in range(nHour):
            wdot_W = CTModel.calc_CT(CT_Load_W[i], CT_nom_W, gv)

            costs += wdot_W * gv.ELEC_PRICE
            CO2 += wdot_W * gv.EL_TO_CO2 * 3600E-6
            prim += wdot_W * gv.EL_TO_OIL_EQ * 3600E-6

        print costs - costCopy, "costs after operation of CT"

    ########## Add investment costs

    costs += VCCModel.calc_Cinv_VCC(VCC_nom_W, gv)
    print VCCModel.calc_Cinv_VCC(VCC_nom_W, gv), "InvC VCC"
    costs += CTModel.calc_Cinv_CT(CT_nom_W, gv)
    print CTModel.calc_Cinv_CT(CT_nom_W, gv), "InvC CT"

    ########### Adjust and add the pumps for filtering and pre-treatment of the water
    calibration = calFactor / 50976000
    print calibration, "adjusting factor"

    extraElec = (127865400 + 85243600) * calibration
    costs += extraElec * gv.ELEC_PRICE
    CO2 += extraElec * gv.EL_TO_CO2 * 3600E-6
    prim += extraElec * gv.EL_TO_OIL_EQ * 3600E-6

    save_file = 1
    if save_file == 1:
        results = pd.DataFrame({
            "costs": [costs],
            "CO2": [CO2],
            "prim": [prim]
        })

        results.to_csv(
            locator.get_optimization_slave_pp_activation_cooling_pattern(
                configKey),
            sep=',')

        print "Cooling Results saved in : ", locator.get_optimization_slave_results_folder(
        )
        print " as : ", configKey + "_coolingresults.csv"

    return (costs, CO2, prim)
Exemple #10
0
def calc_generation_costs_cooling(
    locator,
    master_to_slave_variables,
    config,
):
    # TRIGENERATION
    if master_to_slave_variables.NG_Trigen_on == 1:
        Qc_ACH_nom_W = master_to_slave_variables.NG_Trigen_ACH_size_W
        Q_GT_nom_W = master_to_slave_variables.NG_Trigen_CCGT_size_W

        # ACH
        Capex_a_ACH_USD, Opex_fixed_ACH_USD, Capex_ACH_USD = chiller_absorption.calc_Cinv_ACH(
            Qc_ACH_nom_W, locator, ACH_TYPE_DOUBLE)
        # CCGT
        Capex_a_CCGT_USD, Opex_fixed_CCGT_USD, Capex_CCGT_USD = cogeneration.calc_Cinv_CCGT(
            Q_GT_nom_W, locator, config)

        Capex_a_Trigen_NG_USD = Capex_a_ACH_USD + Capex_a_CCGT_USD
        Opex_fixed_Trigen_NG_USD = Opex_fixed_ACH_USD + Opex_fixed_CCGT_USD
        Capex_Trigen_NG_USD = Capex_ACH_USD + Capex_CCGT_USD
    else:
        Capex_a_Trigen_NG_USD = 0.0
        Opex_fixed_Trigen_NG_USD = 0.0
        Capex_Trigen_NG_USD = 0.0

    # WATER-SOURCE VAPOR COMPRESION CHILLER BASE
    if master_to_slave_variables.WS_BaseVCC_on == 1:
        Qc_VCC_nom_W = master_to_slave_variables.WS_BaseVCC_size_W
        # VCC
        Capex_a_BaseVCC_WS_USD, Opex_fixed_BaseVCC_WS_USD, Capex_BaseVCC_WS_USD = VCCModel.calc_Cinv_VCC(
            Qc_VCC_nom_W, locator, config, 'CH3')
    else:
        Capex_a_BaseVCC_WS_USD = 0.0
        Opex_fixed_BaseVCC_WS_USD = 0.0
        Capex_BaseVCC_WS_USD = 0.0

    # WATER-SOURCE VAPOR COMPRESION CHILLER PEAK
    if master_to_slave_variables.WS_PeakVCC_on == 1:
        Qc_VCC_nom_W = master_to_slave_variables.WS_PeakVCC_size_W
        # VCC
        Capex_a_PeakVCC_WS_USD, Opex_fixed_PeakVCC_WS_USD, Capex_PeakVCC_WS_USD = VCCModel.calc_Cinv_VCC(
            Qc_VCC_nom_W, locator, config, 'CH3')
    else:
        Capex_a_PeakVCC_WS_USD = 0.0
        Opex_fixed_PeakVCC_WS_USD = 0.0
        Capex_PeakVCC_WS_USD = 0.0

    # AIR-SOURCE VAPOR COMPRESION CHILLER BASE
    if master_to_slave_variables.AS_BaseVCC_on == 1:
        Qc_VCC_nom_W = master_to_slave_variables.AS_BaseVCC_size_W
        # VCC
        Capex_a_VCC_USD, Opex_fixed_VCC_USD, Capex_VCC_USD = VCCModel.calc_Cinv_VCC(
            Qc_VCC_nom_W, locator, config, 'CH3')

        # COOLING TOWER
        Capex_a_CT_USD, Opex_fixed_CT_USD, Capex_CT_USD = CTModel.calc_Cinv_CT(
            Qc_VCC_nom_W, locator, 'CT1')

        Capex_a_BaseVCC_AS_USD = Capex_a_VCC_USD + Capex_a_CT_USD
        Opex_fixed_BaseVCC_AS_USD = Opex_fixed_VCC_USD + Opex_fixed_CT_USD
        Capex_BaseVCC_AS_USD = Capex_VCC_USD + Capex_CT_USD

    else:
        Capex_a_BaseVCC_AS_USD = 0.0
        Opex_fixed_BaseVCC_AS_USD = 0.0
        Capex_BaseVCC_AS_USD = 0.0

    # AIR-SOURCE VAPOR COMPRESION CHILLER PEAK
    if master_to_slave_variables.AS_PeakVCC_on == 1:
        Qc_VCC_nom_W = master_to_slave_variables.AS_PeakVCC_size_W
        # VCC
        Capex_a_VCC_USD, Opex_fixed_VCC_USD, Capex_VCC_USD = VCCModel.calc_Cinv_VCC(
            Qc_VCC_nom_W, locator, config, 'CH3')

        # COOLING TOWER
        Capex_a_CT_USD, Opex_fixed_CT_USD, Capex_CT_USD = CTModel.calc_Cinv_CT(
            Qc_VCC_nom_W, locator, 'CT1')

        Capex_a_PeakVCC_AS_USD = Capex_a_VCC_USD + Capex_a_CT_USD
        Opex_fixed_PeakVCC_AS_USD = Opex_fixed_VCC_USD + Opex_fixed_CT_USD
        Capex_PeakVCC_AS_USD = Capex_VCC_USD + Capex_CT_USD

    else:
        Capex_a_PeakVCC_AS_USD = 0.0
        Opex_fixed_PeakVCC_AS_USD = 0.0
        Capex_PeakVCC_AS_USD = 0.0

    # AIR-SOURCE VCC BACK-UP
    if master_to_slave_variables.AS_BackupVCC_on == 1:
        Qc_VCC_nom_W = master_to_slave_variables.AS_BackupVCC_size_W
        # VCC
        Capex_a_VCC_USD, Opex_fixed_VCC_USD, Capex_VCC_USD = VCCModel.calc_Cinv_VCC(
            Qc_VCC_nom_W, locator, config, 'CH3')

        # COOLING TOWER
        Capex_a_CT_USD, Opex_fixed_CT_USD, Capex_CT_USD = CTModel.calc_Cinv_CT(
            Qc_VCC_nom_W, locator, 'CT1')

        Capex_a_BackupVCC_AS_USD = Capex_a_VCC_USD + Capex_a_CT_USD
        Opex_fixed_BackupVCC_AS_USD = Opex_fixed_VCC_USD + Opex_fixed_CT_USD
        Capex_BackupVCC_AS_USD = Capex_VCC_USD + Capex_CT_USD

    else:
        Capex_a_BackupVCC_AS_USD = 0.0
        Opex_fixed_BackupVCC_AS_USD = 0.0
        Capex_BackupVCC_AS_USD = 0.0

    # PLOT RESULTS
    performance = {
        # annualized capex
        "Capex_a_Trigen_NG_connected_USD": Capex_a_Trigen_NG_USD,
        "Capex_a_BaseVCC_WS_connected_USD": Capex_a_BaseVCC_WS_USD,
        "Capex_a_PeakVCC_WS_connected_USD": Capex_a_PeakVCC_WS_USD,
        "Capex_a_BaseVCC_AS_connected_USD": Capex_a_BaseVCC_AS_USD,
        "Capex_a_PeakVCC_AS_connected_USD": Capex_a_PeakVCC_AS_USD,
        "Capex_a_BackupVCC_AS_connected_USD": Capex_a_BackupVCC_AS_USD,

        # total capex
        "Capex_total_Trigen_NG_connected_USD": Capex_Trigen_NG_USD,
        "Capex_total_BaseVCC_WS_connected_USD": Capex_BaseVCC_WS_USD,
        "Capex_total_PeakVCC_WS_connected_USD": Capex_PeakVCC_WS_USD,
        "Capex_total_BaseVCC_AS_connected_USD": Capex_BaseVCC_AS_USD,
        "Capex_total_PeakVCC_AS_connected_USD": Capex_PeakVCC_AS_USD,
        "Capex_total_BackupVCC_AS_connected_USD": Capex_BackupVCC_AS_USD,

        # opex fixed
        "Opex_fixed_Trigen_NG_connected_USD": Opex_fixed_Trigen_NG_USD,
        "Opex_fixed_BaseVCC_WS_connected_USD": Opex_fixed_BaseVCC_WS_USD,
        "Opex_fixed_PeakVCC_WS_connected_USD": Opex_fixed_PeakVCC_WS_USD,
        "Opex_fixed_BaseVCC_AS_connected_USD": Opex_fixed_BaseVCC_AS_USD,
        "Opex_fixed_PeakVCC_AS_connected_USD": Opex_fixed_PeakVCC_AS_USD,
        "Opex_fixed_BackupVCC_AS_connected_USD": Opex_fixed_BackupVCC_AS_USD,
    }

    return performance
Exemple #11
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"