Beispiel #1
0
def heating_source_activator(Q_therm_req_W, hour, master_to_slave_vars, mdot_DH_req_kgpers, tdhsup_K, tdhret_req_K, TretsewArray_K,
                             gv, prices, lca, T_ground):
    """
    :param Q_therm_req_W:
    :param hour:
    :param context:
    :type Q_therm_req_W: float
    :type hour: int
    :type context: list
    :return: cost_data_centralPlant_op, source_info, Q_source_data, E_coldsource_data, E_PP_el_data, E_gas_data, E_wood_data, Q_excess
    :rtype:
    """

    current_source = ACT_FIRST  # Start with first source, no cost yet
    Q_therm_req_W_copy = Q_therm_req_W
    # Initializing resulting values (necessairy as not all of them are over-written):
    Q_uncovered_W = 0
    cost_HPSew_USD, cost_HPLake_USD, cost_GHP_USD, cost_CHP_USD, cost_Furnace_USD, cost_BaseBoiler_USD, cost_PeakBoiler_USD = 0, 0, 0, 0, 0, 0, 0

    # initialize all sources to be off = 0 (turn to "on" with setting to 1)
    source_HP_Sewage = 0
    source_HP_Lake = 0
    source_GHP = 0
    source_CHP = 0
    source_Furnace = 0
    source_BaseBoiler = 0
    source_PeakBoiler = 0
    Q_excess_W = 0
    Q_HPSew_gen_W, Q_HPLake_gen_W, Q_GHP_gen_W, Q_CHP_gen_W, Q_Furnace_gen_W, Q_BaseBoiler_gen_W, Q_PeakBoiler_gen_W = 0, 0, 0, 0, 0, 0, 0
    E_HPSew_req_W, E_HPLake_req_W, E_GHP_req_W, E_CHP_gen_W, E_Furnace_gen_W, E_BaseBoiler_req_W, E_PeakBoiler_req_W = 0, 0, 0, 0, 0, 0, 0
    Gas_used_HPSew_W, Gas_used_HPLake_W, Gas_used_GHP_W, Gas_used_CHP_W, Gas_used_Furnace_W, Gas_used_BaseBoiler_W, Gas_used_PeakBoiler_W = 0, 0, 0, 0, 0, 0, 0
    Wood_used_HPSew_W, Wood_used_HPLake_W, Wood_used_GHP_W, Wood_used_CHP_W, Wood_used_Furnace_W, Wood_used_BaseBoiler_W, Wood_used_PeakBoiler_W = 0, 0, 0, 0, 0, 0, 0
    Q_coldsource_HPSew_W, Q_coldsource_HPLake_W, Q_coldsource_GHP_W, Q_coldsource_CHP_W, \
    Q_coldsource_Furnace_W, Q_coldsource_BaseBoiler_W, Q_coldsource_PeakBoiler_W = 0, 0, 0, 0, 0, 0, 0

    while Q_therm_req_W > 1E-1:  # cover demand as long as the supply is lower than demand!
        if current_source == 'HP':  # use heat pumps available!

            if (master_to_slave_vars.HP_Sew_on) == 1 and Q_therm_req_W > 0 and HP_SEW_ALLOWED == 1:  # activate if its available

                source_HP_Sewage = 0
                cost_HPSew_USD = 0.0
                Q_HPSew_gen_W = 0.0
                E_HPSew_req_W = 0.0
                Q_coldsource_HPSew_W = 0.0

                if Q_therm_req_W > master_to_slave_vars.HPSew_maxSize_W:
                    Q_therm_Sew_W = master_to_slave_vars.HPSew_maxSize_W
                    mdot_DH_to_Sew_kgpers = mdot_DH_req_kgpers * Q_therm_Sew_W / Q_therm_req_W.copy()  # scale down the mass flow if the thermal demand is lowered

                else:
                    Q_therm_Sew_W = float(Q_therm_req_W.copy())
                    mdot_DH_to_Sew_kgpers = float(mdot_DH_req_kgpers.copy())

                C_HPSew_el_pure, C_HPSew_per_kWh_th_pure, Q_HPSew_cold_primary_W, Q_HPSew_therm_W, E_HPSew_req_W = HPSew_op_cost(mdot_DH_to_Sew_kgpers, tdhsup_K, tdhret_req_K, TretsewArray_K,
                                                  lca, Q_therm_Sew_W)
                Q_therm_req_W -= Q_HPSew_therm_W

                # Storing data for further processing
                if Q_HPSew_therm_W > 0:
                    source_HP_Sewage = 1
                cost_HPSew_USD = float(C_HPSew_el_pure)
                Q_HPSew_gen_W = float(Q_HPSew_therm_W)
                E_HPSew_req_W = float(E_HPSew_req_W)
                Q_coldsource_HPSew_W = float(Q_HPSew_cold_primary_W)

            if (master_to_slave_vars.GHP_on) == 1 and hour >= master_to_slave_vars.GHP_SEASON_ON and hour <= master_to_slave_vars.GHP_SEASON_OFF and Q_therm_req_W > 0 and not np.isclose(
                    tdhsup_K, tdhret_req_K):
                # activating GHP plant if possible

                source_GHP = 0
                cost_GHP_USD = 0.0
                Q_GHP_gen_W = 0.0
                E_GHP_req_W = 0.0
                Q_coldsource_GHP_W = 0.0

                Q_max_W, GHP_COP = GHP_Op_max(tdhsup_K, T_ground, master_to_slave_vars.GHP_number)

                if Q_therm_req_W > Q_max_W:
                    mdot_DH_to_GHP_kgpers = Q_max_W / (HEAT_CAPACITY_OF_WATER_JPERKGK * (tdhsup_K - tdhret_req_K))
                    Q_therm_req_W -= Q_max_W

                else:  # regular operation possible, demand is covered
                    mdot_DH_to_GHP_kgpers = Q_therm_req_W.copy() / (HEAT_CAPACITY_OF_WATER_JPERKGK * (tdhsup_K - tdhret_req_K))
                    Q_therm_req_W = 0

                C_GHP_el, E_GHP_req_W, Q_GHP_cold_primary_W, Q_GHP_therm_W = GHP_op_cost(mdot_DH_to_GHP_kgpers, tdhsup_K, tdhret_req_K, GHP_COP, lca)

                # Storing data for further processing
                source_GHP = 1
                cost_GHP_USD = C_GHP_el
                Q_GHP_gen_W = Q_GHP_therm_W
                E_GHP_req_W = E_GHP_req_W
                Q_coldsource_GHP_W = Q_GHP_cold_primary_W

            if (master_to_slave_vars.HP_Lake_on) == 1 and Q_therm_req_W > 0 and HP_LAKE_ALLOWED == 1 and not np.isclose(tdhsup_K,
                                                                                                          tdhret_req_K):  # run Heat Pump Lake
                source_HP_Lake = 0
                cost_HPLake_USD = 0
                Q_HPLake_gen_W = 0
                E_HPLake_req_W = 0
                Q_coldsource_HPLake_W = 0

                if Q_therm_req_W > master_to_slave_vars.HPLake_maxSize_W:  # Scale down Load, 100% load achieved
                    Q_therm_HPL_W = master_to_slave_vars.HPLake_maxSize_W
                    mdot_DH_to_Lake_kgpers = Q_therm_HPL_W / (
                            HEAT_CAPACITY_OF_WATER_JPERKGK * (
                            tdhsup_K - tdhret_req_K))  # scale down the mass flow if the thermal demand is lowered
                    Q_therm_req_W -= master_to_slave_vars.HPLake_maxSize_W

                else:  # regular operation possible
                    Q_therm_HPL_W = Q_therm_req_W.copy()
                    mdot_DH_to_Lake_kgpers = Q_therm_HPL_W / (HEAT_CAPACITY_OF_WATER_JPERKGK * (tdhsup_K - tdhret_req_K))
                    Q_therm_req_W = 0
                C_HPL_el, E_HPLake_req_W, Q_HPL_cold_primary_W, Q_HPL_therm_W = HPLake_op_cost(mdot_DH_to_Lake_kgpers, tdhsup_K, tdhret_req_K, T_LAKE, lca)

                # Storing Data
                source_HP_Lake = 1
                cost_HPLake_USD = C_HPL_el
                Q_HPLake_gen_W = Q_therm_HPL_W
                E_HPLake_req_W = E_HPLake_req_W
                Q_coldsource_HPLake_W = Q_HPL_cold_primary_W

        if current_source == 'CHP' and Q_therm_req_W > 0:  # start activating the combined cycles

            # By definition, one can either activate the CHP (NG-CC) or ORC (Furnace) BUT NOT BOTH at the same time (not activated by Master)
            Cost_CC = 0.0
            source_CHP = 0
            cost_CHP_USD = 0.0
            Q_CHP_gen_W = 0.0
            Gas_used_CHP_W = 0.0
            E_CHP_gen_W = 0

            if (master_to_slave_vars.CC_on) == 1 and Q_therm_req_W > 0 and CC_ALLOWED == 1:  # only operate if the plant is available
                CC_op_cost_data = calc_cop_CCGT(master_to_slave_vars.CC_GT_SIZE_W, tdhsup_K, master_to_slave_vars.gt_fuel,
                                                prices, lca)  # create cost information
                Q_used_prim_CC_fn_W = CC_op_cost_data['q_input_fn_q_output_W']
                cost_per_Wh_CC_fn = CC_op_cost_data['fuel_cost_per_Wh_th_fn_q_output_W']  # gets interpolated cost function
                q_output_CC_min_W = CC_op_cost_data['q_output_min_W']
                Q_output_CC_max_W = CC_op_cost_data['q_output_max_W']
                eta_elec_interpol = CC_op_cost_data['eta_el_fn_q_input']

                if Q_therm_req_W > q_output_CC_min_W:  # operation Possible if above minimal load
                    if Q_therm_req_W < Q_output_CC_max_W:  # Normal operation Possible within partload regime
                        cost_per_Wh_CC = cost_per_Wh_CC_fn(Q_therm_req_W)
                        Q_used_prim_CC_W = Q_used_prim_CC_fn_W(Q_therm_req_W)
                        Q_CC_delivered_W = Q_therm_req_W.copy()
                        Q_therm_req_W = 0
                        E_CHP_gen_W = np.float(eta_elec_interpol(Q_used_prim_CC_W)) * Q_used_prim_CC_W


                    else:  # Only part of the demand can be delivered as 100% load achieved
                        cost_per_Wh_CC = cost_per_Wh_CC_fn(Q_output_CC_max_W)
                        Q_used_prim_CC_W = Q_used_prim_CC_fn_W(Q_output_CC_max_W)
                        Q_CC_delivered_W = Q_output_CC_max_W
                        Q_therm_req_W -= Q_output_CC_max_W
                        E_CHP_gen_W = np.float(eta_elec_interpol(Q_output_CC_max_W)) * Q_used_prim_CC_W

                    Cost_CC = cost_per_Wh_CC * Q_CC_delivered_W
                    source_CHP = 1
                    cost_CHP_USD = Cost_CC
                    Q_CHP_gen_W = Q_CC_delivered_W
                    Gas_used_CHP_W = Q_used_prim_CC_W

            if (master_to_slave_vars.Furnace_on) == 1 and Q_therm_req_W > 0:  # Activate Furnace if its there. By definition, either ORC or NG-CC!
                Q_Furn_therm_W = 0
                source_Furnace = 0
                cost_Furnace_USD = 0.0
                Q_Furnace_gen_W = 0.0
                Wood_used_Furnace_W = 0.0
                Q_Furn_prim_W = 0.0

                if Q_therm_req_W > (
                        gv.Furn_min_Load * master_to_slave_vars.Furnace_Q_max_W):  # Operate only if its above minimal load

                    if Q_therm_req_W > master_to_slave_vars.Furnace_Q_max_W:  # scale down if above maximum load, Furnace operates at max. capacity
                        Furnace_Cost_Data = furnace_op_cost(master_to_slave_vars.Furnace_Q_max_W, master_to_slave_vars.Furnace_Q_max_W, tdhret_req_K,
                                                            master_to_slave_vars.Furn_Moist_type, gv)

                        C_Furn_therm = Furnace_Cost_Data[0]
                        Q_Furn_prim_W = Furnace_Cost_Data[2]
                        Q_Furn_therm_W = master_to_slave_vars.Furnace_Q_max_W
                        Q_therm_req_W -= Q_Furn_therm_W
                        E_Furnace_gen_W = Furnace_Cost_Data[4]

                    else:  # Normal Operation Possible
                        Furnace_Cost_Data = furnace_op_cost(Q_therm_req_W, master_to_slave_vars.Furnace_Q_max_W, tdhret_req_K,
                                                            master_to_slave_vars.Furn_Moist_type, gv)

                        Q_Furn_prim_W = Furnace_Cost_Data[2]
                        C_Furn_therm = Furnace_Cost_Data[0]
                        Q_Furn_therm_W = Q_therm_req_W.copy()
                        E_Furnace_gen_W = Furnace_Cost_Data[4]

                        Q_therm_req_W = 0

                    source_Furnace = 1
                    cost_Furnace_USD = C_Furn_therm.copy()
                    Q_Furnace_gen_W = Q_Furn_therm_W
                    Wood_used_Furnace_W = Q_Furn_prim_W


        if current_source == 'BoilerBase' and Q_therm_req_W > 0:

            Q_therm_boiler_W = 0
            if (master_to_slave_vars.Boiler_on) == 1:
                source_BaseBoiler = 0
                cost_BaseBoiler_USD = 0.0
                Q_BaseBoiler_gen_W = 0.0
                Gas_used_BaseBoiler_W = 0.0
                E_BaseBoiler_req_W = 0.0

                if Q_therm_req_W >= BOILER_MIN * master_to_slave_vars.Boiler_Q_max_W:  # Boiler can be activated?
                    # Q_therm_boiler = Q_therm_req

                    if Q_therm_req_W >= master_to_slave_vars.Boiler_Q_max_W:  # Boiler above maximum Load?
                        Q_therm_boiler_W = master_to_slave_vars.Boiler_Q_max_W
                    else:
                        Q_therm_boiler_W = Q_therm_req_W.copy()

                    C_boil_therm, C_boil_per_Wh, Q_primary_W, E_aux_Boiler_req_W = cond_boiler_op_cost(Q_therm_boiler_W, master_to_slave_vars.Boiler_Q_max_W, tdhret_req_K, \
                                                           master_to_slave_vars.BoilerType, master_to_slave_vars.EL_TYPE, gv, prices, lca)

                    source_BaseBoiler = 1
                    cost_BaseBoiler_USD = C_boil_therm
                    Q_BaseBoiler_gen_W = Q_therm_boiler_W
                    Gas_used_BaseBoiler_W = Q_primary_W
                    E_BaseBoiler_req_W = E_aux_Boiler_req_W
                    Q_therm_req_W -= Q_therm_boiler_W


        if current_source == 'BoilerPeak' and Q_therm_req_W > 0:

            if (master_to_slave_vars.BoilerPeak_on) == 1:
                source_PeakBoiler = 0
                cost_PeakBoiler_USD = 0.0
                Q_PeakBoiler_gen_W = 0.0
                Gas_used_PeakBoiler_W = 0
                E_PeakBoiler_req_W = 0

                if Q_therm_req_W > 0:  # gv.Boiler_min*master_to_slave_vars.BoilerPeak_Q_max: # Boiler can be activated?

                    if Q_therm_req_W > master_to_slave_vars.BoilerPeak_Q_max_W:  # Boiler above maximum Load?
                        Q_therm_boilerP_W = master_to_slave_vars.BoilerPeak_Q_max_W
                        Q_therm_req_W -= Q_therm_boilerP_W
                    else:
                        Q_therm_boilerP_W = Q_therm_req_W.copy()
                        Q_therm_req_W = 0

                    C_boil_thermP, C_boil_per_WhP, Q_primaryP_W, E_aux_BoilerP_W = cond_boiler_op_cost(Q_therm_boilerP_W, master_to_slave_vars.BoilerPeak_Q_max_W, tdhret_req_K, \
                                                            master_to_slave_vars.BoilerPeakType, master_to_slave_vars.EL_TYPE, gv, prices, lca)

                    source_PeakBoiler = 1
                    cost_PeakBoiler_USD = C_boil_thermP
                    Q_PeakBoiler_gen_W = Q_therm_boilerP_W
                    Gas_used_PeakBoiler_W = Q_primaryP_W
                    E_PeakBoiler_req_W = E_aux_BoilerP_W

        Q_excess_W = 0
        if np.floor(Q_therm_req_W) > 0:
            if current_source == ACT_FIRST:
                current_source = ACT_SECOND
            elif current_source == ACT_SECOND:
                current_source = ACT_THIRD
            elif current_source == ACT_THIRD:
                current_source = ACT_FOURTH
            else:
                Q_uncovered_W = Q_therm_req_W
                break

        elif round(Q_therm_req_W, 0) != 0:
            Q_uncovered_W = 0  # Q_therm_req
            Q_excess_W = -Q_therm_req_W
            Q_therm_req_W = 0
            # break
        else:
            Q_therm_req_W = 0

    source_info = source_HP_Sewage, source_HP_Lake, source_GHP, source_CHP, source_Furnace, source_BaseBoiler, source_PeakBoiler
    Q_source_data_W = Q_HPSew_gen_W, Q_HPLake_gen_W, Q_GHP_gen_W, Q_CHP_gen_W, Q_Furnace_gen_W, Q_BaseBoiler_gen_W, Q_PeakBoiler_gen_W, Q_uncovered_W
    E_PP_el_data_W = E_HPSew_req_W, E_HPLake_req_W, E_GHP_req_W, E_CHP_gen_W, E_Furnace_gen_W, E_BaseBoiler_req_W, E_PeakBoiler_req_W
    E_gas_data_W = Gas_used_HPSew_W, Gas_used_HPLake_W, Gas_used_GHP_W, Gas_used_CHP_W, Gas_used_Furnace_W, Gas_used_BaseBoiler_W, Gas_used_PeakBoiler_W
    E_wood_data_W = Wood_used_HPSew_W, Wood_used_HPLake_W, Wood_used_GHP_W, Wood_used_CHP_W, Wood_used_Furnace_W, Wood_used_BaseBoiler_W, Wood_used_PeakBoiler_W
    E_coldsource_data_W = Q_coldsource_HPSew_W, Q_coldsource_HPLake_W, Q_coldsource_GHP_W, Q_coldsource_CHP_W, \
                          Q_coldsource_Furnace_W, Q_coldsource_BaseBoiler_W, Q_coldsource_PeakBoiler_W

    opex_output = {'Opex_var_HP_Sewage_USD':cost_HPSew_USD,
              'Opex_var_HP_Lake_USD': cost_HPLake_USD,
              'Opex_var_GHP_USD': cost_GHP_USD,
              'Opex_var_CHP_USD': cost_CHP_USD,
              'Opex_var_Furnace_USD': cost_Furnace_USD,
              'Opex_var_BaseBoiler_USD': cost_BaseBoiler_USD,
              'Opex_var_PeakBoiler_USD': cost_PeakBoiler_USD}

    source_output = {'HP_Sewage': source_HP_Sewage,
                     'HP_Lake': source_HP_Lake,
                     'GHP': source_GHP,
                     'CHP': source_CHP,
                     'Furnace': source_Furnace,
                     'BaseBoiler': source_BaseBoiler,
                     'PeakBoiler': source_PeakBoiler}

    Q_output = {'Q_HPSew_gen_W': Q_HPSew_gen_W,
                'Q_HPLake_gen_W': Q_HPLake_gen_W,
                'Q_GHP_gen_W': Q_GHP_gen_W,
                'Q_CHP_gen_W': Q_CHP_gen_W,
                'Q_Furnace_gen_W': Q_Furnace_gen_W,
                'Q_BaseBoiler_gen_W': Q_BaseBoiler_gen_W,
                'Q_PeakBoiler_gen_W': Q_PeakBoiler_gen_W,
                'Q_uncovered_W': Q_uncovered_W}

    E_output = {'E_HPSew_req_W': E_HPSew_req_W,
                'E_HPLake_req_W': E_HPLake_req_W,
                'E_GHP_req_W': E_GHP_req_W,
                'E_CHP_gen_W': E_CHP_gen_W,
                'E_Furnace_gen_W': E_Furnace_gen_W,
                'E_BaseBoiler_req_W': E_BaseBoiler_req_W,
                'E_PeakBoiler_req_W': E_PeakBoiler_req_W}

    Gas_output = {'Gas_used_HPSew_W': Gas_used_HPSew_W,
                  'Gas_used_HPLake_W': Gas_used_HPLake_W,
                  'Gas_used_GHP_W': Gas_used_GHP_W,
                  'Gas_used_CHP_W': Gas_used_CHP_W,
                  'Gas_used_Furnace_W': Gas_used_Furnace_W,
                  'Gas_used_BaseBoiler_W': Gas_used_BaseBoiler_W,
                  'Gas_used_PeakBoiler_W': Gas_used_PeakBoiler_W}

    Wood_output = {'Wood_used_HPSew_W': Wood_used_HPSew_W,
                   'Wood_used_HPLake_W': Wood_used_HPLake_W,
                   'Wood_used_GHP_W': Wood_used_GHP_W,
                   'Wood_used_CHP_W': Wood_used_CHP_W,
                   'Wood_used_Furnace_W': Wood_used_Furnace_W,
                   'Wood_used_BaseBoiler_W': Wood_used_BaseBoiler_W,
                   'Wood_used_PeakBoiler_W': Wood_used_PeakBoiler_W}

    coldsource_output = {'Q_coldsource_HPSew_W': Q_coldsource_HPSew_W,
                         'Q_coldsource_HPLake_W': Q_coldsource_HPLake_W,
                         'Q_coldsource_GHP_W': Q_coldsource_GHP_W,
                         'Q_coldsource_CHP_W': Q_coldsource_CHP_W,
                         'Q_coldsource_Furnace_W': Q_coldsource_Furnace_W,
                         'Q_coldsource_BaseBoiler_W': Q_coldsource_BaseBoiler_W,
                         'Q_coldsource_PeakBoiler_W': Q_coldsource_PeakBoiler_W}

    return opex_output, source_output, Q_output, E_output, Gas_output, Wood_output, coldsource_output, Q_excess_W
