Ejemplo n.º 1
0
def slave_main(locator, master_to_slave_vars, solar_features, gv, config,
               prices, lca):
    """
    This function calls the storage optimization and a least cost optimization function.
    Both functions aim at selecting the dispatch pattern of the technologies selected by the evolutionary algorithm.

    :param locator: locator class
    :param network_file_name: name of the network file
    :param master_to_slave_vars: class MastertoSlaveVars containing the value of variables to be passed to the slave
                                 optimization for each individual
    :param solar_features: class solar_features
    :param gv: global variables class
    :type locator: class
    :type network_file_name: string
    :type master_to_slave_vars: class
    :type solar_features: class
    :type gv: class
    :return: E_oil_eq_MJ: primary energy
             CO2_kg_eq: co2 emissions
             cost_sum: accumualted costs during operation
             QUncoveredDesign: part of the design load not covered
             QUncoveredAnnual: part of the total load not covered
    :rtype: float, float, float, float, float

    """
    t0 = time.time()
    # run storage optimization
    storage_main.storage_optimization(locator, master_to_slave_vars, config)

    # run activation pattern
    E_oil_eq_MJ, CO2_kg_eq, cost_sum,\
    Q_uncovered_design_W, Q_uncovered_annual_W = least_cost.least_cost_main(locator, master_to_slave_vars,
                                                                    solar_features, gv, prices, lca, config)

    print " Slave Optimization done (", round(
        time.time() - t0, 1), " seconds used for this task)"

    return E_oil_eq_MJ, CO2_kg_eq, cost_sum, Q_uncovered_design_W, Q_uncovered_annual_W
Ejemplo n.º 2
0
def evaluation_main(individual, building_names, locator, solar_features,
                    network_features, gv, config, prices, lca, ind_num, gen):
    """
    This function evaluates an individual

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    # District Heating Calculations
    if config.district_heating_network:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    # Saving capacity details of the individual

    return costs_USD, GHG_tonCO2, PEN_MJoil, master_to_slave_vars, individual
Ejemplo n.º 3
0
def district_heating_network(locator, master_to_slave_variables, config,
                             network_features):
    """
    Computes the parameters for the heating of the complete DHN

    :param locator: locator class
    :param master_to_slave_variables: class MastertoSlaveVars containing the value of variables to be passed to the
        slave optimization for each individual
    :param solar_features: solar features class
    :type locator: class
    :type master_to_slave_variables: class
    :type solar_features: class
    :return:
        - E_oil_eq_MJ: MJ oil Equivalent used during operation
        - CO2_kg_eq: kg of CO2-Equivalent emitted during operation
        - cost_sum: total cost in CHF used for operation
        - Q_source_data[:,7]: uncovered demand

    :rtype: float, float, float, array

    """
    if master_to_slave_variables.DHN_exists:
        # THERMAL STORAGE + NETWORK
        print(
            "CALCULATING ECOLOGICAL COSTS OF SEASONAL STORAGE - DUE TO OPERATION (IF ANY)"
        )
        storage_dispatch = storage_main.storage_optimization(
            locator, master_to_slave_variables, config)
        # Import data from storage optimization
        Q_DH_networkload_W = np.array(storage_dispatch['Q_DH_networkload_W'])
        Q_thermal_req_W = np.array(storage_dispatch['Q_req_after_storage_W'])

        E_PVT_gen_W = storage_dispatch['E_PVT_gen_W']

        Q_PVT_to_directload_W = storage_dispatch["Q_PVT_gen_directload_W"]
        Q_PVT_to_storage_W = storage_dispatch["Q_PVT_gen_storage_W"]

        Q_SC_ET_to_directload_W = storage_dispatch["Q_SC_ET_gen_directload_W"]
        Q_SC_ET_to_storage_W = storage_dispatch["Q_SC_ET_gen_storage_W"]

        Q_SC_FP_to_directload_W = storage_dispatch["Q_SC_FP_gen_directload_W"]
        Q_SC_FP_to_storage_W = storage_dispatch["Q_SC_FP_gen_storage_W"]

        Q_HP_Server_to_directload_W = storage_dispatch[
            "Q_HP_Server_gen_directload_W"]
        Q_HP_Server_to_storage_W = storage_dispatch[
            "Q_HP_Server_gen_storage_W"]

        E_Storage_req_charging_W = storage_dispatch["E_Storage_charging_req_W"]
        E_Storage_req_discharging_W = storage_dispatch[
            "E_Storage_discharging_req_W"]
        E_HP_SC_FP_req_W = storage_dispatch["E_HP_SC_FP_req_W"]
        E_HP_SC_ET_req_W = storage_dispatch["E_HP_SC_ET_req_W"]
        E_HP_PVT_req_W = storage_dispatch["E_HP_PVT_req_W"]
        E_HP_Server_req_W = storage_dispatch["E_HP_Server_req_W"]

        Q_SC_ET_gen_W = storage_dispatch["Q_SC_ET_gen_W"]
        Q_SC_FP_gen_W = storage_dispatch["Q_SC_FP_gen_W"]
        Q_PVT_gen_W = storage_dispatch["Q_PVT_gen_W"]
        Q_Server_gen_W = storage_dispatch["Q_HP_Server_gen_W"]

        Q_Storage_gen_W = storage_dispatch["Q_Storage_gen_W"]

        # HEATING PLANT
        # Import Temperatures from Network Summary:
        mdot_DH_kgpers, \
        T_district_heating_return_K, \
        T_district_heating_supply_K = calc_network_summary_DHN(master_to_slave_variables)

        # FIXED ORDER ACTIVATION STARTS
        # Import Data - Sewage heat
        if master_to_slave_variables.HPSew_on == 1:
            HPSew_Data = pd.read_csv(locator.get_sewage_heat_potential())
            Q_therm_Sew = np.array(HPSew_Data['Qsw_kW']) * 1E3
            Q_therm_Sew_W = [
                x if x < master_to_slave_variables.HPSew_maxSize_W else
                master_to_slave_variables.HPSew_maxSize_W for x in Q_therm_Sew
            ]
            T_source_average_sewage_K = np.array(HPSew_Data['Ts_C']) + 273
        else:
            Q_therm_Sew_W = np.zeros(HOURS_IN_YEAR)
            T_source_average_sewage_K = np.zeros(HOURS_IN_YEAR)

        # Import Data - lake heat
        if master_to_slave_variables.HPLake_on == 1:
            HPlake_Data = pd.read_csv(locator.get_water_body_potential())
            Q_therm_Lake = np.array(HPlake_Data['QLake_kW']) * 1E3
            Q_therm_Lake_W = [
                x if x < master_to_slave_variables.HPLake_maxSize_W else
                master_to_slave_variables.HPLake_maxSize_W
                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)

        # Import Data - geothermal (shallow)
        if master_to_slave_variables.GHP_on == 1:
            GHP_Data = pd.read_csv(locator.get_geothermal_potential())
            Q_therm_GHP = np.array(GHP_Data['QGHP_kW']) * 1E3
            Q_therm_GHP_W = [
                x if x < master_to_slave_variables.GHP_maxSize_W else
                master_to_slave_variables.GHP_maxSize_W for x in Q_therm_GHP
            ]
            T_source_average_GHP_W = np.array(GHP_Data['Ts_C']) + 273
        else:
            Q_therm_GHP_W = np.zeros(HOURS_IN_YEAR)
            T_source_average_GHP_W = np.zeros(HOURS_IN_YEAR)

        # dispatch
        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_BackupBoiler_gen_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 = np.vectorize(heating_source_activator)(Q_thermal_req_W,
                                                                          master_to_slave_variables,
                                                                          Q_therm_GHP_W,
                                                                          T_source_average_GHP_W,
                                                                          T_source_average_Lake_K,
                                                                          Q_therm_Lake_W,
                                                                          Q_therm_Sew_W,
                                                                          T_source_average_sewage_K,
                                                                          T_district_heating_supply_K,
                                                                          T_district_heating_return_K
                                                                          )

        # COgen size for electricity production
        master_to_slave_variables.CCGT_SIZE_electrical_W = max(E_CHP_gen_W)
        master_to_slave_variables.WBFurnace_electrical_W = max(
            E_Furnace_wet_gen_W)
        master_to_slave_variables.DBFurnace_electrical_W = max(
            E_Furnace_dry_gen_W)

        # BACK-UP BOILER
        master_to_slave_variables.BackupBoiler_size_W = np.amax(
            Q_BackupBoiler_gen_W)
        if master_to_slave_variables.BackupBoiler_size_W != 0:
            master_to_slave_variables.BackupBoiler_on = 1
            NG_BackupBoiler_req_W, E_BackupBoiler_req_W = np.vectorize(
                cond_boiler_op_cost)(
                    Q_BackupBoiler_gen_W,
                    master_to_slave_variables.BackupBoiler_size_W,
                    T_district_heating_return_K)
        else:
            E_BackupBoiler_req_W = np.zeros(HOURS_IN_YEAR)
            NG_BackupBoiler_req_W = np.zeros(HOURS_IN_YEAR)

        # CAPEX (ANNUAL, TOTAL) AND OPEX (FIXED, VAR) GENERATION UNITS
        mdotnMax_kgpers = np.amax(mdot_DH_kgpers)
        performance_costs_generation, \
        district_heating_capacity_installed = cost_model.calc_generation_costs_capacity_installed_heating(locator,
                                                                                                          master_to_slave_variables,
                                                                                                          config,
                                                                                                          storage_dispatch,
                                                                                                          mdotnMax_kgpers
                                                                                                          )

        # CAPEX (ANNUAL, TOTAL) AND OPEX (FIXED, VAR) SEASONAL STORAGE
        performance_costs_storage = cost_model.calc_seasonal_storage_costs(
            config, locator, storage_dispatch)

        # CAPEX (ANNUAL, TOTAL) AND OPEX (FIXED, VAR) NETWORK
        performance_costs_network, \
        E_used_district_heating_network_W = cost_model.calc_network_costs_heating(locator,
                                                                                  master_to_slave_variables,
                                                                                  network_features,
                                                                                  "DH"
                                                                                  )

        # MERGE COSTS AND EMISSIONS IN ONE FILE
        performance_costs_gen = dict(performance_costs_generation,
                                     **performance_costs_network)
        district_heating_costs = dict(performance_costs_gen,
                                      **performance_costs_storage)

    else:
        Q_DH_networkload_W = np.zeros(HOURS_IN_YEAR)
        Q_SC_ET_to_storage_W = np.zeros(HOURS_IN_YEAR)
        Q_PVT_to_storage_W = np.zeros(HOURS_IN_YEAR)
        Q_SC_FP_to_storage_W = np.zeros(HOURS_IN_YEAR)
        Q_HP_Server_to_storage_W = np.zeros(HOURS_IN_YEAR)
        Q_Storage_gen_W = np.zeros(HOURS_IN_YEAR)
        Q_PVT_to_directload_W = np.zeros(HOURS_IN_YEAR)
        Q_SC_ET_to_directload_W = np.zeros(HOURS_IN_YEAR)
        Q_SC_FP_to_directload_W = np.zeros(HOURS_IN_YEAR)
        Q_HP_Server_to_directload_W = np.zeros(HOURS_IN_YEAR)
        Q_HPSew_gen_W = np.zeros(HOURS_IN_YEAR)
        Q_HPLake_gen_W = np.zeros(HOURS_IN_YEAR)
        Q_GHP_gen_W = np.zeros(HOURS_IN_YEAR)
        Q_CHP_gen_W = np.zeros(HOURS_IN_YEAR)
        Q_Furnace_dry_gen_W = np.zeros(HOURS_IN_YEAR)
        Q_Furnace_wet_gen_W = np.zeros(HOURS_IN_YEAR)
        Q_BaseBoiler_gen_W = np.zeros(HOURS_IN_YEAR)
        Q_PeakBoiler_gen_W = np.zeros(HOURS_IN_YEAR)
        Q_BackupBoiler_gen_W = np.zeros(HOURS_IN_YEAR)
        E_CHP_gen_W = np.zeros(HOURS_IN_YEAR)
        E_PVT_gen_W = np.zeros(HOURS_IN_YEAR)
        E_Furnace_dry_gen_W = np.zeros(HOURS_IN_YEAR)
        E_Furnace_wet_gen_W = np.zeros(HOURS_IN_YEAR)
        E_Storage_req_charging_W = np.zeros(HOURS_IN_YEAR)
        E_Storage_req_discharging_W = np.zeros(HOURS_IN_YEAR)
        E_used_district_heating_network_W = np.zeros(HOURS_IN_YEAR)
        E_HP_SC_FP_req_W = np.zeros(HOURS_IN_YEAR)
        E_HP_SC_ET_req_W = np.zeros(HOURS_IN_YEAR)
        E_HP_PVT_req_W = np.zeros(HOURS_IN_YEAR)
        E_HP_Server_req_W = np.zeros(HOURS_IN_YEAR)
        E_HPSew_req_W = np.zeros(HOURS_IN_YEAR)
        E_HPLake_req_W = np.zeros(HOURS_IN_YEAR)
        E_GHP_req_W = np.zeros(HOURS_IN_YEAR)
        E_BaseBoiler_req_W = np.zeros(HOURS_IN_YEAR)
        E_PeakBoiler_req_W = np.zeros(HOURS_IN_YEAR)
        E_BackupBoiler_req_W = np.zeros(HOURS_IN_YEAR)
        NG_CHP_req_W = np.zeros(HOURS_IN_YEAR)
        NG_BaseBoiler_req_W = np.zeros(HOURS_IN_YEAR)
        NG_PeakBoiler_req_W = np.zeros(HOURS_IN_YEAR)
        NG_BackupBoiler_req_W = np.zeros(HOURS_IN_YEAR)
        WetBiomass_Furnace_req_W = np.zeros(HOURS_IN_YEAR)
        DryBiomass_Furnace_req_W = np.zeros(HOURS_IN_YEAR)
        district_heating_costs = {}
        district_heating_capacity_installed = {}

    # save data
    district_heating_generation_dispatch = {

        # demand of the network:
        "Q_districtheating_sys_req_W": Q_DH_networkload_W,

        # ENERGY GENERATION
        # heating
        "Q_PVT_gen_storage_W": Q_PVT_to_storage_W,
        "Q_SC_ET_gen_storage_W": Q_SC_ET_to_storage_W,
        "Q_SC_FP_gen_storage_W": Q_SC_FP_to_storage_W,
        "Q_HP_Server_storage_W": Q_HP_Server_to_storage_W,

        # this is what is generated out of all the technologies sent to the storage
        "Q_Storage_gen_directload_W": Q_Storage_gen_W,
        # heating
        "Q_PVT_gen_directload_W": Q_PVT_to_directload_W,
        "Q_SC_ET_gen_directload_W": Q_SC_ET_to_directload_W,
        "Q_SC_FP_gen_directload_W": Q_SC_FP_to_directload_W,
        "Q_HP_Server_gen_directload_W": Q_HP_Server_to_directload_W,
        "Q_HP_Sew_gen_directload_W": Q_HPSew_gen_W,
        "Q_HP_Lake_gen_directload_W": Q_HPLake_gen_W,
        "Q_GHP_gen_directload_W": Q_GHP_gen_W,
        "Q_CHP_gen_directload_W": Q_CHP_gen_W,
        "Q_Furnace_dry_gen_directload_W": Q_Furnace_dry_gen_W,
        "Q_Furnace_wet_gen_directload_W": Q_Furnace_wet_gen_W,
        "Q_BaseBoiler_gen_directload_W": Q_BaseBoiler_gen_W,
        "Q_PeakBoiler_gen_directload_W": Q_PeakBoiler_gen_W,
        "Q_BackupBoiler_gen_directload_W": Q_BackupBoiler_gen_W,

        # electricity
        "E_CHP_gen_W": E_CHP_gen_W,
        "E_PVT_gen_W": E_PVT_gen_W,
        "E_Furnace_dry_gen_W": E_Furnace_dry_gen_W,
        "E_Furnace_wet_gen_W": E_Furnace_wet_gen_W,
    }

    district_heating_electricity_requirements_dispatch = {
        # ENERGY REQUIREMENTS
        # Electricity
        "E_Storage_charging_req_W": E_Storage_req_charging_W,
        "E_Storage_discharging_req_W": E_Storage_req_discharging_W,
        "E_DHN_req_W": E_used_district_heating_network_W,
        "E_HP_SC_FP_req_W": E_HP_SC_FP_req_W,
        "E_HP_SC_ET_req_W": E_HP_SC_ET_req_W,
        "E_HP_PVT_req_W": E_HP_PVT_req_W,
        "E_HP_Server_req_W": E_HP_Server_req_W,
        "E_HP_Sew_req_W": E_HPSew_req_W,
        "E_HP_Lake_req_W": E_HPLake_req_W,
        "E_GHP_req_W": E_GHP_req_W,
        "E_BaseBoiler_req_W": E_BaseBoiler_req_W,
        "E_PeakBoiler_req_W": E_PeakBoiler_req_W,
        "E_BackupBoiler_req_W": E_BackupBoiler_req_W,
    }
    district_heating_fuel_requirements_dispatch = {
        # FUEL REQUIREMENTS
        "NG_CHP_req_W": NG_CHP_req_W,
        "NG_BaseBoiler_req_W": NG_BaseBoiler_req_W,
        "NG_PeakBoiler_req_W": NG_PeakBoiler_req_W,
        "NG_BackupBoiler_req_W": NG_BackupBoiler_req_W,
        "WB_Furnace_req_W": WetBiomass_Furnace_req_W,
        "DB_Furnace_req_W": DryBiomass_Furnace_req_W,
    }

    return district_heating_costs, \
           district_heating_generation_dispatch, \
           district_heating_electricity_requirements_dispatch, \
           district_heating_fuel_requirements_dispatch, \
           district_heating_capacity_installed
Ejemplo n.º 4
0
def supply_calculation(individual, building_names, total_demand, locator,
                       extra_costs, extra_CO2, extra_primary_energy,
                       solar_features, network_features, gv, config, prices,
                       lca):
    """
    This function evaluates one supply system configuration of the case study.
    :param individual: a list that indicates the supply system configuration
    :type individual: list
    :param building_names: names of all building in the district
    :type building_names: ndarray
    :param locator:
    :param extra_costs: cost of decentralized supply systems
    :param extra_CO2: CO2 emission of decentralized supply systems
    :param extra_primary_energy: Primary energy of decentralized supply systems
    :param solar_features: Energy production potentials of solar technologies, including area of installed panels and annual production
    :type solar_features: dict
    :param network_features: hourly network operating conditions (thermal/pressure losses) and capital costs
    :type network_features: dict
    :param gv:
    :param config:
    :param prices:
    :return:
    """
    individual = evaluation.check_invalid(individual, len(building_names),
                                          config)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    natural_gas_main.natural_gas_imports(master_to_slave_vars, locator, config)

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

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

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

    # add electricity costs corresponding to

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

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

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

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

    return costs_USD, GHG_tonCO2, PEN_MJoil, master_to_slave_vars, individual
Ejemplo n.º 5
0
def district_heating_network(locator, master_to_slave_variables, config,
                             prices, lca, network_features):
    """
    Computes the parameters for the heating of the complete DHN

    :param locator: locator class
    :param master_to_slave_variables: class MastertoSlaveVars containing the value of variables to be passed to the
        slave optimization for each individual
    :param solar_features: solar features class
    :type locator: class
    :type master_to_slave_variables: class
    :type solar_features: class
    :return:
        - E_oil_eq_MJ: MJ oil Equivalent used during operation
        - CO2_kg_eq: kg of CO2-Equivalent emitted during operation
        - cost_sum: total cost in CHF used for operation
        - Q_source_data[:,7]: uncovered demand

    :rtype: float, float, float, array

    """
    # THERMAL STORAGE + NETWORK
    print(
        "CALCULATING ECOLOGICAL COSTS OF SEASONAL STORAGE - DUE TO OPERATION (IF ANY)"
    )
    performance_storage, storage_dispatch = storage_main.storage_optimization(
        locator, master_to_slave_variables, lca, prices, config)
    # Import data from storage optimization
    Q_DH_networkload_W = np.array(storage_dispatch['Q_DH_networkload_W'])
    Q_thermal_req_W = np.array(storage_dispatch['Q_req_after_storage_W'])

    E_PVT_gen_W = storage_dispatch['E_PVT_gen_W']

    Q_PVT_to_directload_W = storage_dispatch["Q_PVT_gen_directload_W"]
    Q_PVT_to_storage_W = storage_dispatch["Q_PVT_gen_storage_W"]

    Q_SC_ET_to_directload_W = storage_dispatch["Q_SC_ET_gen_directload_W"]
    Q_SC_ET_to_storage_W = storage_dispatch["Q_SC_ET_gen_storage_W"]

    Q_SC_FP_to_directload_W = storage_dispatch["Q_SC_FP_gen_directload_W"]
    Q_SC_FP_to_storage_W = storage_dispatch["Q_SC_FP_gen_storage_W"]

    Q_HP_Server_to_directload_W = storage_dispatch[
        "Q_HP_Server_gen_directload_W"]
    Q_HP_Server_to_storage_W = storage_dispatch["Q_HP_Server_gen_storage_W"]

    E_Storage_req_charging_W = storage_dispatch["E_Storage_charging_req_W"]
    E_Storage_req_discharging_W = storage_dispatch[
        "E_Storage_discharging_req_W"]
    E_HP_SC_FP_req_W = storage_dispatch["E_HP_SC_FP_req_W"]
    E_HP_SC_ET_req_W = storage_dispatch["E_HP_SC_ET_req_W"]
    E_HP_PVT_req_W = storage_dispatch["E_HP_PVT_req_W"]
    E_HP_Server_req_W = storage_dispatch["E_HP_Server_req_W"]

    Q_SC_ET_gen_W = storage_dispatch["Q_SC_ET_gen_W"]
    Q_SC_FP_gen_W = storage_dispatch["Q_SC_FP_gen_W"]
    Q_PVT_gen_W = storage_dispatch["Q_PVT_gen_W"]
    Q_Server_gen_W = storage_dispatch["Q_HP_Server_gen_W"]

    Q_Storage_gen_W = storage_dispatch["Q_Storage_gen_W"]

    # HEATING PLANT
    # Import Temperatures from Network Summary:
    mdot_DH_kgpers, T_district_heating_return_K, T_district_heating_supply_K = calc_network_summary_DHN(
        locator, master_to_slave_variables)

    # FIXED ORDER ACTIVATION STARTS
    # Import Data - Sewage heat
    if master_to_slave_variables.HPSew_on == 1:
        HPSew_Data = pd.read_csv(locator.get_sewage_heat_potential())
        Q_therm_Sew = np.array(HPSew_Data['Qsw_kW']) * 1E3
        Q_therm_Sew_W = [
            x if x < master_to_slave_variables.HPSew_maxSize_W else
            master_to_slave_variables.HPSew_maxSize_W for x in Q_therm_Sew
        ]
        T_source_average_sewage_K = np.array(HPSew_Data['Ts_C']) + 273
    else:
        Q_therm_Sew_W = np.zeros(HOURS_IN_YEAR)
        T_source_average_sewage_K = np.zeros(HOURS_IN_YEAR)

    # Import Data - lake heat
    if master_to_slave_variables.HPLake_on == 1:
        HPlake_Data = pd.read_csv(locator.get_lake_potential())
        Q_therm_Lake = np.array(HPlake_Data['QLake_kW']) * 1E3
        Q_therm_Lake_W = [
            x if x < master_to_slave_variables.HPLake_maxSize_W else
            master_to_slave_variables.HPLake_maxSize_W 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)

    # Import Data - geothermal (shallow)
    if master_to_slave_variables.GHP_on == 1:
        GHP_Data = pd.read_csv(locator.get_geothermal_potential())
        Q_therm_GHP = np.array(GHP_Data['QGHP_kW']) * 1E3
        Q_therm_GHP_W = [
            x if x < master_to_slave_variables.GHP_maxSize_W else
            master_to_slave_variables.GHP_maxSize_W for x in Q_therm_GHP
        ]
        T_source_average_GHP_W = np.array(GHP_Data['Ts_C']) + 273
    else:
        Q_therm_GHP_W = np.zeros(HOURS_IN_YEAR)
        T_source_average_GHP_W = np.zeros(HOURS_IN_YEAR)

    # Initiation of the variables

    source_HP_Sewage = np.zeros(HOURS_IN_YEAR)
    source_HP_Lake = np.zeros(HOURS_IN_YEAR)
    source_GHP = np.zeros(HOURS_IN_YEAR)
    source_CHP = np.zeros(HOURS_IN_YEAR)
    source_Furnace_dry = np.zeros(HOURS_IN_YEAR)
    source_Furnace_wet = np.zeros(HOURS_IN_YEAR)
    source_BaseBoiler = np.zeros(HOURS_IN_YEAR)
    source_PeakBoiler = np.zeros(HOURS_IN_YEAR)

    Q_HPSew_gen_W = np.zeros(HOURS_IN_YEAR)
    Q_HPLake_gen_W = np.zeros(HOURS_IN_YEAR)
    Q_GHP_gen_W = np.zeros(HOURS_IN_YEAR)
    Q_CHP_gen_W = np.zeros(HOURS_IN_YEAR)
    Q_Furnace_dry_gen_W = np.zeros(HOURS_IN_YEAR)
    Q_Furnace_wet_gen_W = np.zeros(HOURS_IN_YEAR)
    Q_BaseBoiler_gen_W = np.zeros(HOURS_IN_YEAR)
    Q_PeakBoiler_gen_W = np.zeros(HOURS_IN_YEAR)
    Q_AddBoiler_gen_W = np.zeros(HOURS_IN_YEAR)

    E_HPSew_req_W = np.zeros(HOURS_IN_YEAR)
    E_HPLake_req_W = np.zeros(HOURS_IN_YEAR)
    E_GHP_req_W = np.zeros(HOURS_IN_YEAR)
    E_CHP_gen_W = np.zeros(HOURS_IN_YEAR)
    E_Furnace_dry_gen_W = np.zeros(HOURS_IN_YEAR)
    E_Furnace_wet_gen_W = np.zeros(HOURS_IN_YEAR)
    E_BaseBoiler_req_W = np.zeros(HOURS_IN_YEAR)
    E_PeakBoiler_req_W = np.zeros(HOURS_IN_YEAR)
    E_BackupBoiler_req_W = np.zeros(HOURS_IN_YEAR)

    NG_CHP_req_W = np.zeros(HOURS_IN_YEAR)
    NG_BaseBoiler_req_W = np.zeros(HOURS_IN_YEAR)
    NG_PeakBoiler_req_W = np.zeros(HOURS_IN_YEAR)
    NG_BackupBoiler_req_W = np.zeros(HOURS_IN_YEAR)

    WetBiomass_Furnace_req_W = np.zeros(HOURS_IN_YEAR)
    DryBiomass_Furnace_req_W = np.zeros(HOURS_IN_YEAR)

    for hour in range(HOURS_IN_YEAR):
        if Q_thermal_req_W[hour] > 0.0:
            activation_output, \
            thermal_output, \
            electricity_output, \
            gas_output, \
            biomass_output = heating_source_activator(Q_thermal_req_W[hour],
                                                      hour,
                                                      master_to_slave_variables,
                                                      Q_therm_GHP_W[hour],
                                                      T_source_average_GHP_W[hour],
                                                      T_source_average_Lake_K[hour],
                                                      Q_therm_Lake_W[hour],
                                                      Q_therm_Sew_W[hour],
                                                      T_source_average_sewage_K[hour],
                                                      T_district_heating_supply_K[hour],
                                                      T_district_heating_return_K[hour],
                                                      prices,
                                                      lca)

            source_HP_Sewage[hour] = activation_output['Source_HP_Sewage']
            source_HP_Lake[hour] = activation_output['Source_HP_Lake']
            source_GHP[hour] = activation_output['Source_GHP']
            source_CHP[hour] = activation_output['Source_CHP']
            source_Furnace_dry[hour] = activation_output['Source_Furnace_dry']
            source_Furnace_wet[hour] = activation_output['Source_Furnace_wet']
            source_BaseBoiler[hour] = activation_output['Source_BaseBoiler']
            source_PeakBoiler[hour] = activation_output['Source_PeakBoiler']

            Q_HPSew_gen_W[hour] = thermal_output['Q_HPSew_gen_W']
            Q_HPLake_gen_W[hour] = thermal_output['Q_HPLake_gen_W']
            Q_GHP_gen_W[hour] = thermal_output['Q_GHP_gen_W']
            Q_CHP_gen_W[hour] = thermal_output['Q_CHP_gen_W']
            Q_Furnace_dry_gen_W[hour] = thermal_output['Q_Furnace_dry_gen_W']
            Q_Furnace_wet_gen_W[hour] = thermal_output['Q_Furnace_wet_gen_W']
            Q_BaseBoiler_gen_W[hour] = thermal_output['Q_BaseBoiler_gen_W']
            Q_PeakBoiler_gen_W[hour] = thermal_output['Q_PeakBoiler_gen_W']
            Q_AddBoiler_gen_W[hour] = thermal_output['Q_AddBoiler_gen_W']

            E_HPSew_req_W[hour] = electricity_output['E_HPSew_req_W']
            E_HPLake_req_W[hour] = electricity_output['E_HPLake_req_W']
            E_GHP_req_W[hour] = electricity_output['E_GHP_req_W']
            E_CHP_gen_W[hour] = electricity_output['E_CHP_gen_W']
            E_BaseBoiler_req_W[hour] = electricity_output['E_BaseBoiler_req_W']
            E_PeakBoiler_req_W[hour] = electricity_output['E_PeakBoiler_req_W']

            E_Furnace_dry_gen_W[hour] = electricity_output[
                'E_Furnace_dry_gen_W']
            E_Furnace_wet_gen_W[hour] = electricity_output[
                'E_Furnace_wet_gen_W']

            NG_CHP_req_W[hour] = gas_output['Gas_CHP_req_W']
            NG_BaseBoiler_req_W[hour] = gas_output['Gas_BaseBoiler_req_W']
            NG_PeakBoiler_req_W[hour] = gas_output['Gas_PeakBoiler_req_W']
            WetBiomass_Furnace_req_W[hour] = biomass_output[
                'Biomass_Furnace_dry_req_W']
            DryBiomass_Furnace_req_W[hour] = biomass_output[
                'Biomass_Furnace_wet_req_W']

    # BACK-UP BOILER
    master_to_slave_variables.BackupBoiler_size_W = np.amax(Q_AddBoiler_gen_W)
    if master_to_slave_variables.BackupBoiler_size_W != 0:
        master_to_slave_variables.BackupBoiler_on = 1
        for hour in range(HOURS_IN_YEAR):
            tdhret_req_K = T_district_heating_return_K[hour]
            _, \
            _, \
            NG_BackupBoiler_req_W[hour], \
            E_BackupBoiler_req_W[hour] = cond_boiler_op_cost(Q_AddBoiler_gen_W[hour],
                                                             master_to_slave_variables.BackupBoiler_size_W,
                                                             tdhret_req_K,
                                                             "NG",
                                                             prices, lca, hour)

    # CAPEX (ANNUAL, TOTAL) AND OPEX (FIXED, VAR) GENERATION UNITS
    performance_costs_generation = cost_model.calc_generation_costs_heating(
        locator,
        master_to_slave_variables,
        config,
        storage_dispatch,
    )

    # CAPEX (ANNUAL, TOTAL) AND OPEX (FIXED, VAR) NETWORK
    performance_costs_network, \
    E_used_district_heating_network_W = cost_model.calc_network_costs_heating(locator,
                                                                              master_to_slave_variables,
                                                                              network_features,
                                                                              lca,
                                                                              "DH")

    # MERGE COSTS AND EMISSIONS IN ONE FILE
    district_heating_costs = dict(performance_costs_generation,
                                  **performance_costs_network)

    # save data
    district_heating_generation_dispatch = {

        # demand of the network:
        "Q_districtheating_sys_req_W": Q_DH_networkload_W,

        # Status of each technology 1 = on, 0 = off in every hour
        "HPSew_Status": source_HP_Sewage,
        "HPLake_Status": source_HP_Lake,
        "GHP_Status": source_GHP,
        "CHP_Status": source_CHP,
        "Furnace_dry_Status": source_Furnace_dry,
        "Furnace_wet_Status": source_Furnace_wet,
        "BoilerBase_Status": source_BaseBoiler,
        "BoilerPeak_Status": source_PeakBoiler,

        # ENERGY GENERATION
        # heating
        "Q_PVT_gen_storage_W": Q_PVT_to_storage_W,
        "Q_SC_ET_gen_storage_W": Q_SC_ET_to_storage_W,
        "Q_SC_FP_gen_storage_W": Q_SC_FP_to_storage_W,
        "Q_HP_Server_storage_W": Q_HP_Server_to_storage_W,

        # this is what is generated out of all the technologies sent to the storage
        "Q_Storage_gen_directload_W": Q_Storage_gen_W,
        # heating
        "Q_PVT_gen_directload_W": Q_PVT_to_directload_W,
        "Q_SC_ET_gen_directload_W": Q_SC_ET_to_directload_W,
        "Q_SC_FP_gen_directload_W": Q_SC_FP_to_directload_W,
        "Q_HP_Server_gen_directload_W": Q_HP_Server_to_directload_W,
        "Q_HP_Sew_gen_directload_W": Q_HPSew_gen_W,
        "Q_HP_Lake_gen_directload_W": Q_HPLake_gen_W,
        "Q_GHP_gen_directload_W": Q_GHP_gen_W,
        "Q_CHP_gen_directload_W": Q_CHP_gen_W,
        "Q_Furnace_dry_gen_directload_W": Q_Furnace_dry_gen_W,
        "Q_Furnace_wet_gen_directload_W": Q_Furnace_wet_gen_W,
        "Q_BaseBoiler_gen_directload_W": Q_BaseBoiler_gen_W,
        "Q_PeakBoiler_gen_directload_W": Q_PeakBoiler_gen_W,
        "Q_BackupBoiler_gen_directload_W": Q_AddBoiler_gen_W,

        # electricity
        "E_CHP_gen_W": E_CHP_gen_W,
        "E_PVT_gen_W": E_PVT_gen_W,
        "E_Furnace_dry_gen_W": E_Furnace_dry_gen_W,
        "E_Furnace_wet_gen_W": E_Furnace_wet_gen_W,
    }

    district_heating_electricity_requirements_dispatch = {
        # ENERGY REQUIREMENTS
        # Electricity
        "E_Storage_charging_req_W": E_Storage_req_charging_W,
        "E_Storage_discharging_req_W": E_Storage_req_discharging_W,
        "E_DHN_req_W": E_used_district_heating_network_W,
        "E_HP_SC_FP_req_W": E_HP_SC_FP_req_W,
        "E_HP_SC_ET_req_W": E_HP_SC_ET_req_W,
        "E_HP_PVT_req_W": E_HP_PVT_req_W,
        "E_HP_Server_req_W": E_HP_Server_req_W,
        "E_HP_Sew_req_W": E_HPSew_req_W,
        "E_HP_Lake_req_W": E_HPLake_req_W,
        "E_GHP_req_W": E_GHP_req_W,
        "E_BaseBoiler_req_W": E_BaseBoiler_req_W,
        "E_PeakBoiler_req_W": E_PeakBoiler_req_W,
        "E_BackupBoiler_req_W": E_BackupBoiler_req_W,
    }
    district_heating_fuel_requirements_dispatch = {
        # FUEL REQUIREMENTS
        "NG_CHP_req_W": NG_CHP_req_W,
        "NG_BaseBoiler_req_W": NG_BaseBoiler_req_W,
        "NG_PeakBoiler_req_W": NG_PeakBoiler_req_W,
        "NG_BackupBoiler_req_W": NG_BackupBoiler_req_W,
        "WB_Furnace_req_W": WetBiomass_Furnace_req_W,
        "DB_Furnace_req_W": DryBiomass_Furnace_req_W,
    }

    return district_heating_costs, \
           district_heating_generation_dispatch, \
           district_heating_electricity_requirements_dispatch,\
           district_heating_fuel_requirements_dispatch