def cooling_calculations_of_DC_buildings(locator, master_to_slave_vars, ntwFeat, prices, lca, config, reduced_timesteps_flag):
    """
    Computes the parameters for the cooling of the complete DCN

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

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

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

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

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

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

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

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

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

    T_ground_K = calculate_ground_temperature(locator, config)

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

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

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


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

    Qc_VCC_backup_max_W = (Q_peak_load_W - Qc_ACH_max_W - Qc_VCC_max_W - Qc_tank_discharge_peak_W)

    if Qc_VCC_backup_max_W < 0:
        Qc_VCC_backup_max_W = 0

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    costs_a_USD += Capex_a_CT_USD + Opex_fixed_CT_USD

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

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

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

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

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

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

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

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

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

    return (costs_a_USD, CO2_kgCO2, prim_MJ)
def district_cooling_network(locator,
                             master_to_slave_variables,
                             config,
                             prices,
                             network_features):
    """
    Computes the parameters for the cooling of the complete DCN

    :param cea.inputlocator.InputLocator locator: path to res folder
    :param network_features: network features
    :param prices: Prices imported from the database
    :type network_features: class
    :type prices: class
    :return: costs, co2, prim
    :rtype: tuple
    """

    if master_to_slave_variables.DCN_exists:
        # THERMAL STORAGE + NETWORK
        # Import Temperatures from Network Summary:
        Q_thermal_req_W, \
        T_district_cooling_return_K, \
        T_district_cooling_supply_K, \
        mdot_kgpers = calc_network_summary_DCN(master_to_slave_variables)

        # Initialize daily storage calss
        T_ground_K = calculate_ground_temperature(locator)
        daily_storage = LoadLevelingDailyStorage(master_to_slave_variables.Storage_cooling_on,
                                                 master_to_slave_variables.Storage_cooling_size_W,
                                                 min(T_district_cooling_supply_K) - DT_COOL,
                                                 max(T_district_cooling_return_K) - DT_COOL,
                                                 T_TANK_FULLY_DISCHARGED_K,
                                                 np.mean(T_ground_K)
                                                 )

        # Import Data - potentials lake heat
        if master_to_slave_variables.WS_BaseVCC_on == 1 or master_to_slave_variables.WS_PeakVCC_on == 1:
            HPlake_Data = pd.read_csv(locator.get_water_body_potential())
            Q_therm_Lake = np.array(HPlake_Data['QLake_kW']) * 1E3
            total_WS_VCC_installed = master_to_slave_variables.WS_BaseVCC_size_W + master_to_slave_variables.WS_PeakVCC_size_W
            Q_therm_Lake_W = [x if x < total_WS_VCC_installed else total_WS_VCC_installed for x in Q_therm_Lake]
            T_source_average_Lake_K = np.array(HPlake_Data['Ts_C']) + 273
        else:
            Q_therm_Lake_W = np.zeros(HOURS_IN_YEAR)
            T_source_average_Lake_K = np.zeros(HOURS_IN_YEAR)

        # get properties of technology used in this script
        absorption_chiller = AbsorptionChiller(pd.read_excel(locator.get_database_conversion_systems(), sheet_name="Absorption_chiller"), 'double')
        CCGT_prop = calc_cop_CCGT(master_to_slave_variables.NG_Trigen_ACH_size_W, ACH_T_IN_FROM_CHP_K, "NG")

        VCC_database = pd.read_excel(locator.get_database_conversion_systems(), sheet_name="Chiller")
        technology_type = VCC_CODE_CENTRALIZED
        VCC_database = VCC_database[VCC_database['code'] == technology_type]
        max_VCC_capacity = int(VCC_database['cap_max'])
        min_VCC_capacity = int(VCC_database['cap_min'])
        # G_VALUE = VCC_database['ISENTROPIC_EFFICIENCY'] # create vessel to carry down gvalue and max_VCC_capacity, min_VCC_capacity to VCC module

        # initialize variables
        Q_Trigen_NG_gen_W = np.zeros(HOURS_IN_YEAR)
        Q_BaseVCC_WS_gen_W = np.zeros(HOURS_IN_YEAR)
        Q_PeakVCC_WS_gen_W = np.zeros(HOURS_IN_YEAR)
        Q_BaseVCC_AS_gen_W = np.zeros(HOURS_IN_YEAR)
        Q_PeakVCC_AS_gen_W = np.zeros(HOURS_IN_YEAR)
        Q_DailyStorage_gen_directload_W = np.zeros(HOURS_IN_YEAR)

        E_Trigen_NG_gen_W = np.zeros(HOURS_IN_YEAR)
        E_BaseVCC_AS_req_W = np.zeros(HOURS_IN_YEAR)
        E_PeakVCC_AS_req_W = np.zeros(HOURS_IN_YEAR)
        E_BaseVCC_WS_req_W = np.zeros(HOURS_IN_YEAR)
        E_PeakVCC_WS_req_W = np.zeros(HOURS_IN_YEAR)
        NG_Trigen_req_W = np.zeros(HOURS_IN_YEAR)
        Q_BackupVCC_AS_gen_W = np.zeros(HOURS_IN_YEAR)

        Q_Trigen_NG_gen_directload_W = np.zeros(HOURS_IN_YEAR)
        Q_BaseVCC_WS_gen_directload_W = np.zeros(HOURS_IN_YEAR)
        Q_PeakVCC_WS_gen_directload_W = np.zeros(HOURS_IN_YEAR)
        Q_BaseVCC_AS_gen_directload_W = np.zeros(HOURS_IN_YEAR)
        Q_PeakVCC_AS_gen_directload_W = np.zeros(HOURS_IN_YEAR)
        Q_BackupVCC_AS_directload_W = np.zeros(HOURS_IN_YEAR)

        for hour in range(HOURS_IN_YEAR):  # cooling supply for all buildings excluding cooling loads from data centers
            if Q_thermal_req_W[hour] > 0.0:  # only if there is a cooling load!
                daily_storage, \
                thermal_output, \
                electricity_output, \
                gas_output = cooling_resource_activator(Q_thermal_req_W[hour],
                                                        T_district_cooling_supply_K[hour],
                                                        T_district_cooling_return_K[hour],
                                                        Q_therm_Lake_W[hour],
                                                        T_source_average_Lake_K[hour],
                                                        daily_storage,
                                                        T_ground_K[hour],
                                                        master_to_slave_variables,
                                                        absorption_chiller,
                                                        CCGT_prop,
                                                        min_VCC_capacity,
                                                        max_VCC_capacity)

                Q_DailyStorage_gen_directload_W[hour] = thermal_output['Q_DailyStorage_gen_directload_W']
                Q_Trigen_NG_gen_directload_W[hour] = thermal_output['Q_Trigen_NG_gen_directload_W']
                Q_BaseVCC_WS_gen_directload_W[hour] = thermal_output['Q_BaseVCC_WS_gen_directload_W']
                Q_PeakVCC_WS_gen_directload_W[hour] = thermal_output['Q_PeakVCC_WS_gen_directload_W']
                Q_BaseVCC_AS_gen_directload_W[hour] = thermal_output['Q_BaseVCC_AS_gen_directload_W']
                Q_PeakVCC_AS_gen_directload_W[hour] = thermal_output['Q_PeakVCC_AS_gen_directload_W']
                Q_BackupVCC_AS_directload_W[hour] = thermal_output['Q_BackupVCC_AS_directload_W']

                Q_Trigen_NG_gen_W[hour] = thermal_output['Q_Trigen_NG_gen_W']
                Q_BaseVCC_WS_gen_W[hour] = thermal_output['Q_BaseVCC_WS_gen_W']
                Q_PeakVCC_WS_gen_W[hour] = thermal_output['Q_PeakVCC_WS_gen_W']
                Q_BaseVCC_AS_gen_W[hour] = thermal_output['Q_BaseVCC_AS_gen_W']
                Q_PeakVCC_AS_gen_W[hour] = thermal_output['Q_PeakVCC_AS_gen_W']
                Q_BackupVCC_AS_gen_W[hour] = thermal_output['Q_BackupVCC_AS_gen_W']

                E_BaseVCC_WS_req_W[hour] = electricity_output['E_BaseVCC_WS_req_W']
                E_PeakVCC_WS_req_W[hour] = electricity_output['E_PeakVCC_WS_req_W']
                E_BaseVCC_AS_req_W[hour] = electricity_output['E_BaseVCC_AS_req_W']
                E_PeakVCC_AS_req_W[hour] = electricity_output['E_PeakVCC_AS_req_W']
                E_Trigen_NG_gen_W[hour] = electricity_output['E_Trigen_NG_gen_W']

                NG_Trigen_req_W[hour] = gas_output['NG_Trigen_req_W']

        #calculate the electrical capacity as a function of the peak produced by the turbine
        master_to_slave_variables.NG_Trigen_CCGT_size_electrical_W = E_Trigen_NG_gen_W.max()

        # BACK-UPP VCC - AIR SOURCE
        scale = 'DISTRICT'
        master_to_slave_variables.AS_BackupVCC_size_W = np.amax(Q_BackupVCC_AS_gen_W)
        size_chiller_CT = master_to_slave_variables.AS_BackupVCC_size_W
        if master_to_slave_variables.AS_BackupVCC_size_W != 0.0:
            master_to_slave_variables.AS_BackupVCC_on = 1
            Q_BackupVCC_AS_gen_W, E_BackupVCC_AS_req_W = np.vectorize(calc_vcc_CT_operation)(Q_BackupVCC_AS_gen_W,
                                                                                             T_district_cooling_return_K,
                                                                                             T_district_cooling_supply_K,
                                                                                             VCC_T_COOL_IN,
                                                                                             size_chiller_CT,
                                                                                             min_VCC_capacity,
                                                                                             max_VCC_capacity,
                                                                                             scale)
        else:
            E_BackupVCC_AS_req_W = np.zeros(HOURS_IN_YEAR)

        # CAPEX (ANNUAL, TOTAL) AND OPEX (FIXED, VAR, ANNUAL) GENERATION UNITS
        supply_systems = SupplySystemsDatabase(locator)
        mdotnMax_kgpers = np.amax(mdot_kgpers)
        performance_costs_generation, \
        district_cooling_capacity_installed = cost_model.calc_generation_costs_capacity_installed_cooling(locator,
                                                                                                          master_to_slave_variables,
                                                                                                          supply_systems,
                                                                                                          mdotnMax_kgpers
                                                                                                          )
        # CAPEX (ANNUAL, TOTAL) AND OPEX (FIXED, VAR, ANNUAL) STORAGE UNITS
        performance_costs_storage = cost_model.calc_generation_costs_cooling_storage(locator,
                                                                                     master_to_slave_variables,
                                                                                     config,
                                                                                     daily_storage
                                                                                     )

        # CAPEX (ANNUAL, TOTAL) AND OPEX (FIXED, VAR, ANNUAL) NETWORK
        performance_costs_network, \
        E_used_district_cooling_network_W = cost_model.calc_network_costs_cooling(locator,
                                                                                  master_to_slave_variables,
                                                                                  network_features,
                                                                                  "DC",
                                                                                  prices)

        # MERGE COSTS AND EMISSIONS IN ONE FILE
        performance = dict(performance_costs_generation, **performance_costs_storage)
        district_cooling_costs = dict(performance, **performance_costs_network)
    else:
        Q_thermal_req_W = np.zeros(HOURS_IN_YEAR)
        Q_DailyStorage_gen_directload_W = np.zeros(HOURS_IN_YEAR)
        Q_Trigen_NG_gen_directload_W = np.zeros(HOURS_IN_YEAR)
        Q_BaseVCC_WS_gen_directload_W = np.zeros(HOURS_IN_YEAR)
        Q_PeakVCC_WS_gen_directload_W = np.zeros(HOURS_IN_YEAR)
        Q_BaseVCC_AS_gen_directload_W = np.zeros(HOURS_IN_YEAR)
        Q_PeakVCC_AS_gen_directload_W = np.zeros(HOURS_IN_YEAR)
        Q_BackupVCC_AS_directload_W = np.zeros(HOURS_IN_YEAR)
        Q_Trigen_NG_gen_W = np.zeros(HOURS_IN_YEAR)
        Q_BaseVCC_WS_gen_W = np.zeros(HOURS_IN_YEAR)
        Q_PeakVCC_WS_gen_W = np.zeros(HOURS_IN_YEAR)
        Q_BaseVCC_AS_gen_W = np.zeros(HOURS_IN_YEAR)
        Q_PeakVCC_AS_gen_W = np.zeros(HOURS_IN_YEAR)
        Q_BackupVCC_AS_gen_W = np.zeros(HOURS_IN_YEAR)
        E_Trigen_NG_gen_W = np.zeros(HOURS_IN_YEAR)
        E_used_district_cooling_network_W = np.zeros(HOURS_IN_YEAR)
        E_BaseVCC_WS_req_W = np.zeros(HOURS_IN_YEAR)
        E_PeakVCC_WS_req_W = np.zeros(HOURS_IN_YEAR)
        E_BaseVCC_AS_req_W = np.zeros(HOURS_IN_YEAR)
        E_PeakVCC_AS_req_W = np.zeros(HOURS_IN_YEAR)
        E_BackupVCC_AS_req_W = np.zeros(HOURS_IN_YEAR)
        NG_Trigen_req_W = np.zeros(HOURS_IN_YEAR)
        district_cooling_costs = {}
        district_cooling_capacity_installed = {}

    # SAVE
    district_cooling_generation_dispatch = {
        # demand of the network
        "Q_districtcooling_sys_req_W": Q_thermal_req_W,

        # ENERGY GENERATION TO DIRECT LOAD
        # from storage
        "Q_DailyStorage_gen_directload_W": Q_DailyStorage_gen_directload_W,
        # cooling
        "Q_Trigen_NG_gen_directload_W": Q_Trigen_NG_gen_directload_W,
        "Q_BaseVCC_WS_gen_directload_W": Q_BaseVCC_WS_gen_directload_W,
        "Q_PeakVCC_WS_gen_directload_W": Q_PeakVCC_WS_gen_directload_W,
        "Q_BaseVCC_AS_gen_directload_W": Q_BaseVCC_AS_gen_directload_W,
        "Q_PeakVCC_AS_gen_directload_W": Q_PeakVCC_AS_gen_directload_W,
        "Q_BackupVCC_AS_directload_W": Q_BackupVCC_AS_directload_W,

        # ENERGY GENERATION TOTAL
        # cooling
        "Q_Trigen_NG_gen_W": Q_Trigen_NG_gen_W,
        "Q_BaseVCC_WS_gen_W": Q_BaseVCC_WS_gen_W,
        "Q_PeakVCC_WS_gen_W": Q_PeakVCC_WS_gen_W,
        "Q_BaseVCC_AS_gen_W": Q_BaseVCC_AS_gen_W,
        "Q_PeakVCC_AS_gen_W": Q_PeakVCC_AS_gen_W,
        "Q_BackupVCC_AS_W": Q_BackupVCC_AS_gen_W,

        # electricity
        "E_Trigen_NG_gen_W": E_Trigen_NG_gen_W
    }

    district_cooling_electricity_requirements_dispatch = {
        # ENERGY REQUIREMENTS
        # Electricity
        "E_DCN_req_W": E_used_district_cooling_network_W,
        "E_BaseVCC_WS_req_W": E_BaseVCC_WS_req_W,
        "E_PeakVCC_WS_req_W": E_PeakVCC_WS_req_W,
        "E_BaseVCC_AS_req_W": E_BaseVCC_AS_req_W,
        "E_PeakVCC_AS_req_W": E_PeakVCC_AS_req_W,
        "E_BackupVCC_AS_req_W": E_BackupVCC_AS_req_W,
    }

    district_cooling_fuel_requirements_dispatch = {
        # fuels
        "NG_Trigen_req_W": NG_Trigen_req_W
    }

    # PLOT RESULTS

    return district_cooling_costs, \
           district_cooling_generation_dispatch, \
           district_cooling_electricity_requirements_dispatch, \
           district_cooling_fuel_requirements_dispatch, \
           district_cooling_capacity_installed
def heating_source_activator(Q_therm_req_W, master_to_slave_vars,
                             Q_therm_GHP_W, TretGHPArray_K, TretLakeArray_K,
                             Q_therm_Lake_W, Q_therm_Sew_W, TretsewArray_K,
                             tdhsup_K, tdhret_req_K):
    """
    :param Q_therm_req_W:
    :param hour:
    :param context:
    :type Q_therm_req_W: float
    :type hour: int
    :type context: list
    :return: cost_data_centralPlant_op, source_info, Q_source_data, E_coldsource_data, E_PP_el_data, E_gas_data, E_wood_data, Q_excess
    :rtype:
    """

    ## initializing unmet heating load
    Q_heat_unmet_W = Q_therm_req_W

    # ACTIVATE THE COGEN
    if master_to_slave_vars.CC_on == 1 and Q_heat_unmet_W > 0.0:

        CC_op_cost_data = calc_cop_CCGT(master_to_slave_vars.CCGT_SIZE_W,
                                        tdhsup_K,
                                        "NG")  # create cost information
        Q_used_prim_CC_fn_W = CC_op_cost_data['q_input_fn_q_output_W']
        q_output_CC_min_W = CC_op_cost_data['q_output_min_W']
        Q_output_CC_max_W = CC_op_cost_data['q_output_max_W']
        eta_elec_interpol = CC_op_cost_data['eta_el_fn_q_input']

        if Q_heat_unmet_W >= q_output_CC_min_W:
            # operation Possible if above minimal load
            if Q_heat_unmet_W <= Q_output_CC_max_W:  # Normal operation Possible within partload regime
                Q_CHP_gen_W = Q_heat_unmet_W
                NG_CHP_req_W = Q_used_prim_CC_fn_W(Q_CHP_gen_W)
                E_CHP_gen_W = np.float(
                    eta_elec_interpol(NG_CHP_req_W)) * NG_CHP_req_W
            else:  # Only part of the demand can be delivered as 100% load achieved
                Q_CHP_gen_W = Q_output_CC_max_W
                NG_CHP_req_W = Q_used_prim_CC_fn_W(Q_CHP_gen_W)
                E_CHP_gen_W = np.float(
                    eta_elec_interpol(NG_CHP_req_W)) * NG_CHP_req_W
        else:
            NG_CHP_req_W = 0.0
            E_CHP_gen_W = 0.0
            Q_CHP_gen_W = 0.0
        Q_heat_unmet_W = Q_heat_unmet_W - Q_CHP_gen_W
    else:
        NG_CHP_req_W = 0.0
        E_CHP_gen_W = 0.0
        Q_CHP_gen_W = 0.0

    # WET FURNACE
    if master_to_slave_vars.Furnace_wet_on == 1 and Q_heat_unmet_W > 0.0:  # Activate Furnace if its there.
        # Operate only if its above minimal load
        if Q_heat_unmet_W > master_to_slave_vars.WBFurnace_Q_max_W:
            if Q_heat_unmet_W > master_to_slave_vars.WBFurnace_Q_max_W:
                Q_Furnace_wet_gen_W = master_to_slave_vars.WBFurnace_Q_max_W
                # scale down if above maximum load, Furnace operates at max. capacity
                DryBiomass_Furnace_req_W, E_Furnace_wet_gen_W = furnace_op_cost(
                    Q_Furnace_wet_gen_W,
                    master_to_slave_vars.WBFurnace_Q_max_W, tdhret_req_K,
                    "wet")

            else:  # Normal Operation Possible
                Q_Furnace_wet_gen_W = Q_heat_unmet_W
                DryBiomass_Furnace_req_W, E_Furnace_wet_gen_W = furnace_op_cost(
                    Q_Furnace_wet_gen_W,
                    master_to_slave_vars.WBFurnace_Q_max_W, tdhret_req_K,
                    "wet")
        else:
            E_Furnace_wet_gen_W = 0.0
            DryBiomass_Furnace_req_W = 0.0
            Q_Furnace_wet_gen_W = 0.0

        Q_heat_unmet_W = Q_heat_unmet_W - Q_Furnace_wet_gen_W

    else:
        E_Furnace_wet_gen_W = 0.0
        DryBiomass_Furnace_req_W = 0.0
        Q_Furnace_wet_gen_W = 0.0

    # DRY FURNACE
    if master_to_slave_vars.Furnace_dry_on == 1 and Q_heat_unmet_W > 0.0:  # Activate Furnace if its there.
        # Operate only if its above minimal load
        if Q_heat_unmet_W > master_to_slave_vars.DBFurnace_Q_max_W:
            if Q_heat_unmet_W > master_to_slave_vars.DBFurnace_Q_max_W:
                Q_Furnace_dry_gen_W = master_to_slave_vars.DBFurnace_Q_max_W
                # scale down if above maximum load, Furnace operates at max. capacity
                WetBiomass_Furnace_req_W, E_Furnace_dry_gen_W = furnace_op_cost(
                    Q_Furnace_dry_gen_W,
                    master_to_slave_vars.DBFurnace_Q_max_W, tdhret_req_K,
                    "dry")

            else:  # Normal Operation Possible
                Q_Furnace_dry_gen_W = Q_heat_unmet_W
                WetBiomass_Furnace_req_W, E_Furnace_dry_gen_W = furnace_op_cost(
                    Q_Furnace_dry_gen_W,
                    master_to_slave_vars.DBFurnace_Q_max_W, tdhret_req_K,
                    "dry")
        else:
            E_Furnace_dry_gen_W = 0.0
            WetBiomass_Furnace_req_W = 0.0
            Q_Furnace_dry_gen_W = 0.0

        Q_heat_unmet_W = Q_heat_unmet_W - Q_Furnace_dry_gen_W
    else:
        E_Furnace_dry_gen_W = 0.0
        WetBiomass_Furnace_req_W = 0.0
        Q_Furnace_dry_gen_W = 0.0

    if (master_to_slave_vars.HPSew_on
        ) == 1 and Q_heat_unmet_W > 0.0 and not np.isclose(
            tdhsup_K, tdhret_req_K):  # activate if its available

        if Q_heat_unmet_W > Q_therm_Sew_W:
            Q_HPSew_gen_W = Q_therm_Sew_W
            mdot_DH_to_Sew_kgpers = Q_HPSew_gen_W / (
                HEAT_CAPACITY_OF_WATER_JPERKGK * (tdhsup_K - tdhret_req_K))
        else:
            Q_HPSew_gen_W = Q_heat_unmet_W
            mdot_DH_to_Sew_kgpers = Q_HPSew_gen_W / (
                HEAT_CAPACITY_OF_WATER_JPERKGK * (tdhsup_K - tdhret_req_K))

        E_HPSew_req_W, \
        Q_coldsource_HPSew_W, \
        Q_HPSew_gen_W = HPSew_op_cost(mdot_DH_to_Sew_kgpers,
                                      tdhsup_K,
                                      tdhret_req_K,
                                      TretsewArray_K,
                                      Q_HPSew_gen_W
                                      )

        Q_heat_unmet_W = Q_heat_unmet_W - Q_HPSew_gen_W

    else:
        E_HPSew_req_W = 0.0
        Q_HPSew_gen_W = 0.0

    if (master_to_slave_vars.HPLake_on
        ) == 1 and Q_heat_unmet_W > 0.0 and not np.isclose(
            tdhsup_K, tdhret_req_K):
        if Q_heat_unmet_W > Q_therm_Lake_W:  # Scale down Load, 100% load achieved
            Q_HPLake_gen_W = Q_therm_Lake_W
        else:  # regular operation possible
            Q_HPLake_gen_W = Q_heat_unmet_W

        E_HPLake_req_W, Q_coldsource_HPLake_W, Q_HPLake_gen_W = HPLake_op_cost(
            Q_HPLake_gen_W, tdhsup_K, tdhret_req_K, TretLakeArray_K)
        E_pump_req_W = calc_water_body_uptake_pumping(Q_HPLake_gen_W,
                                                      tdhret_req_K, tdhsup_K)

        E_HPLake_req_W += E_pump_req_W

        Q_heat_unmet_W = Q_heat_unmet_W - Q_HPLake_gen_W

    else:
        E_HPLake_req_W = 0.0
        Q_HPLake_gen_W = 0.0

    if (master_to_slave_vars.GHP_on
        ) == 1 and Q_heat_unmet_W > 0.0 and not np.isclose(
            tdhsup_K, tdhret_req_K):
        if Q_heat_unmet_W > Q_therm_GHP_W:
            Q_GHP_gen_W = Q_therm_GHP_W
            mdot_DH_to_GHP_kgpers = Q_GHP_gen_W / (
                HEAT_CAPACITY_OF_WATER_JPERKGK * (tdhsup_K - tdhret_req_K))
        else:  # regular operation possible, demand is covered
            Q_GHP_gen_W = Q_heat_unmet_W
            mdot_DH_to_GHP_kgpers = Q_GHP_gen_W / (
                HEAT_CAPACITY_OF_WATER_JPERKGK * (tdhsup_K - tdhret_req_K))

        E_GHP_req_W, Q_coldsource_GHP_W, Q_GHP_gen_W = GHP_op_cost(
            mdot_DH_to_GHP_kgpers, tdhsup_K, tdhret_req_K, TretGHPArray_K,
            Q_GHP_gen_W)
        Q_heat_unmet_W = Q_heat_unmet_W - Q_GHP_gen_W

    else:
        E_GHP_req_W = 0.0
        Q_GHP_gen_W = 0.0

    if (master_to_slave_vars.Boiler_on) == 1 and Q_heat_unmet_W > 0:
        if Q_heat_unmet_W >= BOILER_MIN * master_to_slave_vars.Boiler_Q_max_W:  # Boiler can be activated?
            if Q_heat_unmet_W >= master_to_slave_vars.Boiler_Q_max_W:  # Boiler above maximum Load?
                Q_BaseBoiler_gen_W = master_to_slave_vars.Boiler_Q_max_W
            else:
                Q_BaseBoiler_gen_W = Q_heat_unmet_W

            NG_BaseBoiler_req_W, E_BaseBoiler_req_W = cond_boiler_op_cost(
                Q_BaseBoiler_gen_W, master_to_slave_vars.Boiler_Q_max_W,
                tdhret_req_K)
        else:
            Q_BaseBoiler_gen_W = 0.0
            NG_BaseBoiler_req_W = 0.0
            E_BaseBoiler_req_W = 0.0

        Q_heat_unmet_W = Q_heat_unmet_W - Q_BaseBoiler_gen_W

    else:
        Q_BaseBoiler_gen_W = 0.0
        NG_BaseBoiler_req_W = 0.0
        E_BaseBoiler_req_W = 0.0

    if master_to_slave_vars.BoilerPeak_on == 1 and Q_heat_unmet_W > 0:
        if Q_heat_unmet_W >= BOILER_MIN * master_to_slave_vars.BoilerPeak_Q_max_W:  # Boiler can be activated?
            if Q_heat_unmet_W > master_to_slave_vars.BoilerPeak_Q_max_W:  # Boiler above maximum Load?
                Q_PeakBoiler_gen_W = master_to_slave_vars.BoilerPeak_Q_max_W
            else:
                Q_PeakBoiler_gen_W = Q_heat_unmet_W

            NG_PeakBoiler_req_W, E_PeakBoiler_req_W = cond_boiler_op_cost(
                Q_PeakBoiler_gen_W, master_to_slave_vars.BoilerPeak_Q_max_W,
                tdhret_req_K)
        else:
            Q_PeakBoiler_gen_W = 0.0
            NG_PeakBoiler_req_W = 0
            E_PeakBoiler_req_W = 0.0

        Q_heat_unmet_W = Q_heat_unmet_W - Q_PeakBoiler_gen_W

    else:
        Q_PeakBoiler_gen_W = 0.0
        NG_PeakBoiler_req_W = 0
        E_PeakBoiler_req_W = 0.0

    if Q_heat_unmet_W > 1.0E-3:
        Q_uncovered_W = Q_heat_unmet_W  # this will become the back-up boiler
    else:
        Q_uncovered_W = 0.0

    return Q_HPSew_gen_W, \
           Q_HPLake_gen_W, \
           Q_GHP_gen_W, \
           Q_CHP_gen_W, \
           Q_Furnace_dry_gen_W, \
           Q_Furnace_wet_gen_W, \
           Q_BaseBoiler_gen_W, \
           Q_PeakBoiler_gen_W, \
           Q_uncovered_W, \
           E_HPSew_req_W, \
           E_HPLake_req_W, \
           E_BaseBoiler_req_W, \
           E_PeakBoiler_req_W, \
           E_GHP_req_W, \
           E_CHP_gen_W, \
           E_Furnace_dry_gen_W, \
           E_Furnace_wet_gen_W, \
           NG_CHP_req_W, \
           NG_BaseBoiler_req_W, \
           NG_PeakBoiler_req_W, \
           WetBiomass_Furnace_req_W, \
           DryBiomass_Furnace_req_W