def preproccessing(locator, total_demand, building_names, weather_file, gv):

    # read weather and calculate ground temperature
    T_ambient = epwreader.epw_reader(weather_file)['drybulb_C']
    gv.ground_temperature = geothermal.calc_ground_temperature(T_ambient.values, gv)

    print "Run substation model for each building separately"
    subsM.subsMain(locator, total_demand, building_names, gv, Flag = True) # 1 if disconected buildings are calculated

    print "Heating operation pattern for disconnected buildings"
    dbM.discBuildOp(locator, building_names, gv)

    print "Create network file with all buildings connected"
    nM.Network_Summary(locator, total_demand, building_names, gv, "all") #"_all" key for all buildings

    print "Solar features extraction"
    solarFeat = sFn.solarRead(locator, gv)

    print "electricity"
    elecCosts, elecCO2, elecPrim = electricity.calc_pareto_electricity(locator, gv)

    print "Process Heat "
    hpCosts, hpCO2, hpPrim = hpMain.calc_pareto_Qhp(locator, total_demand, gv)

    extraCosts = elecCosts + hpCosts
    extraCO2 = elecCO2 + hpCO2
    extraPrim = elecPrim + hpPrim

    return extraCosts, extraCO2, extraPrim, solarFeat
Example #2
0
def run_as_script(scenario_path=None):
    """
    run the whole network summary routine
    """
    import cea.globalvar
    import cea.inputlocator as inputlocator
    from geopandas import GeoDataFrame as gpdf
    from cea.utilities import epwreader
    from cea.resources import geothermal

    gv = cea.globalvar.GlobalVariables()

    if scenario_path is None:
        scenario_path = gv.scenario_reference

    locator = inputlocator.InputLocator(scenario_path=scenario_path)
    total_demand = pd.read_csv(locator.get_total_demand())
    building_names = pd.read_csv(locator.get_total_demand())['Name']
    weather_file = locator.get_default_weather()
    # add geothermal part of preprocessing
    T_ambient = epwreader.epw_reader(weather_file)['drybulb_C']
    gv.ground_temperature = geothermal.calc_ground_temperature(T_ambient.values, gv)
    #substation_main(locator, total_demand, total_demand['Name'], gv, False)

    t = 1000  # FIXME
    T_DH = 60  # FIXME
    network = 'DH'  # FIXME
    t_flag = True  # FIXME

    substations_HEX_specs, buildings = substation_HEX_design_main(locator, total_demand, building_names, gv)

    substation_return_model_main(locator, gv, building_names, buildings, substations_HEX_specs, T_DH, t, network, t_flag)

    print 'substation_main() succeeded'
Example #3
0
def preproccessing(locator, total_demand, building_names, weather_file, gv):

    # read weather and calculate ground temperature
    T_ambient = epwreader.epw_reader(weather_file)['drybulb_C']
    gv.ground_temperature = geothermal.calc_ground_temperature(
        T_ambient.values, gv)

    print "Run substation model for each building separately"
    subsM.subsMain(locator, total_demand, building_names, gv,
                   Flag=True)  # 1 if disconected buildings are calculated

    print "Heating operation pattern for disconnected buildings"
    dbM.discBuildOp(locator, building_names, gv)

    print "Create network file with all buildings connected"
    nM.Network_Summary(locator, total_demand, building_names, gv,
                       "all")  #"_all" key for all buildings

    print "Solar features extraction"
    solarFeat = sFn.solarRead(locator, gv)

    print "electricity"
    elecCosts, elecCO2, elecPrim = electricity.calc_pareto_electricity(
        locator, gv)

    print "Process Heat "
    hpCosts, hpCO2, hpPrim = hpMain.calc_pareto_Qhp(locator, total_demand, gv)

    extraCosts = elecCosts + hpCosts
    extraCO2 = elecCO2 + hpCO2
    extraPrim = elecPrim + hpPrim

    return extraCosts, extraCO2, extraPrim, solarFeat
def preproccessing(locator, total_demand, buildings_heating_demand, buildings_cooling_demand,
                   weather_file, district_heating_network, district_cooling_network):
    """
    This function aims at preprocessing all data for the optimization.

    :param locator: path to locator function
    :param total_demand: dataframe with total demand and names of all building in the area
    :param building_names: dataframe with names of all buildings in the area
    :param weather_file: path to wather file
    :type locator: class
    :type total_demand: list
    :type building_names: list
    :type weather_file: string
    :return:
        - extraCosts: extra pareto optimal costs due to electricity and process heat (
            these are treated separately and not considered inside the optimization)
        - extraCO2: extra pareto optimal emissions due to electricity and process heat (
            these are treated separately and not considered inside the optimization)
        - extraPrim: extra pareto optimal primary energy due to electricity and process heat (
            these are treated separately and not considered inside the optimization)
        - solar_features: extraction of solar features form the results of the solar technologies
            calculation.

    :rtype: float, float, float, float

    """

    # local variables
    network_depth_m = Z0

    print("PRE-PROCESSING 1/2: weather properties")
    T_ambient = epwreader.epw_reader(weather_file)['drybulb_C']
    ground_temp = calc_ground_temperature(locator, T_ambient, depth_m=network_depth_m)

    print("PRE-PROCESSING 2/2: thermal networks")  # at first estimate a distribution with all the buildings connected
    if district_heating_network:
        num_tot_buildings = len(buildings_heating_demand)
        DHN_barcode = ''.join(str(1) for e in range(num_tot_buildings))
        substation.substation_main_heating(locator, total_demand, buildings_heating_demand,
                                           DHN_barcode=DHN_barcode)

        summarize_network.network_main(locator, buildings_heating_demand, ground_temp, num_tot_buildings, "DH",
                                       DHN_barcode)
        # "_all" key for all buildings
    if district_cooling_network:
        num_tot_buildings = len(buildings_cooling_demand)
        DCN_barcode = ''.join(str(1) for e in range(num_tot_buildings))
        substation.substation_main_cooling(locator, total_demand, buildings_cooling_demand, DCN_barcode=DCN_barcode)

        summarize_network.network_main(locator, buildings_cooling_demand,
                                       ground_temp, num_tot_buildings, "DC",
                                       DCN_barcode)  # "_all" key for all buildings

    network_features = NetworkOptimizationFeatures(district_heating_network, district_cooling_network, locator)

    return network_features
def disconnected_buildings_heating_main(locator, total_demand, building_names,
                                        config, prices, lca):
    """
    Computes the parameters for the operation of disconnected buildings
    output results in csv files.
    There is no optimization at this point. The different technologies are calculated and compared 1 to 1 to
    each technology. it is a classical combinatorial problem.
    :param locator: locator class
    :param building_names: list with names of buildings
    :type locator: class
    :type building_names: list
    :return: results of operation of buildings located in locator.get_optimization_decentralized_folder
    :rtype: Nonetype
    """
    t0 = time.perf_counter()
    prop_geometry = Gdf.from_file(locator.get_zone_geometry())
    geometry = pd.DataFrame({
        'Name': prop_geometry.Name,
        'Area': prop_geometry.area
    })
    geothermal_potential_data = dbf.dbf_to_dataframe(
        locator.get_building_supply())
    geothermal_potential_data = pd.merge(geothermal_potential_data,
                                         geometry,
                                         on='Name')
    geothermal_potential_data['Area_geo'] = geothermal_potential_data['Area']
    weather_path = locator.get_weather_file()
    weather_data = epwreader.epw_reader(weather_path)[[
        'year', 'drybulb_C', 'wetbulb_C', 'relhum_percent', 'windspd_ms',
        'skytemp_C'
    ]]

    T_ground_K = calc_ground_temperature(locator,
                                         weather_data['drybulb_C'],
                                         depth_m=10)
    supply_systems = SupplySystemsDatabase(locator)

    # This will calculate the substation state if all buildings where connected(this is how we study this)
    substation.substation_main_heating(locator, total_demand, building_names)

    n = len(building_names)
    cea.utilities.parallel.vectorize(disconnected_heating_for_building,
                                     config.get_number_of_processes())(
                                         building_names,
                                         repeat(supply_systems, n),
                                         repeat(T_ground_K, n),
                                         repeat(geothermal_potential_data, n),
                                         repeat(lca, n), repeat(locator, n),
                                         repeat(prices, n))

    print(time.perf_counter() - t0,
          "seconds process time for the Disconnected Building Routine \n")
Example #6
0
def calculate_ground_temperature(locator):
    """
    calculate ground temperatures.

    :param locator:
    :return: list of ground temperatures, one for each hour of the year
    :rtype: list[np.float64]
    """
    weather_file = locator.get_weather_file()
    T_ambient_C = epw_reader(weather_file)['drybulb_C']
    network_depth_m = NETWORK_DEPTH  # [m]
    T_ground_K = geothermal.calc_ground_temperature(locator, T_ambient_C.values, network_depth_m)
    return T_ground_K
def disconnected_buildings_heating_main(locator, total_demand, building_names, config, prices, lca):
    """
    Computes the parameters for the operation of disconnected buildings
    output results in csv files.
    There is no optimization at this point. The different technologies are calculated and compared 1 to 1 to
    each technology. it is a classical combinatorial problem.
    :param locator: locator class
    :param building_names: list with names of buildings
    :type locator: class
    :type building_names: list
    :return: results of operation of buildings located in locator.get_optimization_decentralized_folder
    :rtype: Nonetype
    """
    t0 = time.clock()
    prop_geometry = Gdf.from_file(locator.get_zone_geometry())
    geometry = pd.DataFrame({'Name': prop_geometry.Name, 'Area': prop_geometry.area})
    geothermal_potential_data = dbf.dbf_to_dataframe(locator.get_building_supply())
    geothermal_potential_data = pd.merge(geothermal_potential_data, geometry, on='Name')
    geothermal_potential_data['Area_geo'] = geothermal_potential_data['Area']
    weather_path = locator.get_weather_file()
    weather_data = epwreader.epw_reader(weather_path)[['year', 'drybulb_C', 'wetbulb_C',
                                                         'relhum_percent', 'windspd_ms', 'skytemp_C']]

    T_ground_K = calc_ground_temperature(locator, weather_data['drybulb_C'], depth_m=10)


    # This will calculate the substation state if all buildings where connected(this is how we study this)
    substation.substation_main_heating(locator, total_demand, building_names)

    for building_name in building_names:
        print('running for building %s') %(building_name)
        # run substation model to derive temperatures of the building
        substation_results = pd.read_csv(locator.get_optimization_substations_results_file(building_name, "DH", ""))
        q_load_Wh = np.vectorize(calc_new_load)(substation_results["mdot_DH_result_kgpers"],
                                                substation_results["T_supply_DH_result_K"],
                                                substation_results["T_return_DH_result_K"])
        Qnom_W = q_load_Wh.max()

        # Create empty matrices
        Opex_a_var_USD = np.zeros((13, 7))
        Capex_total_USD = np.zeros((13, 7))
        Capex_a_USD = np.zeros((13, 7))
        Opex_a_fixed_USD = np.zeros((13, 7))
        Capex_opex_a_fixed_only_USD = np.zeros((13, 7))
        Opex_a_USD = np.zeros((13, 7))
        GHG_tonCO2 = np.zeros((13, 7))
        PEN_MJoil = np.zeros((13, 7))
        # indicate supply technologies for each configuration
        Opex_a_var_USD[0][0] = 1  # Boiler NG
        Opex_a_var_USD[1][1] = 1  # Boiler BG
        Opex_a_var_USD[2][2] = 1  # Fuel Cell

        resourcesRes = np.zeros((13, 4))
        Q_Boiler_for_GHP_W = np.zeros((10, 1))  # Save peak capacity of GHP Backup Boilers
        GHP_el_size_W = np.zeros((10, 1))  # Save peak capacity of GHP

        # save supply system activation of all supply configurations
        heating_dispatch = {}

        # Supply with the Boiler / FC / GHP
        Tret_K = substation_results["T_return_DH_result_K"].values
        Tsup_K = substation_results["T_supply_DH_result_K"].values
        mdot_kgpers = substation_results["mdot_DH_result_kgpers"].values

        ## Start Hourly calculation
        print building_name, ' decentralized heating supply systems simulations...'
        Tret_K = np.where(Tret_K > 0.0, Tret_K, Tsup_K)

        ## 0: Boiler NG
        BoilerEff = np.vectorize(Boiler.calc_Cop_boiler)(q_load_Wh, Qnom_W, Tret_K)
        Qgas_to_Boiler_Wh = np.divide(q_load_Wh, BoilerEff, out=np.zeros_like(q_load_Wh), where=BoilerEff != 0.0)
        Boiler_Status = np.where(Qgas_to_Boiler_Wh > 0.0, 1, 0)
        # add costs
        Opex_a_var_USD[0][4] += sum(prices.NG_PRICE * Qgas_to_Boiler_Wh)  # CHF
        GHG_tonCO2[0][5] += calc_emissions_Whyr_to_tonCO2yr(sum(Qgas_to_Boiler_Wh), lca.NG_TO_CO2_EQ)  # ton CO2
        PEN_MJoil[0][6] += calc_pen_Whyr_to_MJoilyr(sum(Qgas_to_Boiler_Wh), lca.NG_TO_OIL_EQ)  # MJ-oil-eq
        # add activation
        resourcesRes[0][0] += sum(q_load_Wh)  # q from NG
        heating_dispatch[0] = {'Q_Boiler_gen_directload_W': q_load_Wh,
                                         'Boiler_Status': Boiler_Status,
                                         'NG_Boiler_req_W': Qgas_to_Boiler_Wh,
                                         'E_hs_ww_req_W': np.zeros(8760)}
        ## 1: Boiler BG
        # add costs
        Opex_a_var_USD[1][4] += sum(prices.BG_PRICE * Qgas_to_Boiler_Wh)  # CHF
        GHG_tonCO2[1][5] += calc_emissions_Whyr_to_tonCO2yr(sum(Qgas_to_Boiler_Wh), lca.NG_TO_CO2_EQ)  # ton CO2
        PEN_MJoil[1][6] += calc_pen_Whyr_to_MJoilyr(sum(Qgas_to_Boiler_Wh), lca.NG_TO_OIL_EQ)  # MJ-oil-eq
        # add activation
        resourcesRes[1][1] += sum(q_load_Wh)  # q from BG
        heating_dispatch[1] = {'Q_Boiler_gen_directload_W': q_load_Wh,
                               'Boiler_Status': Boiler_Status,
                               'BG_Boiler_req_W': Qgas_to_Boiler_Wh,
                               'E_hs_ww_req_W': np.zeros(8760)}

        ## 2: Fuel Cell
        (FC_Effel, FC_Effth) = np.vectorize(FC.calc_eta_FC)(q_load_Wh, Qnom_W, 1, "B")
        Qgas_to_FC_Wh = q_load_Wh / (FC_Effth + FC_Effel)  # FIXME: should be q_load_Wh/FC_Effth?
        el_from_FC_Wh = Qgas_to_FC_Wh * FC_Effel
        FC_Status = np.where(Qgas_to_FC_Wh > 0.0, 1, 0)
        # add variable costs, emissions and primary energy
        Opex_a_var_USD[2][4] += sum(prices.NG_PRICE * Qgas_to_FC_Wh - prices.ELEC_PRICE_EXPORT * el_from_FC_Wh)  # CHF, extra electricity sold to grid
        GHG_tonCO2_from_FC = (0.0874 * Qgas_to_FC_Wh * 3600E-6 + 773 * 0.45 * el_from_FC_Wh * 1E-6 -
                              lca.EL_TO_CO2_EQ * el_from_FC_Wh * 3600E-6) / 1E3
        GHG_tonCO2[2][5] += sum(GHG_tonCO2_from_FC)  # tonCO2
        # Bloom box emissions within the FC: 773 lbs / MWh_el (and 1 lbs = 0.45 kg)
        # http://www.carbonlighthouse.com/2011/09/16/bloom-box/
        PEN_MJoil_from_FC = 1.51 * Qgas_to_FC_Wh * 3600E-6 - lca.EL_TO_OIL_EQ * el_from_FC_Wh * 3600E-6
        PEN_MJoil[2][6] += sum(PEN_MJoil_from_FC)  # MJ-oil-eq
        # add activation
        resourcesRes[2][0] = sum(q_load_Wh)  # q from NG
        resourcesRes[2][2] = sum(el_from_FC_Wh)  # el for GHP # FIXME: el from FC
        heating_dispatch[2] = {'Q_Fuelcell_gen_directload_W': q_load_Wh,
                               'Fuelcell_Status': FC_Status,
                               'NG_FuelCell_req_W': Qgas_to_FC_Wh,
                               'E_Fuelcell_gen_export_W': el_from_FC_Wh,
                               'E_hs_ww_req_W': np.zeros(8760)}

        # 3-13: Boiler NG + GHP
        for i in range(10):
            # set nominal size for Boiler and GHP
            QnomBoiler_W = i / 10.0 * Qnom_W
            mdot_kgpers_Boiler = i / 10.0 * mdot_kgpers
            QnomGHP_W = Qnom_W - QnomBoiler_W

            # GHP operation
            Texit_GHP_nom_K = QnomGHP_W / (mdot_kgpers * HEAT_CAPACITY_OF_WATER_JPERKGK) + Tret_K
            el_GHP_Wh, q_load_NG_Boiler_Wh, \
            qhot_missing_Wh, \
            Texit_GHP_K, q_from_GHP_Wh = np.vectorize(calc_GHP_operation)(QnomGHP_W, T_ground_K, Texit_GHP_nom_K,
                                                                      Tret_K, Tsup_K, mdot_kgpers, q_load_Wh)
            GHP_el_size_W[i][0] = max(el_GHP_Wh)
            GHP_Status = np.where(q_from_GHP_Wh > 0.0, 1, 0)

            # GHP Backup Boiler operation
            if max(qhot_missing_Wh) > 0.0:
                print "GHP unable to cover the whole demand, boiler activated!"
                Qnom_GHP_Backup_Boiler_W = max(qhot_missing_Wh)
                BoilerEff = np.vectorize(Boiler.calc_Cop_boiler)(qhot_missing_Wh, Qnom_GHP_Backup_Boiler_W, Texit_GHP_K)
                Qgas_to_GHPBoiler_Wh = np.divide(qhot_missing_Wh, BoilerEff,
                                                 out=np.zeros_like(qhot_missing_Wh), where=BoilerEff != 0.0)
            else:
                Qgas_to_GHPBoiler_Wh = np.zeros(q_load_Wh.shape[0])
                Qnom_GHP_Backup_Boiler_W = 0.0
            Q_Boiler_for_GHP_W[i][0] = Qnom_GHP_Backup_Boiler_W
            GHPbackupBoiler_Status = np.where(qhot_missing_Wh > 0.0, 1, 0)

            # NG Boiler operation
            BoilerEff = np.vectorize(Boiler.calc_Cop_boiler)(q_load_NG_Boiler_Wh, QnomBoiler_W, Texit_GHP_K)
            Qgas_to_Boiler_Wh = np.divide(q_load_NG_Boiler_Wh, BoilerEff,
                                          out=np.zeros_like(q_load_NG_Boiler_Wh), where=BoilerEff != 0.0)
            Boiler_Status = np.where(q_load_NG_Boiler_Wh > 0.0, 1, 0)

            # add costs
            # electricity
            el_total_Wh = el_GHP_Wh
            Opex_a_var_USD[3 + i][4] += sum(prices.ELEC_PRICE * el_total_Wh)  # CHF
            GHG_tonCO2[3 + i][5] += calc_emissions_Whyr_to_tonCO2yr(sum(el_total_Wh), lca.EL_TO_CO2_EQ)  # ton CO2
            PEN_MJoil[3 + i][6] += calc_pen_Whyr_to_MJoilyr(sum(el_total_Wh), lca.EL_TO_OIL_EQ)  # MJ-oil-eq
            # gas
            Q_gas_total_Wh = Qgas_to_GHPBoiler_Wh + Qgas_to_Boiler_Wh
            Opex_a_var_USD[3 + i][4] += sum(prices.NG_PRICE * Q_gas_total_Wh)  # CHF
            GHG_tonCO2[3 + i][5] += calc_emissions_Whyr_to_tonCO2yr(sum(Q_gas_total_Wh), lca.NG_TO_CO2_EQ)  # ton CO2
            PEN_MJoil[3 + i][6] += calc_pen_Whyr_to_MJoilyr(sum(Q_gas_total_Wh), lca.NG_TO_OIL_EQ)  # MJ-oil-eq
            # add activation
            resourcesRes[3 + i][0] = sum(qhot_missing_Wh + q_load_NG_Boiler_Wh)
            resourcesRes[3 + i][2] = sum(el_GHP_Wh)
            resourcesRes[3 + i][3] = sum(q_from_GHP_Wh)

            heating_dispatch[3 + i] = {'Q_GHP_gen_directload_W': q_from_GHP_Wh,
                                       'Q_BackupBoiler_gen_directload_W': qhot_missing_Wh,
                                       'Q_Boiler_gen_directload_W': q_load_NG_Boiler_Wh,
                                       'GHP_Status': GHP_Status,
                                       'BackupBoiler_Status': GHPbackupBoiler_Status,
                                       'Boiler_Status': Boiler_Status,
                                       'NG_BackupBoiler_req_Wh': Qgas_to_GHPBoiler_Wh,
                                       'NG_Boiler_req_Wh': Qgas_to_Boiler_Wh,
                                       'E_hs_ww_req_W': el_GHP_Wh}

        # Add all costs
        # 0: Boiler NG
        Capex_a_Boiler_USD, Opex_a_fixed_Boiler_USD, Capex_Boiler_USD = Boiler.calc_Cinv_boiler(Qnom_W, locator, config,
                                                                                                'BO1')
        Capex_total_USD[0][0] = Capex_Boiler_USD
        Capex_a_USD[0][0] = Capex_a_Boiler_USD
        Opex_a_fixed_USD[0][0] = Opex_a_fixed_Boiler_USD
        Capex_opex_a_fixed_only_USD[0][0] = Capex_a_Boiler_USD + Opex_a_fixed_Boiler_USD  # TODO:variable price?

        # 1: Boiler BG
        Capex_total_USD[1][0] = Capex_Boiler_USD
        Capex_a_USD[1][0] = Capex_a_Boiler_USD
        Opex_a_fixed_USD[1][0] = Opex_a_fixed_Boiler_USD
        Capex_opex_a_fixed_only_USD[1][0] = Capex_a_Boiler_USD + Opex_a_fixed_Boiler_USD  # TODO:variable price?

        # 2: Fuel Cell
        Capex_a_FC_USD, Opex_fixed_FC_USD, Capex_FC_USD = FC.calc_Cinv_FC(Qnom_W, locator, config)
        Capex_total_USD[2][0] = Capex_FC_USD
        Capex_a_USD[2][0] = Capex_a_FC_USD
        Opex_a_fixed_USD[2][0] = Opex_fixed_FC_USD
        Capex_opex_a_fixed_only_USD[2][0] = Capex_a_FC_USD + Opex_fixed_FC_USD  # TODO:variable price?

        # 3-13: BOILER + GHP
        for i in range(10):
            Opex_a_var_USD[3 + i][0] = i / 10.0  # Boiler share
            Opex_a_var_USD[3 + i][3] = 1 - i / 10.0  # GHP share

            # Get boiler costs
            QnomBoiler_W = i / 10.0 * Qnom_W
            Capex_a_Boiler_USD, Opex_a_fixed_Boiler_USD, Capex_Boiler_USD = Boiler.calc_Cinv_boiler(QnomBoiler_W,
                                                                                                    locator,
                                                                                                    config, 'BO1')

            Capex_total_USD[3 + i][0] += Capex_Boiler_USD
            Capex_a_USD[3 + i][0] += Capex_a_Boiler_USD
            Opex_a_fixed_USD[3 + i][0] += Opex_a_fixed_Boiler_USD
            Capex_opex_a_fixed_only_USD[3 + i][
                0] += Capex_a_Boiler_USD + Opex_a_fixed_Boiler_USD  # TODO:variable price?

            # Get back up boiler costs
            Qnom_Backup_Boiler_W = Q_Boiler_for_GHP_W[i][0]
            Capex_a_GHPBoiler_USD, Opex_a_fixed_GHPBoiler_USD, Capex_GHPBoiler_USD = Boiler.calc_Cinv_boiler(
                Qnom_Backup_Boiler_W, locator,
                config, 'BO1')

            Capex_total_USD[3 + i][0] += Capex_GHPBoiler_USD
            Capex_a_USD[3 + i][0] += Capex_a_GHPBoiler_USD
            Opex_a_fixed_USD[3 + i][0] += Opex_a_fixed_GHPBoiler_USD
            Capex_opex_a_fixed_only_USD[3 + i][
                0] += Capex_a_GHPBoiler_USD + Opex_a_fixed_GHPBoiler_USD  # TODO:variable price?

            # Get ground source heat pump costs
            Capex_a_GHP_USD, Opex_a_fixed_GHP_USD, Capex_GHP_USD = HP.calc_Cinv_GHP(GHP_el_size_W[i][0], locator,
                                                                                    config)
            Capex_total_USD[3 + i][0] += Capex_GHP_USD
            Capex_a_USD[3 + i][0] += Capex_a_GHP_USD
            Opex_a_fixed_USD[3 + i][0] += Opex_a_fixed_GHP_USD
            Capex_opex_a_fixed_only_USD[3 + i][0] += Capex_a_GHP_USD + Opex_a_fixed_GHP_USD  # TODO:variable price?

        # Best configuration
        Best = np.zeros((13, 1))
        indexBest = 0
        TAC_USD = np.zeros((13, 2))
        TotalCO2 = np.zeros((13, 2))
        TotalPrim = np.zeros((13, 2))
        for i in range(13):
            TAC_USD[i][0] = TotalCO2[i][0] = TotalPrim[i][0] = i
            Opex_a_USD[i][1] = Opex_a_fixed_USD[i][0] + + Opex_a_var_USD[i][4]
            TAC_USD[i][1] = Capex_opex_a_fixed_only_USD[i][0] + Opex_a_var_USD[i][4]
            TotalCO2[i][1] = GHG_tonCO2[i][5]
            TotalPrim[i][1] = PEN_MJoil[i][6]

        CostsS = TAC_USD[np.argsort(TAC_USD[:, 1])]
        CO2S = TotalCO2[np.argsort(TotalCO2[:, 1])]
        PrimS = TotalPrim[np.argsort(TotalPrim[:, 1])]

        el = len(CostsS)
        rank = 0
        Bestfound = False

        optsearch = np.empty(el)
        optsearch.fill(3)
        indexBest = 0
        geothermal_potential = geothermal_potential_data.set_index('Name')

        # Check the GHP area constraint
        for i in range(10):
            QGHP = (1 - i / 10.0) * Qnom_W
            areaAvail = geothermal_potential.ix[building_name, 'Area_geo']
            Qallowed = np.ceil(areaAvail / GHP_A) * GHP_HMAX_SIZE  # [W_th]
            if Qallowed < QGHP:
                optsearch[i + 3] += 1
                Best[i + 3][0] = - 1

        while not Bestfound and rank < el:

            optsearch[int(CostsS[rank][0])] -= 1
            optsearch[int(CO2S[rank][0])] -= 1
            optsearch[int(PrimS[rank][0])] -= 1

            if np.count_nonzero(optsearch) != el:
                Bestfound = True
                indexBest = np.where(optsearch == 0)[0][0]

            rank += 1

        # get the best option according to the ranking.
        Best[indexBest][0] = 1

        # Save results in csv file
        performance_results = {
            "Nominal heating load": Qnom_W,
            "Capacity_BaseBoiler_NG_W": Qnom_W * Opex_a_var_USD[:, 0],
            "Capacity_FC_NG_W": Qnom_W * Opex_a_var_USD[:, 2],
            "Capacity_GS_HP_W": Qnom_W * Opex_a_var_USD[:, 3],
            "TAC_USD": TAC_USD[:, 1],
            "Capex_a_USD": Capex_a_USD[:, 0],
            "Capex_total_USD": Capex_total_USD[:, 0],
            "Opex_fixed_USD": Opex_a_fixed_USD[:, 0],
            "Opex_var_USD": Opex_a_var_USD[:, 4],
            "GHG_tonCO2": GHG_tonCO2[:, 5],
            "PEN_MJoil": PEN_MJoil[:, 6],
            "Best configuration": Best[:, 0]}

        results_to_csv = pd.DataFrame(performance_results)

        fName_result = locator.get_optimization_decentralized_folder_building_result_heating(building_name)
        results_to_csv.to_csv(fName_result, sep=',')

        # save activation for the best supply system configuration
        best_activation_df = pd.DataFrame.from_dict(heating_dispatch[indexBest])  #
        best_activation_df.to_csv(
            locator.get_optimization_decentralized_folder_building_result_heating_activation(building_name))

    print time.clock() - t0, "seconds process time for the Disconnected Building Routine \n"
def network_main(locator, total_demand, building_names, config, gv, key):
    """
    This function summarizes the distribution demands and will give them as:
    - absolute values (design values = extreme values)
    - hourly operation scheme of input/output of distribution

    :param locator: locator class
    :param total_demand: dataframe with total demand of buildings
    :param building_names: vector with names of buildings
    :param gv: global variables class
    :param key: when called by the optimization, a key will provide an id for the individual
        and the generation.
    :type locator: class
    :type total_demand: list
    :type building_names: vector
    :type gv: class
    :type key: int
    :return: csv file stored in locator.get_optimization_network_results_folder() as fName_result
        where fName_result: FIXME: what?
    :rtype: Nonetype
    """

    t0 = time.clock()
    weather_data = epwreader.epw_reader(config.weather)[[
        'year', 'drybulb_C', 'wetbulb_C', 'relhum_percent', 'windspd_ms',
        'skytemp_C'
    ]]
    ground_temp = calc_ground_temperature(locator,
                                          weather_data['drybulb_C'],
                                          depth_m=10)
    # import properties of distribution
    network_type = config.thermal_network.network_type
    list_network_name = ['', '']  # config.thermal_network.network_names
    num_buildings_network = total_demand.Name.count()
    if len(list_network_name) == 0:
        network_name = ''
        pipes_tot_length = pd.read_csv(
            locator.get_optimization_network_edge_list_file(
                network_type, network_name),
            usecols=['pipe length']).sum().values
    else:
        for i, network_name in enumerate(list_network_name):
            if i == 0:
                pipes_tot_length = pd.read_csv(
                    locator.get_optimization_network_edge_list_file(
                        network_type, network_name),
                    usecols=['pipe length']).sum().values
            else:
                pipes_tot_length = pipes_tot_length + pd.read_csv(
                    locator.get_optimization_network_edge_list_file(
                        network_type, network_name),
                    usecols=['pipe length']).sum().values

    ntwk_length = pipes_tot_length.sum(
    ) * num_buildings_network / gv.num_tot_buildings

    # empty vectors
    buildings = []
    substations = []
    Qcdata_netw_total_kWh = np.zeros(8760)
    mcpdata_netw_total_kWperC = np.zeros(8760)
    Electr_netw_total_W = np.zeros(8760)
    mdot_heat_netw_all_kgpers = np.zeros(8760)
    mdot_cool_space_cooling_and_refrigeration_netw_all_kgpers = np.zeros(8760)
    mdot_cool_space_cooling_data_center_and_refrigeration_netw_all_kgpers = np.zeros(
        8760)
    Q_DH_building_netw_total_W = np.zeros(8760)
    Q_DC_building_netw_space_cooling_and_refrigeration_total_W = np.zeros(8760)
    Q_DC_building_netw_space_cooling_data_center_and_refrigeration_total_W = np.zeros(
        8760)
    sum_tret_mdot_heat = np.zeros(8760)
    sum_tret_mdot_cool_space_cooling_and_refrigeration = np.zeros(8760)
    sum_tret_mdot_cool_space_cooling_data_center_and_refrigeration = np.zeros(
        8760)
    mdot_heat_netw_min_kgpers = np.zeros(8760) + 1E6
    mdot_cool_space_cooling_and_refrigeration_netw_min_kgpers = np.zeros(
        8760) + 1E6
    mdot_cool_space_cooling_data_center_and_refrigeration_netw_min_kgpers = np.zeros(
        8760) + 1E6
    iteration = 0

    for building_name in building_names:
        buildings.append(
            pd.read_csv(
                locator.get_demand_results_file(building_name),
                usecols=['DATE', 'mcpcdata_sys_kWperC', 'Qcdata_sys_kWh']))
        substations.append(
            pd.read_csv(
                locator.get_optimization_substations_results_file(
                    building_name),
                usecols=[
                    'Electr_array_all_flat_W', 'mdot_DH_result_kgpers',
                    'mdot_space_cooling_and_refrigeration_result_kgpers',
                    'mdot_space_cooling_data_center_and_refrigeration_result_kgpers',
                    'Q_heating_W', 'Q_dhw_W',
                    'Q_space_cooling_and_refrigeration_W',
                    'Q_space_cooling_data_center_and_refrigeration_W',
                    'T_return_DH_result_K',
                    'T_return_DC_space_cooling_and_refrigeration_result_K',
                    'T_return_DC_space_cooling_data_center_and_refrigeration_result_K',
                    'T_supply_DH_result_K',
                    'T_supply_DC_space_cooling_and_refrigeration_result_K',
                    'T_supply_DC_space_cooling_data_center_and_refrigeration_result_K'
                ]))

        Qcdata_netw_total_kWh += buildings[iteration].Qcdata_sys_kWh.values
        mcpdata_netw_total_kWperC += buildings[
            iteration].mcpcdata_sys_kWperC.values
        Electr_netw_total_W += substations[
            iteration].Electr_array_all_flat_W.values
        mdot_heat_netw_all_kgpers += substations[
            iteration].mdot_DH_result_kgpers.values
        mdot_cool_space_cooling_and_refrigeration_netw_all_kgpers += substations[
            iteration].mdot_space_cooling_and_refrigeration_result_kgpers.values
        mdot_cool_space_cooling_data_center_and_refrigeration_netw_all_kgpers += substations[
            iteration].mdot_space_cooling_data_center_and_refrigeration_result_kgpers.values
        Q_DH_building_netw_total_W += (
            substations[iteration].Q_heating_W.values +
            substations[iteration].Q_dhw_W.values)
        Q_DC_building_netw_space_cooling_and_refrigeration_total_W += (
            substations[iteration].Q_space_cooling_and_refrigeration_W.values)
        Q_DC_building_netw_space_cooling_data_center_and_refrigeration_total_W += (
            substations[iteration].
            Q_space_cooling_data_center_and_refrigeration_W.values)
        sum_tret_mdot_heat += substations[
            iteration].T_return_DH_result_K.values * substations[
                iteration].mdot_DH_result_kgpers.values
        sum_tret_mdot_cool_space_cooling_and_refrigeration += substations[
                                                                  iteration].T_return_DC_space_cooling_and_refrigeration_result_K.values * \
                                                              substations[iteration].mdot_space_cooling_and_refrigeration_result_kgpers.values
        sum_tret_mdot_cool_space_cooling_data_center_and_refrigeration += substations[
                                                                  iteration].T_return_DC_space_cooling_data_center_and_refrigeration_result_K.values * \
                                                              substations[iteration].mdot_space_cooling_data_center_and_refrigeration_result_kgpers.values

        # evaluate minimum flows
        mdot_heat_netw_min_kgpers = np.vectorize(calc_min_flow)(
            mdot_heat_netw_min_kgpers,
            substations[iteration].mdot_DH_result_kgpers.values)
        mdot_cool_space_cooling_and_refrigeration_netw_min_kgpers = np.vectorize(
            calc_min_flow)(
                mdot_cool_space_cooling_and_refrigeration_netw_min_kgpers,
                substations[iteration].
                mdot_space_cooling_and_refrigeration_result_kgpers.values)
        mdot_cool_space_cooling_data_center_and_refrigeration_netw_min_kgpers = np.vectorize(
            calc_min_flow
        )(mdot_cool_space_cooling_data_center_and_refrigeration_netw_min_kgpers,
          substations[iteration].
          mdot_space_cooling_data_center_and_refrigeration_result_kgpers.values
          )
        iteration += 1

    # calculate thermal losses of distribution
    T_DHN_withoutlosses_re_K = np.vectorize(calc_return_temp)(
        sum_tret_mdot_heat, mdot_heat_netw_all_kgpers)

    T_DHN_withoutlosses_sup_K = np.vectorize(calc_supply_temp)(
        T_DHN_withoutlosses_re_K, Q_DH_building_netw_total_W,
        mdot_heat_netw_all_kgpers, HEAT_CAPACITY_OF_WATER_JPERKGK, "DH")

    T_DCN_space_cooling_and_refrigeration_withoutlosses_re_K = np.vectorize(
        calc_return_temp)(
            sum_tret_mdot_cool_space_cooling_and_refrigeration,
            mdot_cool_space_cooling_and_refrigeration_netw_all_kgpers)
    T_DCN_space_cooling_and_refrigeration_withoutlosses_sup_K = np.vectorize(
        calc_supply_temp)(
            T_DCN_space_cooling_and_refrigeration_withoutlosses_re_K,
            Q_DC_building_netw_space_cooling_and_refrigeration_total_W,
            mdot_cool_space_cooling_and_refrigeration_netw_all_kgpers,
            HEAT_CAPACITY_OF_WATER_JPERKGK, "DC")

    T_DCN_space_cooling_data_center_and_refrigeration_withoutlosses_re_K = np.vectorize(
        calc_return_temp
    )(sum_tret_mdot_cool_space_cooling_data_center_and_refrigeration,
      mdot_cool_space_cooling_data_center_and_refrigeration_netw_all_kgpers)
    T_DCN_space_cooling_data_center_and_refrigeration_withoutlosses_sup_K = np.vectorize(
        calc_supply_temp
    )(T_DCN_space_cooling_data_center_and_refrigeration_withoutlosses_re_K,
      Q_DC_building_netw_space_cooling_data_center_and_refrigeration_total_W,
      mdot_cool_space_cooling_data_center_and_refrigeration_netw_all_kgpers,
      HEAT_CAPACITY_OF_WATER_JPERKGK, "DC")

    Q_DH_losses_sup_W = np.vectorize(calc_piping_thermal_losses_heating)(
        T_DHN_withoutlosses_sup_K, mdot_heat_netw_all_kgpers,
        mdot_heat_netw_min_kgpers, ntwk_length, ground_temp, K_DH,
        HEAT_CAPACITY_OF_WATER_JPERKGK)

    Q_DH_losses_re_W = np.vectorize(calc_piping_thermal_losses_heating)(
        T_DHN_withoutlosses_re_K, mdot_heat_netw_all_kgpers,
        mdot_heat_netw_min_kgpers, ntwk_length, ground_temp, K_DH,
        HEAT_CAPACITY_OF_WATER_JPERKGK)
    Q_DH_losses_W = Q_DH_losses_sup_W + Q_DH_losses_re_W
    Q_DHNf_W = Q_DH_building_netw_total_W + Q_DH_losses_W

    Q_DC_space_cooling_and_refrigeration_losses_sup_W = np.vectorize(
        calc_piping_thermal_losses_cooling)(
            Q_DC_building_netw_space_cooling_and_refrigeration_total_W)
    Q_DC_space_cooling_data_center_and_refrigeration_losses_sup_W = np.vectorize(
        calc_piping_thermal_losses_cooling
    )(Q_DC_building_netw_space_cooling_data_center_and_refrigeration_total_W)

    Q_DC_space_cooling_and_refrigeration_losses_re_W = np.vectorize(
        calc_piping_thermal_losses_cooling)(
            Q_DC_building_netw_space_cooling_and_refrigeration_total_W)
    Q_DC_space_cooling_data_center_and_refrigeration_losses_re_W = np.vectorize(
        calc_piping_thermal_losses_cooling
    )(Q_DC_building_netw_space_cooling_data_center_and_refrigeration_total_W)

    Q_DC_space_cooling_and_refrigeration_losses_W = Q_DC_space_cooling_and_refrigeration_losses_sup_W + Q_DC_space_cooling_and_refrigeration_losses_re_W
    Q_DC_space_cooling_data_center_and_refrigeration_losses_W = Q_DC_space_cooling_data_center_and_refrigeration_losses_sup_W + Q_DC_space_cooling_data_center_and_refrigeration_losses_re_W

    Q_DCNf_space_cooling_and_refrigeration_W = Q_DC_building_netw_space_cooling_and_refrigeration_total_W + Q_DC_space_cooling_and_refrigeration_losses_W
    Q_DCNf_space_cooling_data_center_and_refrigeration_W = Q_DC_building_netw_space_cooling_data_center_and_refrigeration_total_W + Q_DC_space_cooling_data_center_and_refrigeration_losses_W

    T_DHN_re_K = np.vectorize(calc_temp_withlosses)(
        T_DHN_withoutlosses_re_K, Q_DH_losses_re_W, mdot_heat_netw_all_kgpers,
        HEAT_CAPACITY_OF_WATER_JPERKGK, "negative")

    T_DHN_sup_K = np.vectorize(calc_temp_withlosses)(
        T_DHN_withoutlosses_sup_K, Q_DH_losses_sup_W,
        mdot_heat_netw_all_kgpers, HEAT_CAPACITY_OF_WATER_JPERKGK, "positive")

    T_DCN_space_cooling_and_refrigeration_re_K = np.vectorize(
        calc_temp_withlosses)(
            T_DCN_space_cooling_and_refrigeration_withoutlosses_re_K,
            Q_DC_space_cooling_and_refrigeration_losses_re_W,
            mdot_cool_space_cooling_and_refrigeration_netw_all_kgpers,
            HEAT_CAPACITY_OF_WATER_JPERKGK, "positive")

    T_DCN_space_cooling_data_center_and_refrigeration_re_K = np.vectorize(
        calc_temp_withlosses
    )(T_DCN_space_cooling_data_center_and_refrigeration_withoutlosses_re_K,
      Q_DC_space_cooling_data_center_and_refrigeration_losses_re_W,
      mdot_cool_space_cooling_data_center_and_refrigeration_netw_all_kgpers,
      HEAT_CAPACITY_OF_WATER_JPERKGK, "positive")

    T_DCN_space_cooling_and_refrigeration_sup_K = np.vectorize(
        calc_temp_withlosses)(
            T_DCN_space_cooling_and_refrigeration_withoutlosses_sup_K,
            Q_DC_space_cooling_and_refrigeration_losses_sup_W,
            mdot_cool_space_cooling_and_refrigeration_netw_all_kgpers,
            HEAT_CAPACITY_OF_WATER_JPERKGK, "negative")

    T_DCN_space_cooling_data_center_and_refrigeration_sup_K = np.vectorize(
        calc_temp_withlosses
    )(T_DCN_space_cooling_data_center_and_refrigeration_withoutlosses_sup_K,
      Q_DC_space_cooling_data_center_and_refrigeration_losses_sup_W,
      mdot_cool_space_cooling_data_center_and_refrigeration_netw_all_kgpers,
      HEAT_CAPACITY_OF_WATER_JPERKGK, "negative")

    day_of_max_heatmassflow_fin = np.zeros(8760)
    day_of_max_heatmassflow = find_index_of_max(mdot_heat_netw_all_kgpers)
    day_of_max_heatmassflow_fin[:] = day_of_max_heatmassflow

    for i in range(8760):
        if T_DCN_space_cooling_data_center_and_refrigeration_sup_K[
                i] > T_DCN_space_cooling_data_center_and_refrigeration_re_K[i]:
            print(i)

        if T_DCN_space_cooling_and_refrigeration_sup_K[
                i] > T_DCN_space_cooling_and_refrigeration_re_K[i]:
            print(i)

    date = pd.read_csv(locator.get_demand_results_file(
        building_names[0])).DATE.values
    results = pd.DataFrame({
        "DATE":
        date,
        "mdot_DH_netw_total_kgpers":
        mdot_heat_netw_all_kgpers,
        "mdot_cool_space_cooling_and_refrigeration_netw_all_kgpers":
        mdot_cool_space_cooling_and_refrigeration_netw_all_kgpers,
        "mdot_cool_space_cooling_data_center_and_refrigeration_netw_all_kgpers":
        mdot_cool_space_cooling_data_center_and_refrigeration_netw_all_kgpers,
        "Q_DHNf_W":
        Q_DHNf_W,
        "Q_DCNf_space_cooling_and_refrigeration_W":
        Q_DCNf_space_cooling_and_refrigeration_W,
        "Q_DCNf_space_cooling_data_center_and_refrigeration_W":
        Q_DCNf_space_cooling_data_center_and_refrigeration_W,
        "T_DHNf_re_K":
        T_DHN_re_K,
        "T_DCNf_space_cooling_and_refrigeration_re_K":
        T_DCN_space_cooling_and_refrigeration_re_K,
        "T_DCNf_space_cooling_data_center_and_refrigeration_re_K":
        T_DCN_space_cooling_data_center_and_refrigeration_re_K,
        "T_DHNf_sup_K":
        T_DHN_sup_K,
        "T_DCNf_space_cooling_and_refrigeration_sup_K":
        T_DCN_space_cooling_and_refrigeration_sup_K,
        "T_DCNf_space_cooling_data_center_and_refrigeration_sup_K":
        T_DCN_space_cooling_data_center_and_refrigeration_sup_K,
        "Qcdata_netw_total_kWh":
        Qcdata_netw_total_kWh,
        "day_of_max_heatmassflow":
        day_of_max_heatmassflow,
        "mcpdata_netw_total_kWperC":
        mcpdata_netw_total_kWperC,
        "Electr_netw_total_W":
        Electr_netw_total_W,
        "Q_DH_losses_W":
        Q_DH_losses_W,
        "Q_DC_space_cooling_and_refrigeration_losses_W":
        Q_DC_space_cooling_and_refrigeration_losses_W,
        "Q_DC_space_cooling_data_center_and_refrigeration_losses_W":
        Q_DC_space_cooling_data_center_and_refrigeration_losses_W
    })

    # the key depicts weather this is the distribution of all customers or a distribution of a gorup of them.
    if key == 'all':
        results.to_csv(
            locator.get_optimization_network_all_results_summary(key),
            index=False)
    else:
        results.to_csv(locator.get_optimization_network_results_summary(key),
                       index=False)

    print time.clock(
    ) - t0, "seconds process time for Network summary for configuration", key, "\n"
def extract_loads_individual(locator, DCN_barcode, DHN_barcode,
                             district_heating_network,
                             district_cooling_network,
                             column_names_buildings_heating,
                             column_names_buildings_cooling):
    # local variables
    weather_file = locator.get_weather_file()
    network_depth_m = Z0
    T_ambient = epwreader.epw_reader(weather_file)['drybulb_C']
    ground_temp = calc_ground_temperature(locator,
                                          T_ambient,
                                          depth_m=network_depth_m)

    # EVALUATE CASES TO CREATE A NETWORK OR NOT
    if district_heating_network:  # network exists
        network_file_name_heating = "DH_Network_summary_result_" + hex(
            int(str(DHN_barcode), 2)) + ".csv"
        if not os.path.exists(
                locator.get_optimization_network_results_summary(
                    'DH', DHN_barcode)):
            total_demand = createTotalNtwCsv(DHN_barcode, locator,
                                             column_names_buildings_heating)
            num_total_buildings = len(column_names_buildings_heating)
            buildings_in_heating_network = total_demand.Name.values
            # Run the substation and distribution routines
            substation.substation_main_heating(locator,
                                               total_demand,
                                               buildings_in_heating_network,
                                               DHN_barcode=DHN_barcode)
            results = summarize_network.network_main(
                locator, buildings_in_heating_network, ground_temp,
                num_total_buildings, "DH", DHN_barcode)
        else:
            results = pd.read_csv(
                locator.get_optimization_network_results_summary(
                    'DH', DHN_barcode))

        Q_DHNf_W = results['Q_DHNf_W'].values
        Q_heating_max_W = Q_DHNf_W.max()
        Qcdata_netw_total_kWh = results['Qcdata_netw_total_kWh'].values
        Q_wasteheat_datacentre_max_W = Qcdata_netw_total_kWh.max()
    else:
        Q_heating_max_W = 0.0
        Q_wasteheat_datacentre_max_W = 0.0
        network_file_name_heating = ""

    if district_cooling_network:  # network exists
        network_file_name_cooling = "DC_Network_summary_result_" + hex(
            int(str(DCN_barcode), 2)) + ".csv"
        if not os.path.exists(
                locator.get_optimization_network_results_summary(
                    'DC', DCN_barcode)):
            total_demand = createTotalNtwCsv(DCN_barcode, locator,
                                             column_names_buildings_cooling)
            num_total_buildings = len(column_names_buildings_cooling)
            buildings_in_cooling_network = total_demand.Name.values

            # Run the substation and distribution routines
            substation.substation_main_cooling(locator,
                                               total_demand,
                                               buildings_in_cooling_network,
                                               DCN_barcode=DCN_barcode)
            results = summarize_network.network_main(
                locator, buildings_in_cooling_network, ground_temp,
                num_total_buildings, 'DC', DCN_barcode)
        else:
            results = pd.read_csv(
                locator.get_optimization_network_results_summary(
                    'DC', DCN_barcode))

        # if heat recovery is ON, then only need to satisfy cooling load of space cooling and refrigeration
        Q_DCNf_W = results[
            "Q_DCNf_space_cooling_data_center_and_refrigeration_W"].values
        Q_cooling_max_W = Q_DCNf_W.max()
    else:
        Q_cooling_max_W = 0.0
        network_file_name_cooling = ""

    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)

    return Q_cooling_nom_W, Q_heating_nom_W, Q_wasteheat_datacentre_max_W, network_file_name_cooling, network_file_name_heating
 def __init__(self, weather_file, locator):
     self.weather_data = epwreader.epw_reader(weather_file)
     self.date = self.weather_data['date']
     self.T_ambient = self.weather_data['drybulb_C']
     self.ground_temp = calc_ground_temperature(locator, self.T_ambient, depth_m=Z0)
def Storage_Design(T_storage_old_K, Q_in_storage_old_W, locator,
                   STORAGE_SIZE_m3, solar_technologies_data,
                   master_to_slave_vars, P_HP_max_W):
    """

    :param CSV_NAME:
    :param SOLCOL_TYPE:
    :param T_storage_old_K:
    :param Q_in_storage_old_W:
    :param locator:
    :param STORAGE_SIZE_m3:
    :param STORE_DATA:
    :param master_to_slave_vars:
    :param P_HP_max_W:
    :type CSV_NAME:
    :type SOLCOL_TYPE:
    :type T_storage_old_K:
    :type Q_in_storage_old_W:
    :type locator:
    :type STORAGE_SIZE_m3:
    :type STORE_DATA:
    :type master_to_slave_vars:
    :type P_HP_max_W:
    :return:
    :rtype:
    """

    # Get network summary
    Network_Data, \
    Q_DH_networkload_Wh, \
    Q_wasteheatServer_Wh, \
    T_DH_return_array_K, \
    T_DH_supply_array_K, \
    mdot_heat_netw_total_kgpers = read_data_from_Network_summary(master_to_slave_vars)

    # Get ground temperatures
    weather_path = locator.get_weather_file()
    weather_data = epwreader.epw_reader(weather_path)[[
        'year', 'drybulb_C', 'wetbulb_C', 'relhum_percent', 'windspd_ms',
        'skytemp_C'
    ]]
    T_ground_K = calc_ground_temperature(locator,
                                         weather_data['drybulb_C'],
                                         depth_m=10)

    # Calculate DH operation with on-site energy sources and storage
    T_amb_K = weather_data['drybulb_C'] + 273.15  # K
    T_storage_min_K = master_to_slave_vars.T_ST_MAX
    Q_disc_seasonstart_W = [0]

    # Get installation and production data of all types of solar technologies for every hour of the year
    E_PVT_gen_Whr = solar_technologies_data['E_PVT_gen_W']
    Q_PVT_gen_Whr = solar_technologies_data['Q_PVT_gen_W']
    Q_SC_ET_gen_Whr = solar_technologies_data['Q_SC_ET_gen_W']
    Q_SC_FP_gen_Whr = solar_technologies_data['Q_SC_FP_gen_W']
    Solar_Tscr_th_PVT_K_hour = solar_technologies_data['Tscr_th_PVT_K']
    Solar_Tscr_th_SC_ET_K_hour = solar_technologies_data['Tscr_th_SC_ET_K']
    Solar_Tscr_th_SC_FP_K_hour = solar_technologies_data['Tscr_th_SC_FP_K']

    # Initialize variables
    Q_storage_content_final_Whr = np.zeros(HOURS_IN_YEAR)
    T_storage_final_Khr = np.zeros(HOURS_IN_YEAR)
    Q_from_storage_final_Whr = np.zeros(HOURS_IN_YEAR)
    Q_to_storage_final_Whr = np.zeros(HOURS_IN_YEAR)
    E_aux_ch_final_Whr = np.zeros(HOURS_IN_YEAR)
    E_aux_dech_final_Whr = np.zeros(HOURS_IN_YEAR)
    Q_uncontrollable_final_Whr = np.zeros(HOURS_IN_YEAR)
    Q_missing_final_Whr = np.zeros(HOURS_IN_YEAR)
    Q_rejected_final_W = np.zeros(HOURS_IN_YEAR)
    mdot_DH_final_kgpers = np.zeros(HOURS_IN_YEAR)
    E_HPSC_FP_final_req_Whr = np.zeros(HOURS_IN_YEAR)
    E_HPSC_ET_final_req_Whr = np.zeros(HOURS_IN_YEAR)
    E_HPPVT_final_req_Whr = np.zeros(HOURS_IN_YEAR)
    E_HPServer_final_req_Whr = np.zeros(HOURS_IN_YEAR)
    Q_PVT_to_directload_Whr = np.zeros(HOURS_IN_YEAR)
    Q_SC_ET_to_directload_Whr = np.zeros(HOURS_IN_YEAR)
    Q_SC_FP_to_directload_Whr = np.zeros(HOURS_IN_YEAR)
    Q_server_to_directload_Whr = np.zeros(HOURS_IN_YEAR)
    Q_PVT_to_storage_Whr = np.zeros(HOURS_IN_YEAR)
    Q_SC_ET_to_storage_Whr = np.zeros(HOURS_IN_YEAR)
    Q_SC_FP_to_storage_Whr = np.zeros(HOURS_IN_YEAR)
    Q_server_to_storage_Whr = np.zeros(HOURS_IN_YEAR)
    Q_HP_Server_Whr = np.zeros(HOURS_IN_YEAR)
    Q_HP_PVT_Whr = np.zeros(HOURS_IN_YEAR)
    Q_HP_SC_ET_Whr = np.zeros(HOURS_IN_YEAR)
    Q_HP_SC_FP_Whr = np.zeros(HOURS_IN_YEAR)
    Q_loss_Whr = np.zeros(HOURS_IN_YEAR)

    for HOUR in range(
            HOURS_IN_YEAR
    ):  # no idea why, but if we try a for loop it does not work
        # Get network temperatures and capacity flow rates
        T_DH_sup_K = T_DH_supply_array_K[HOUR]
        T_DH_return_K = T_DH_return_array_K[HOUR]
        mdot_DH_kgpers = mdot_heat_netw_total_kgpers[HOUR]
        Q_Server_gen_initial_W = Q_wasteheatServer_Wh[HOUR]
        Q_PVT_gen_W = Q_PVT_gen_Whr[HOUR]
        Q_SC_ET_gen_W = Q_SC_ET_gen_Whr[HOUR]
        Q_SC_FP_gen_W = Q_SC_FP_gen_Whr[HOUR]
        Solar_Tscr_th_PVT_K = Solar_Tscr_th_PVT_K_hour[HOUR]
        Solar_Tscr_th_SC_ET_K = Solar_Tscr_th_SC_ET_K_hour[HOUR]
        Solar_Tscr_th_SC_FP_K = Solar_Tscr_th_SC_FP_K_hour[HOUR]

        # Get heating demand in DH
        Q_network_demand_W = Q_DH_networkload_Wh[HOUR]

        # Get heating proved by SOLAR AND DATA CENTER (IF ANY)
        E_HP_solar_and_server_req_W, \
        Q_PVT_gen_W, \
        Q_SC_ET_gen_W, \
        Q_SC_FP_gen_W, \
        Q_Server_gen_W, \
        E_HPSC_FP_req_W, \
        E_HPSC_ET_req_W, \
        E_HPPVT_reg_W, \
        E_HPServer_reg_W, \
        Q_HP_Server_W, \
        Q_HP_PVT_W, \
        Q_HP_SC_ET_W, \
        Q_HP_SC_FP_W = get_heating_provided_by_onsite_energy_sources(Q_PVT_gen_W,
                                                                     Q_SC_ET_gen_W,
                                                                     Q_SC_FP_gen_W,
                                                                     Q_Server_gen_initial_W,
                                                                     Solar_Tscr_th_PVT_K,
                                                                     Solar_Tscr_th_SC_ET_K,
                                                                     Solar_Tscr_th_SC_FP_K,
                                                                     T_DH_sup_K,
                                                                     master_to_slave_vars)

        # Calculate storage operation
        Q_in_storage_new_W, \
        T_storage_new_K, \
        Q_from_storage_req_W, \
        Q_to_storage_W, \
        E_aux_ch_W, \
        E_aux_dech_W, \
        Q_missing_W, \
        Q_loss_W, \
        mdot_DH_missing_kgpers, \
        Q_server_to_directload_W, \
        Q_server_to_storage_W, \
        Q_PVT_to_directload_W, \
        Q_PVT_to_storage_W, \
        Q_SC_ET_to_directload_W, \
        Q_SC_ET_to_storage_W, \
        Q_SC_FP_to_directload_W, \
        Q_SC_FP_to_storage_W = SPH_fn.Storage_Operator(Q_PVT_gen_W, Q_SC_ET_gen_W, Q_SC_FP_gen_W, Q_Server_gen_W,
                                                       Q_network_demand_W, T_storage_old_K, T_DH_sup_K, T_amb_K[HOUR],
                                                       Q_in_storage_old_W, T_DH_return_K, mdot_DH_kgpers,
                                                       STORAGE_SIZE_m3,
                                                       master_to_slave_vars, P_HP_max_W, T_ground_K[HOUR])

        ## Modify storage level according to temeprature
        if Q_in_storage_new_W < 0.0001:
            Q_in_storage_new_W = 0.0

        # if storage temperature too high, no more charging possible - reject energy
        if T_storage_new_K >= master_to_slave_vars.T_ST_MAX - 0.001:
            Q_in_storage_new_W = min(Q_in_storage_old_W, Q_in_storage_new_W)
            Q_to_storage_W = max(Q_in_storage_new_W - Q_in_storage_old_W, 0)
            Q_rejected_final_W[HOUR] = Q_PVT_gen_W + \
                                       Q_SC_ET_gen_W + \
                                       Q_SC_FP_gen_W + \
                                       Q_Server_gen_W \
                                       - Q_to_storage_W
            T_storage_new_K = min(T_storage_old_K, T_storage_new_K)
            E_aux_ch_W = 0

        ## Overwrite values for the calculation in the next timestep
        Q_in_storage_old_W = Q_in_storage_new_W
        T_storage_old_K = T_storage_new_K

        # catch an error if the storage temperature is too low
        # if T_storage_old_K < T_amb_K[HOUR] - 1:
        #     # print "Storage temperature is too lower than ambient, please check the calculation"

        ## Save values for the current timestep
        Q_storage_content_final_Whr[HOUR] = Q_in_storage_new_W
        T_storage_final_Khr[HOUR] = T_storage_new_K
        Q_from_storage_final_Whr[HOUR] = Q_from_storage_req_W
        Q_to_storage_final_Whr[HOUR] = Q_to_storage_W
        E_aux_ch_final_Whr[HOUR] = E_aux_ch_W
        E_aux_dech_final_Whr[HOUR] = E_aux_dech_W

        # scale to the fraction taht goes directly to the grid. the rest is considered in the storage charging and discharging
        E_HPSC_FP_final_req_Whr[HOUR] = E_HPSC_FP_req_W
        E_HPSC_ET_final_req_Whr[HOUR] = E_HPSC_ET_req_W
        E_HPPVT_final_req_Whr[HOUR] = E_HPPVT_reg_W
        E_HPServer_final_req_Whr[HOUR] = E_HPServer_reg_W

        Q_PVT_to_directload_Whr[HOUR] = Q_PVT_to_directload_W
        Q_SC_ET_to_directload_Whr[HOUR] = Q_SC_ET_to_directload_W
        Q_SC_FP_to_directload_Whr[HOUR] = Q_SC_FP_to_directload_W
        Q_server_to_directload_Whr[HOUR] = Q_server_to_directload_W
        Q_PVT_to_storage_Whr[HOUR] = Q_PVT_to_storage_W
        Q_SC_ET_to_storage_Whr[HOUR] = Q_SC_ET_to_storage_W
        Q_SC_FP_to_storage_Whr[HOUR] = Q_SC_FP_to_storage_W
        Q_server_to_storage_Whr[HOUR] = Q_server_to_storage_W
        Q_HP_Server_Whr[HOUR] = Q_HP_Server_W
        Q_HP_PVT_Whr[HOUR] = Q_HP_PVT_W
        Q_HP_SC_ET_Whr[HOUR] = Q_HP_SC_ET_W
        Q_HP_SC_FP_Whr[HOUR] = Q_HP_SC_FP_W
        Q_loss_Whr[HOUR] = Q_loss_W
        # heating demand satisfied directly from these technologies
        Q_uncontrollable_final_Whr[HOUR] = Q_PVT_to_directload_W + \
                                           Q_SC_ET_to_directload_W + \
                                           Q_SC_FP_to_directload_W + \
                                           Q_server_to_directload_W

        # heating demand required from heating plant
        Q_missing_final_Whr[
            HOUR] = Q_network_demand_W - Q_uncontrollable_final_Whr[
                HOUR] - Q_from_storage_final_Whr[HOUR]

        # amount of heat required from heating plants
        mdot_DH_final_kgpers[HOUR] = mdot_DH_missing_kgpers

        if T_storage_new_K <= T_storage_min_K:
            T_storage_min_K = T_storage_new_K
            Q_disc_seasonstart_W[0] += Q_from_storage_req_W

    Q_stored_max_W = np.amax(Q_storage_content_final_Whr)
    T_st_max_K = np.amax(T_storage_final_Khr)
    T_st_min_K = np.amin(T_storage_final_Khr)
    Q_loss_tot_W = np.sum(Q_loss_Whr)

    storage_dispatch = {

        # TOTAL ENERGY GENERATED
        "Q_SC_ET_gen_W": Q_SC_ET_gen_Whr,
        "Q_SC_FP_gen_W": Q_SC_FP_gen_Whr,
        "Q_PVT_gen_W": Q_PVT_gen_Whr,
        "Q_HP_Server_gen_W":
        Q_server_to_storage_Whr + Q_server_to_directload_Whr,

        # ENERGY GOING DIRECTLY TO CUSTOMERS
        "Q_PVT_gen_directload_W": Q_PVT_to_directload_Whr,
        "Q_SC_ET_gen_directload_W": Q_SC_ET_to_directload_Whr,
        "Q_SC_FP_gen_directload_W": Q_SC_FP_to_directload_Whr,
        "Q_HP_Server_gen_directload_W": Q_server_to_directload_Whr,

        # ENERGY GOING INTO THE STORAGE
        # total
        "Q_Storage_req_W": Q_to_storage_final_Whr,
        # per technology
        "Q_PVT_gen_storage_W": Q_PVT_to_storage_Whr,
        "Q_SC_ET_gen_storage_W": Q_SC_ET_to_storage_Whr,
        "Q_SC_FP_gen_storage_W": Q_SC_FP_to_storage_Whr,
        "Q_HP_Server_gen_storage_W": Q_server_to_storage_Whr,

        # ENERGY COMMING FROM THE STORAGE
        "Q_Storage_gen_W": Q_from_storage_final_Whr,

        # AUXILIARY LOADS NEEDED TO CHARGE/DISCHARGE THE STORAGE
        "E_Storage_charging_req_W": E_aux_ch_final_Whr,
        "E_Storage_discharging_req_W": E_aux_dech_final_Whr,
        "E_HP_SC_FP_req_W":
        E_HPSC_FP_final_req_Whr,  # this is included in charging the storage
        "E_HP_SC_ET_req_W":
        E_HPSC_ET_final_req_Whr,  # this is included in charging the storage
        "E_HP_PVT_req_W":
        E_HPPVT_final_req_Whr,  # this is included in charging the storage
        "E_HP_Server_req_W":
        E_HPServer_final_req_Whr,  # this is included in charging the storage

        # ENERGY THAT NEEDS TO BE SUPPLIED (NEXT)
        "Q_req_after_storage_W": Q_missing_final_Whr,

        # mass flow rate of the network, size and energy generated
        "mdot_DH_fin_kgpers": mdot_DH_final_kgpers,
        "E_PVT_gen_W":
        E_PVT_gen_Whr,  # useful later on for the electricity dispatch curve
        "Storage_Size_m3": STORAGE_SIZE_m3,
        "Q_storage_content_W": Q_storage_content_final_Whr,
        "Q_storage_max_W": Q_stored_max_W,
        "Q_DH_networkload_W": Q_DH_networkload_Wh,

        # this helps to know the peak (thermal) of the heatpumps
        "Q_HP_Server_W": Q_HP_PVT_Whr,
        "Q_HP_PVT_W": Q_HP_PVT_Whr,
        "Q_HP_SC_ET_W": Q_HP_SC_ET_Whr,
        "Q_HP_SC_FP_W": Q_HP_SC_FP_Whr,
    }

    return (Q_stored_max_W, Q_rejected_final_W, Q_disc_seasonstart_W,
            T_st_max_K, T_st_min_K, Q_storage_content_final_Whr,
            T_storage_final_Khr, Q_loss_tot_W, mdot_DH_final_kgpers,
            Q_uncontrollable_final_Whr), storage_dispatch
def preproccessing(locator, total_demand, building_names, weather_file, gv):
    """
    This function aims at preprocessing all data for the optimization.

    :param locator: path to locator function
    :param total_demand: dataframe with total demand and names of all building in the area
    :param building_names: dataframe with names of all buildings in the area
    :param weather_file: path to wather file
    :param gv: path to global variables class
    :type locator: class
    :type total_demand: list
    :type building_names: list
    :type weather_file: string
    :type gv: class
    :return: extraCosts: extra pareto optimal costs due to electricity and process heat (
             these are treated separately and not considered inside the optimization)
             extraCO2: extra pareto optimal emissions due to electricity and process heat (
             these are treated separately and not considered inside the optimization)
             extraPrim: extra pareto optimal primary energy due to electricity and process heat (
             these are treated separately and not considered inside the optimization)
             solar_features: extraction of solar features form the results of the solar technologies
             calculation.
    :rtype: float, float, float, float
    """

    # GET ENERGY POTENTIALS
    # geothermal
    T_ambient = epwreader.epw_reader(weather_file)['drybulb_C']
    gv.ground_temperature = geothermal.calc_ground_temperature(
        T_ambient.values, gv)

    # solar
    print "Solar features extraction"
    solar_features = SolarFeatures(locator)

    # GET LOADS IN SUBSTATIONS
    # prepocess space heating, domestic hot water and space cooling to substation.
    print "Run substation model for each building separately"
    substation.substation_main(
        locator, total_demand, building_names, gv,
        Flag=True)  # True if disconected buildings are calculated

    # GET COMPETITIVE ALTERNATIVES TO A NETWORK
    # estimate what would be the operation of single buildings only for heating.
    # For cooling all buildings are assumed to be connected to the cooling distribution on site.
    print "Run decentralized model for buildings"
    #decentralized_buildings.decentralized_main(locator, building_names, gv)

    # GET DH NETWORK
    # at first estimate a distribution with all the buildings connected at it.
    print "Create distribution file with all buildings connected"
    summarize_network.network_main(locator, total_demand, building_names, gv,
                                   "all")  #"_all" key for all buildings

    # GET EXTRAS
    # estimate the extra costs, emissions and primary energy of electricity.
    print "electricity"
    elecCosts, elecCO2, elecPrim = electricity.calc_pareto_electricity(
        locator, gv)

    # estimate the extra costs, emissions and primary energy for process heat
    print "Process-heat"
    hpCosts, hpCO2, hpPrim = process_heat.calc_pareto_Qhp(
        locator, total_demand, gv)

    extraCosts = elecCosts + hpCosts
    extraCO2 = elecCO2 + hpCO2
    extraPrim = elecPrim + hpPrim

    return extraCosts, extraCO2, extraPrim, solar_features
Example #13
0
def Storage_Design(CSV_NAME, SOLCOL_TYPE, T_storage_old_K, Q_in_storage_old_W, locator,
                   STORAGE_SIZE_m3, STORE_DATA, master_to_slave_vars, P_HP_max_W, config):
    """

    :param CSV_NAME:
    :param SOLCOL_TYPE:
    :param T_storage_old_K:
    :param Q_in_storage_old_W:
    :param locator:
    :param STORAGE_SIZE_m3:
    :param STORE_DATA:
    :param master_to_slave_vars:
    :param P_HP_max_W:
    :param gV:
    :type CSV_NAME:
    :type SOLCOL_TYPE:
    :type T_storage_old_K:
    :type Q_in_storage_old_W:
    :type locator:
    :type STORAGE_SIZE_m3:
    :type STORE_DATA:
    :type master_to_slave_vars:
    :type P_HP_max_W:
    :type gV:
    :return:
    :rtype:
    """


    # Import Network Data
    Network_Data = pd.read_csv(locator.get_optimization_network_data_folder(CSV_NAME))

    # recover Network  Data:
    mdot_heat_netw_total_kgpers = Network_Data['mdot_DH_netw_total_kgpers'].values
    Q_DH_networkload_W = Network_Data['Q_DHNf_W'].values
    T_DH_return_array_K =  Network_Data['T_DHNf_re_K'].values
    T_DH_supply_array_K = Network_Data['T_DHNf_sup_K'].values
    Q_wasteheatServer_kWh =  Network_Data['Qcdata_netw_total_kWh'].values
    
    Solar_Data_SC = np.zeros((8760, 7))
    Solar_Data_PVT = np.zeros((8760, 7))
    Solar_Data_PV = np.zeros((8760, 7))
    
    Solar_Tscr_th_SC_K = Solar_Data_SC[:,6]
    Solar_E_aux_SC_req_kWh = Solar_Data_SC[:,1]
    Solar_Q_th_SC_kWh = Solar_Data_SC[:,1]
    
    Solar_Tscr_th_PVT_K = Solar_Data_PVT[:,6]
    Solar_E_aux_PVT_kW = Solar_Data_PVT[:,1]
    Solar_Q_th_SC_kWh = Solar_Data_PVT[:,2]
    PVT_kWh = Solar_Data_PVT[:,5]
    Solar_E_aux_PV_kWh = Solar_Data_PV[:,1]
    PV_kWh = Solar_Data_PV[:,5]
    
    # Import Solar Data
    os.chdir(locator.get_potentials_solar_folder())
    
    fNameArray = [master_to_slave_vars.SOLCOL_TYPE_PVT, master_to_slave_vars.SOLCOL_TYPE_SC_ET, master_to_slave_vars.SOLCOL_TYPE_SC_FP, master_to_slave_vars.SOLCOL_TYPE_PV]
    
        #LOOP AROUND ALL SC TYPES
    for solartype in range(4):
        fName = fNameArray[solartype]
    
        if master_to_slave_vars.SOLCOL_TYPE_SC_ET != "NONE" and fName == master_to_slave_vars.SOLCOL_TYPE_SC_ET:
            Solar_Area_SC_ET_m2, Solar_E_aux_SC_ET_req_kWh, Solar_Q_th_SC_ET_kWh, Solar_Tscs_th_SC_ET, Solar_mcp_SC_ET_kWperC, SC_ET_kWh, Solar_Tscr_th_SC_ET_K\
                            = fn.import_solar_data(master_to_slave_vars.SOLCOL_TYPE_SC_ET)

        if master_to_slave_vars.SOLCOL_TYPE_SC_FP != "NONE" and fName == master_to_slave_vars.SOLCOL_TYPE_SC_FP:
            Solar_Area_SC_FP_m2, Solar_E_aux_SC_FP_req_kWh, Solar_Q_th_SC_FP_kWh, Solar_Tscs_th_SC_FP, Solar_mcp_SC_FP_kWperC, SC_FP_kWh, Solar_Tscr_th_SC_FP_K \
                = fn.import_solar_data(master_to_slave_vars.SOLCOL_TYPE_SC_FP)
        
        if master_to_slave_vars.SOLCOL_TYPE_PVT != "NONE" and fName == master_to_slave_vars.SOLCOL_TYPE_PVT:
            Solar_Area_PVT_m2, Solar_E_aux_PVT_kW, Solar_Q_th_PVT_kW, Solar_Tscs_th_PVT, Solar_mcp_PVT_kWperC, PVT_kWh, Solar_Tscr_th_PVT_K \
                            = fn.import_solar_data(master_to_slave_vars.SOLCOL_TYPE_PVT)

        if master_to_slave_vars.SOLCOL_TYPE_PV != "NONE" and fName == master_to_slave_vars.SOLCOL_TYPE_PV:
            Solar_Area_PV_m2, Solar_E_aux_PV_kWh, Solar_Q_th_PV_kW, Solar_Tscs_th_PV, Solar_mcp_PV_kWperC, PV_kWh, Solar_Tscr_th_PV_K\
                            = fn.import_solar_data(master_to_slave_vars.SOLCOL_TYPE_PV)

    
    # Recover Solar Data
    Solar_E_aux_W = np.ravel(Solar_E_aux_SC_ET_req_kWh * 1000 * master_to_slave_vars.SOLAR_PART_SC_ET) + np.ravel(Solar_E_aux_SC_FP_req_kWh * 1000 * master_to_slave_vars.SOLAR_PART_SC_FP)\
                    + np.ravel(Solar_E_aux_PVT_kW * 1000 * master_to_slave_vars.SOLAR_PART_PVT)  + np.ravel(Solar_E_aux_PV_kWh * 1000 * master_to_slave_vars.SOLAR_PART_PV)

    
    Q_SC_ET_gen_Wh = Solar_Q_th_SC_ET_kWh * 1000 * master_to_slave_vars.SOLAR_PART_SC_ET
    Q_SC_FP_gen_Wh = Solar_Q_th_SC_FP_kWh * 1000 * master_to_slave_vars.SOLAR_PART_SC_FP
    Q_PVT_gen_Wh = Solar_Q_th_PVT_kW * 1000 * master_to_slave_vars.SOLAR_PART_PVT
    Q_SCandPVT_gen_Wh = np.zeros(8760)
    weather_data = epwreader.epw_reader(config.weather)[['year', 'drybulb_C', 'wetbulb_C','relhum_percent',
                                                              'windspd_ms', 'skytemp_C']]
    ground_temp = calc_ground_temperature(locator, config, weather_data['drybulb_C'], depth_m=10)

    for hour in range(len(Q_SCandPVT_gen_Wh)):
        Q_SCandPVT_gen_Wh[hour] = Q_SC_ET_gen_Wh[hour] + Q_SC_FP_gen_Wh[hour] + Q_PVT_gen_Wh[hour]

    
    E_PV_Wh = PV_kWh * 1000 * master_to_slave_vars.SOLAR_PART_PV
    E_PVT_Wh = PVT_kWh * 1000  * master_to_slave_vars.SOLAR_PART_PVT

    HOUR = 0
    Q_to_storage_avail_W = np.zeros(8760)
    Q_from_storage_W = np.zeros(8760)
    to_storage = np.zeros(8760)
    Q_storage_content_fin_W = np.zeros(8760)
    Q_server_to_directload_W = np.zeros(8760)
    Q_server_to_storage_W = np.zeros(8760)
    Q_compair_to_directload_W = np.zeros(8760)
    Q_compair_to_storage_W = np.zeros(8760)
    Q_PVT_to_directload_W = np.zeros(8760)
    Q_PVT_to_storage_W = np.zeros(8760)
    Q_SC_ET_to_directload_W = np.zeros(8760)
    Q_SC_ET_to_storage_W = np.zeros(8760)
    Q_SC_FP_to_directload_W = np.zeros(8760)
    Q_SC_FP_to_storage_W = np.zeros(8760)
    T_storage_fin_K = np.zeros(8760)
    Q_from_storage_fin_W = np.zeros(8760)
    Q_to_storage_fin_W = np.zeros(8760)
    E_aux_ch_fin_W = np.zeros(8760)
    E_aux_dech_fin_W = np.zeros(8760)
    #E_PV_Wh_fin = np.zeros(8760)
    E_aux_solar_W = np.zeros(8760)
    Q_missing_fin_W = np.zeros(8760)
    Q_from_storage_used_fin_W = np.zeros(8760)
    Q_rejected_fin_W = np.zeros(8760)
    mdot_DH_fin_kgpers = np.zeros(8760)
    Q_uncontrollable_fin_Wh = np.zeros(8760)
    E_aux_solar_and_heat_recovery_Wh = np.zeros(8760)
    HPServerHeatDesignArray_kWh = np.zeros(8760)
    HPpvt_designArray_Wh = np.zeros(8760)
    HPCompAirDesignArray_kWh = np.zeros(8760)
    HPScDesignArray_Wh = np.zeros(8760)
    
    T_amb_K = 10 + 273.0 # K
    T_storage_min_K = master_to_slave_vars.T_ST_MAX
    Q_disc_seasonstart_W = [0]
    Q_loss_tot_W = 0
    
    while HOUR < 8760:
        # Store later on this data
        HPServerHeatDesign_kWh = 0
        HPpvt_design_Wh = 0
        HPCompAirDesign_kWh = 0
        HPScDesign_Wh = 0
        
        T_DH_sup_K = T_DH_supply_array_K[HOUR]
        T_DH_return_K = T_DH_return_array_K[HOUR]
        mdot_DH_kgpers = mdot_heat_netw_total_kgpers[HOUR]
        if master_to_slave_vars.WasteServersHeatRecovery == 1:
            Q_server_gen_kW = Q_wasteheatServer_kWh[HOUR]
        else:
            Q_server_gen_kW = 0

        # if MS_Var.WasteCompressorHeatRecovery == 1:
        #     Q_compair_gen_kW= Q_wasteheatCompAir_kWh[HOUR]
        # else:
        #     Q_compair_gen_kW = 0
        Q_SC_ET_gen_W = Q_SC_ET_gen_Wh[HOUR]
        Q_SC_FP_gen_W = Q_SC_FP_gen_Wh[HOUR]
        Q_PVT_gen_W = Q_PVT_gen_Wh[HOUR]
        
        # check if each source needs a heat-pump, calculate the final energy 
        if T_DH_sup_K > T_EL_TO_HEAT_SUP - DT_HEAT: #and checkpoint_ElToHeat == 1:
            #use a heat pump to bring it to distribution temp
            COP_th = T_DH_sup_K / (T_DH_sup_K - (T_EL_TO_HEAT_SUP - DT_HEAT))
            COP = HP_ETA_EX * COP_th
            E_aux_Server_kWh = Q_server_gen_kW * (1/COP) # assuming the losses occur after the heat pump
            if E_aux_Server_kWh > 0:
                HPServerHeatDesign_kWh = Q_server_gen_kW
                Q_server_gen_kW += E_aux_Server_kWh
        else:
            E_aux_Server_kWh = 0.0
            
        # if T_DH_sup_K > T_FROM_SERVER - DT_HEAT:# and checkpoint_QfromServer == 1:
        #     #use a heat pump to bring it to distribution temp
        #     COP_th = T_DH_sup_K / (T_DH_sup_K - (T_FROM_SERVER - DT_HEAT))
        #     COP = HP_ETA_EX * COP_th
        #     E_aux_CAH_kWh = Q_compair_gen_kW * (1/COP) # assuming the losses occur after the heat pump
        #     if E_aux_Server_kWh > 0:
        #         HPCompAirDesign_kWh = Q_compair_gen_kW
        #         Q_compair_gen_kW += E_aux_CAH_kWh
        # else:
        #     E_aux_CAH_kWh = 0.0
        #eliminating compressed air of the code
        E_aux_CAH_kWh =  0
        Q_compair_gen_kW = 0

        if T_DH_sup_K > Solar_Tscr_th_PVT_K[HOUR] - DT_HEAT:# and checkpoint_PVT == 1:
            #use a heat pump to bring it to distribution temp
            COP_th = T_DH_sup_K / (T_DH_sup_K - (Solar_Tscr_th_PVT_K[HOUR] - DT_HEAT))
            COP = HP_ETA_EX * COP_th
            E_aux_PVT_Wh = Q_PVT_gen_W * (1/COP) # assuming the losses occur after the heat pump
            if E_aux_PVT_Wh > 0:
                HPpvt_design_Wh = Q_PVT_gen_W
                Q_PVT_gen_W += E_aux_PVT_Wh
                
        else:
            E_aux_PVT_Wh = 0.0
            
        if T_DH_sup_K > Solar_Tscr_th_SC_ET_K[HOUR] - DT_HEAT:# and checkpoint_SC == 1:
            #use a heat pump to bring it to distribution temp
            COP_th = T_DH_sup_K / (T_DH_sup_K - (Solar_Tscr_th_SC_ET_K[HOUR] - DT_HEAT))
            COP = HP_ETA_EX * COP_th
            E_aux_SC_ET_Wh = Q_SC_ET_gen_W * (1/COP) # assuming the losses occur after the heat pump
            if E_aux_SC_ET_Wh > 0:
                HPScDesign_Wh = Q_SC_ET_gen_W
                Q_SC_ET_gen_W += E_aux_SC_ET_Wh
        else:  
            E_aux_SC_ET_Wh = 0.0

        if T_DH_sup_K > Solar_Tscr_th_SC_FP_K[HOUR] - DT_HEAT:# and checkpoint_SC == 1:
            #use a heat pump to bring it to distribution temp
            COP_th = T_DH_sup_K / (T_DH_sup_K - (Solar_Tscr_th_SC_FP_K[HOUR] - DT_HEAT))
            COP = HP_ETA_EX * COP_th
            E_aux_SC_FP_Wh = Q_SC_FP_gen_W * (1/COP) # assuming the losses occur after the heat pump
            if E_aux_SC_FP_Wh > 0:
                HPScDesign_Wh = Q_SC_FP_gen_W
                Q_SC_FP_gen_W += E_aux_SC_FP_Wh
        else:
            E_aux_SC_FP_Wh = 0.0
        
        
        HPServerHeatDesignArray_kWh[HOUR] = HPServerHeatDesign_kWh
        HPpvt_designArray_Wh[HOUR] = HPpvt_design_Wh
        HPCompAirDesignArray_kWh[HOUR] = HPCompAirDesign_kWh
        HPScDesignArray_Wh[HOUR] = HPScDesign_Wh
        
        
        E_aux_HP_uncontrollable_Wh = float(E_aux_SC_FP_Wh + E_aux_SC_ET_Wh + E_aux_PVT_Wh + E_aux_CAH_kWh + E_aux_Server_kWh)

        # Heat Recovery has some losses, these are taken into account as "overall Losses", i.e.: from Source to DH Pipe
        # hhhhhhhhhhhhhh GET VALUES
        Q_server_gen_W = Q_server_gen_kW * ETA_SERVER_TO_HEAT * 1000 # converting to W
        Q_compair_gen_W = Q_compair_gen_kW * ETA_EL_TO_HEAT * 1000


        Q_network_demand_W = Q_DH_networkload_W[HOUR]


        Storage_Data = SPH_fn.Storage_Operator(Q_PVT_gen_W, Q_SC_ET_gen_W, Q_SC_FP_gen_W, Q_server_gen_W, Q_compair_gen_W, Q_network_demand_W, T_storage_old_K, T_DH_sup_K, T_amb_K, \
                                               Q_in_storage_old_W, T_DH_return_K, mdot_DH_kgpers, STORAGE_SIZE_m3, master_to_slave_vars, P_HP_max_W, ground_temp[HOUR])
    
        Q_in_storage_new_W = Storage_Data[0]
        T_storage_new_K = Storage_Data[1]
        Q_to_storage_final_W = Storage_Data[3]
        Q_from_storage_req_final_W = Storage_Data[2]
        E_aux_ch_W = Storage_Data[4]
        E_aux_dech_W = Storage_Data[5]
        Q_missing_W = Storage_Data[6]
        Q_from_storage_used_fin_W[HOUR] = Storage_Data[7]
        Q_loss_tot_W += Storage_Data[8]
        mdot_DH_afterSto_kgpers = Storage_Data[9]
        Q_server_to_directload_W[HOUR] = Storage_Data[10]
        Q_server_to_storage_W[HOUR] = Storage_Data[11]
        Q_compair_to_directload_W[HOUR] = Storage_Data[12]
        Q_compair_to_storage_W[HOUR] = Storage_Data[13]
        Q_PVT_to_directload_W[HOUR] = Storage_Data[14]
        Q_PVT_to_storage_W[HOUR] = Storage_Data[15]
        Q_SC_ET_to_directload_W[HOUR] = Storage_Data[16]
        Q_SC_ET_to_storage_W[HOUR] = Storage_Data[17]
        Q_SC_FP_to_directload_W[HOUR] = Storage_Data[18]
        Q_SC_FP_to_storage_W[HOUR] = Storage_Data[19]
        
        if Q_in_storage_new_W < 0.0001:
            Q_in_storage_new_W = 0
    
        
        if T_storage_new_K >= master_to_slave_vars.T_ST_MAX-0.001: # no more charging possible - reject energy
            Q_in_storage_new_W = min(Q_in_storage_old_W, Storage_Data[0])
            Q_to_storage_final_W = max(Q_in_storage_new_W - Q_in_storage_old_W, 0)
            Q_rejected_fin_W[HOUR] = Q_PVT_gen_W + Q_SC_ET_gen_W + Q_SC_FP_gen_W + Q_compair_gen_W + Q_server_gen_W - Storage_Data[3]
            T_storage_new_K = min(T_storage_old_K, T_storage_new_K)
            E_aux_ch_W = 0

        Q_storage_content_fin_W[HOUR] = Q_in_storage_new_W
        Q_in_storage_old_W = Q_in_storage_new_W
        
        T_storage_fin_K[HOUR] = T_storage_new_K
        T_storage_old_K = T_storage_new_K
        
        if T_storage_old_K < T_amb_K-1: # chatch an error if the storage temperature is too low
            # print "ERROR!"
            break
        
        Q_from_storage_fin_W[HOUR] = Q_from_storage_req_final_W
        Q_to_storage_fin_W[HOUR] = Q_to_storage_final_W
        E_aux_ch_fin_W[HOUR] = E_aux_ch_W
        E_aux_dech_fin_W[HOUR] = E_aux_dech_W
        E_aux_solar_W[HOUR] = Solar_E_aux_W[HOUR]
        Q_uncontrollable_fin_Wh[HOUR] = Q_PVT_to_directload_W[HOUR] + Q_SC_ET_to_directload_W[HOUR] + Q_SC_FP_to_directload_W[HOUR] + Q_compair_to_directload_W[HOUR] + Q_server_to_directload_W[HOUR]

        Q_missing_fin_W[HOUR] = Q_network_demand_W - Q_uncontrollable_fin_Wh[HOUR] - Q_from_storage_used_fin_W[HOUR]

        E_aux_solar_and_heat_recovery_Wh[HOUR] = float(E_aux_HP_uncontrollable_Wh)
        mdot_DH_fin_kgpers[HOUR] = mdot_DH_afterSto_kgpers
        
        # Q_from_storage_fin_W[HOUR] = Q_DH_networkload_W[HOUR] - Q_missing_W
        
        if T_storage_new_K <= T_storage_min_K:
            T_storage_min_K = T_storage_new_K
            Q_disc_seasonstart_W[0] += Q_from_storage_req_final_W

        HOUR += 1
        
        
        """ STORE DATA """
    E_aux_solar_and_heat_recovery_flat_Wh = E_aux_solar_and_heat_recovery_Wh.flatten()
    # Calculate imported and exported Electricity Arrays:
    E_produced_total_W = np.zeros(8760)
    E_consumed_for_storage_solar_and_heat_recovery_W = np.zeros(8760)
    
    for hour in range(8760):
        E_produced_total_W[hour] = E_PV_Wh[hour] + E_PVT_Wh[hour]
        E_consumed_for_storage_solar_and_heat_recovery_W[hour] = E_aux_ch_fin_W[hour] + E_aux_dech_fin_W[hour] + E_aux_solar_and_heat_recovery_Wh[hour]


    if STORE_DATA == "yes":
        date = Network_Data.DATE.values
        results = pd.DataFrame(
            {"DATE": date,
             "Q_storage_content_W":Q_storage_content_fin_W,
             "Q_DH_networkload_W":Q_DH_networkload_W,
             "Q_uncontrollable_hot_W":Q_uncontrollable_fin_Wh,
             "Q_to_storage_W":Q_to_storage_fin_W,
             "Q_from_storage_used_W":Q_from_storage_used_fin_W,
             "Q_server_to_directload_W":Q_server_to_directload_W,
             "Q_server_to_storage_W":Q_server_to_storage_W,
             "Q_compair_to_directload_W":Q_compair_to_directload_W,
             "Q_compair_to_storage_W":Q_compair_to_storage_W,
             "Q_PVT_to_directload_W":Q_PVT_to_directload_W,
             "Q_PVT_to_storage_W": Q_PVT_to_storage_W,
             "Q_SC_ET_to_directload_W":Q_SC_ET_to_directload_W,
             "Q_SC_ET_to_storage_W":Q_SC_ET_to_storage_W,
             "Q_SC_FP_to_directload_W": Q_SC_FP_to_directload_W,
             "Q_SC_FP_to_storage_W": Q_SC_FP_to_storage_W,
             "E_aux_ch_W":E_aux_ch_fin_W,
             "E_aux_dech_W":E_aux_dech_fin_W,
             "Q_missing_W":Q_missing_fin_W,
             "mdot_DH_fin_kgpers":mdot_DH_fin_kgpers,
             "E_aux_solar_and_heat_recovery_Wh": E_aux_solar_and_heat_recovery_Wh,
             "E_consumed_for_storage_solar_and_heat_recovery_W": E_consumed_for_storage_solar_and_heat_recovery_W,
             "E_PV_Wh":E_PV_Wh,
             "E_PVT_Wh":E_PVT_Wh,
             "E_produced_from_solar_W": E_produced_total_W,
             "Storage_Size_m3":STORAGE_SIZE_m3,
             "Q_SC_ET_gen_Wh":Q_SC_ET_gen_Wh,
             "Q_SC_FP_gen_Wh": Q_SC_FP_gen_Wh,
             "Q_PVT_gen_Wh": Q_PVT_gen_Wh,
             "HPServerHeatDesignArray_kWh":HPServerHeatDesignArray_kWh,
             "HPpvt_designArray_Wh":HPpvt_designArray_Wh,
             "HPCompAirDesignArray_kWh":HPCompAirDesignArray_kWh,
             "HPScDesignArray_Wh":HPScDesignArray_Wh,
             "Q_rejected_fin_W":Q_rejected_fin_W,
             "P_HPCharge_max_W":P_HP_max_W
            })
        storage_operation_data_path = locator.get_optimization_slave_storage_operation_data(master_to_slave_vars.individual_number,
                                                                                            master_to_slave_vars.generation_number)
        results.to_csv(storage_operation_data_path, index=False)

    Q_stored_max_W = np.amax(Q_storage_content_fin_W)
    T_st_max_K = np.amax(T_storage_fin_K)
    T_st_min_K = np.amin(T_storage_fin_K)
        
    return Q_stored_max_W, Q_rejected_fin_W, Q_disc_seasonstart_W, T_st_max_K, T_st_min_K, Q_storage_content_fin_W, T_storage_fin_K, \
                                    Q_loss_tot_W, mdot_DH_fin_kgpers, Q_uncontrollable_fin_Wh
def disconnected_buildings_heating_main(locator, building_names, config,
                                        prices, lca):
    """
    Computes the parameters for the operation of disconnected buildings
    output results in csv files.
    There is no optimization at this point. The different technologies are calculated and compared 1 to 1 to
    each technology. it is a classical combinatorial problem.
    :param locator: locator class
    :param building_names: list with names of buildings
    :type locator: class
    :type building_names: list
    :return: results of operation of buildings located in locator.get_optimization_disconnected_folder
    :rtype: Nonetype
    """
    t0 = time.clock()
    prop_geometry = Gdf.from_file(locator.get_zone_geometry())
    restrictions = Gdf.from_file(locator.get_building_restrictions())

    geometry = pd.DataFrame({
        'Name': prop_geometry.Name,
        'Area': prop_geometry.area
    })
    geothermal_potential_data = dbf.dbf_to_dataframe(
        locator.get_building_supply())
    geothermal_potential_data = pd.merge(geothermal_potential_data,
                                         geometry,
                                         on='Name').merge(restrictions,
                                                          on='Name')
    geothermal_potential_data['Area_geo'] = (
        1 - geothermal_potential_data['GEOTHERMAL']
    ) * geothermal_potential_data['Area']
    weather_data = epwreader.epw_reader(config.weather)[[
        'year', 'drybulb_C', 'wetbulb_C', 'relhum_percent', 'windspd_ms',
        'skytemp_C'
    ]]
    ground_temp = calc_ground_temperature(locator,
                                          weather_data['drybulb_C'],
                                          depth_m=10)

    BestData = {}
    total_demand = pd.read_csv(locator.get_total_demand())

    def calc_new_load(mdot, TsupDH, Tret):
        """
        This function calculates the load distribution side of the district heating distribution.
        :param mdot: mass flow
        :param TsupDH: supply temeperature
        :param Tret: return temperature
        :param gv: global variables class
        :type mdot: float
        :type TsupDH: float
        :type Tret: float
        :type gv: class
        :return: Qload: load of the distribution
        :rtype: float
        """
        Qload = mdot * HEAT_CAPACITY_OF_WATER_JPERKGK * (TsupDH - Tret) * (
            1 + Q_LOSS_DISCONNECTED)
        if Qload < 0:
            Qload = 0

        return Qload

    for building_name in building_names:
        print building_name
        substation.substation_main(locator,
                                   total_demand,
                                   building_names=[building_name],
                                   heating_configuration=7,
                                   cooling_configuration=7,
                                   Flag=False)
        loads = pd.read_csv(
            locator.get_optimization_substations_results_file(building_name),
            usecols=[
                "T_supply_DH_result_K", "T_return_DH_result_K",
                "mdot_DH_result_kgpers"
            ])
        Qload = np.vectorize(calc_new_load)(loads["mdot_DH_result_kgpers"],
                                            loads["T_supply_DH_result_K"],
                                            loads["T_return_DH_result_K"])
        Qannual = Qload.sum()
        Qnom = Qload.max() * (1 + SIZING_MARGIN
                              )  # 1% reliability margin on installed capacity

        # Create empty matrices
        result = np.zeros((13, 7))
        result[0][0] = 1
        result[1][1] = 1
        result[2][2] = 1
        InvCosts = np.zeros((13, 1))
        resourcesRes = np.zeros((13, 4))
        QannualB_GHP = np.zeros(
            (10, 1))  # For the investment costs of the boiler used with GHP
        Wel_GHP = np.zeros((10, 1))  # For the investment costs of the GHP

        # Supply with the Boiler / FC / GHP
        Tret = loads["T_return_DH_result_K"].values
        TsupDH = loads["T_supply_DH_result_K"].values
        mdot = loads["mdot_DH_result_kgpers"].values

        for hour in range(8760):

            if Tret[hour] == 0:
                Tret[hour] = TsupDH[hour]

            # Boiler NG
            BoilerEff = Boiler.calc_Cop_boiler(Qload[hour], Qnom, Tret[hour])

            Qgas = Qload[hour] / BoilerEff

            result[0][4] += prices.NG_PRICE * Qgas  # CHF
            result[0][
                5] += lca.NG_BACKUPBOILER_TO_CO2_STD * Qgas * 3600E-6  # kgCO2
            result[0][
                6] += lca.NG_BACKUPBOILER_TO_OIL_STD * Qgas * 3600E-6  # MJ-oil-eq
            resourcesRes[0][0] += Qload[hour]

            if DISC_BIOGAS_FLAG == 1:
                result[0][4] += prices.BG_PRICE * Qgas  # CHF
                result[0][
                    5] += lca.BG_BACKUPBOILER_TO_CO2_STD * Qgas * 3600E-6  # kgCO2
                result[0][
                    6] += lca.BG_BACKUPBOILER_TO_OIL_STD * Qgas * 3600E-6  # MJ-oil-eq

            # Boiler BG
            result[1][4] += prices.BG_PRICE * Qgas  # CHF
            result[1][
                5] += lca.BG_BACKUPBOILER_TO_CO2_STD * Qgas * 3600E-6  # kgCO2
            result[1][
                6] += lca.BG_BACKUPBOILER_TO_OIL_STD * Qgas * 3600E-6  # MJ-oil-eq
            resourcesRes[1][1] += Qload[hour]

            # FC
            (FC_Effel, FC_Effth) = FC.calc_eta_FC(Qload[hour], Qnom, 1, "B")
            Qgas = Qload[hour] / (FC_Effth + FC_Effel)
            Qelec = Qgas * FC_Effel

            result[2][
                4] += prices.NG_PRICE * Qgas - lca.ELEC_PRICE * Qelec  # CHF, extra electricity sold to grid
            result[2][
                5] += 0.0874 * Qgas * 3600E-6 + 773 * 0.45 * Qelec * 1E-6 - lca.EL_TO_CO2 * Qelec * 3600E-6  # kgCO2
            # Bloom box emissions within the FC: 773 lbs / MWh_el (and 1 lbs = 0.45 kg)
            # http://www.carbonlighthouse.com/2011/09/16/bloom-box/
            result[2][
                6] += 1.51 * Qgas * 3600E-6 - lca.EL_TO_OIL_EQ * Qelec * 3600E-6  # MJ-oil-eq

            resourcesRes[2][0] += Qload[hour]
            resourcesRes[2][2] += Qelec

            # GHP
            for i in range(10):

                QnomBoiler = i / 10 * Qnom
                QnomGHP = Qnom - QnomBoiler

                if Qload[hour] <= QnomGHP:
                    (wdot_el, qcolddot, qhotdot_missing,
                     tsup2) = HP.calc_Cop_GHP(ground_temp[hour], mdot[hour],
                                              TsupDH[hour], Tret[hour])

                    if Wel_GHP[i][0] < wdot_el:
                        Wel_GHP[i][0] = wdot_el

                    result[3 + i][4] += lca.ELEC_PRICE * wdot_el  # CHF
                    result[3 + i][
                        5] += lca.SMALL_GHP_TO_CO2_STD * wdot_el * 3600E-6  # kgCO2
                    result[3 + i][
                        6] += lca.SMALL_GHP_TO_OIL_STD * wdot_el * 3600E-6  # MJ-oil-eq

                    resourcesRes[3 + i][2] -= wdot_el
                    resourcesRes[3 + i][3] += Qload[hour] - qhotdot_missing

                    if qhotdot_missing > 0:
                        print "GHP unable to cover the whole demand, boiler activated!"
                        BoilerEff = Boiler.calc_Cop_boiler(
                            qhotdot_missing, QnomBoiler, tsup2)
                        Qgas = qhotdot_missing / BoilerEff

                        result[3 + i][4] += prices.NG_PRICE * Qgas  # CHF
                        result[3 + i][
                            5] += lca.NG_BACKUPBOILER_TO_CO2_STD * Qgas * 3600E-6  # kgCO2
                        result[3 + i][
                            6] += lca.NG_BACKUPBOILER_TO_OIL_STD * Qgas * 3600E-6  # MJ-oil-eq

                        QannualB_GHP[i][0] += qhotdot_missing
                        resourcesRes[3 + i][0] += qhotdot_missing

                else:
                    # print "Boiler activated to compensate GHP", i
                    # if gv.DiscGHPFlag == 0:
                    #    print QnomGHP
                    #   QnomGHP = 0
                    #   print "GHP not allowed 2, set QnomGHP to zero"

                    TexitGHP = QnomGHP / (
                        mdot[hour] *
                        HEAT_CAPACITY_OF_WATER_JPERKGK) + Tret[hour]
                    (wdot_el, qcolddot, qhotdot_missing,
                     tsup2) = HP.calc_Cop_GHP(ground_temp[hour], mdot[hour],
                                              TexitGHP, Tret[hour])

                    if Wel_GHP[i][0] < wdot_el:
                        Wel_GHP[i][0] = wdot_el

                    result[3 + i][4] += lca.ELEC_PRICE * wdot_el  # CHF
                    result[3 + i][
                        5] += lca.SMALL_GHP_TO_CO2_STD * wdot_el * 3600E-6  # kgCO2
                    result[3 + i][
                        6] += lca.SMALL_GHP_TO_OIL_STD * wdot_el * 3600E-6  # MJ-oil-eq

                    resourcesRes[3 + i][2] -= wdot_el
                    resourcesRes[3 + i][3] += QnomGHP - qhotdot_missing

                    if qhotdot_missing > 0:
                        print "GHP unable to cover the whole demand, boiler activated!"
                        BoilerEff = Boiler.calc_Cop_boiler(
                            qhotdot_missing, QnomBoiler, tsup2)
                        Qgas = qhotdot_missing / BoilerEff

                        result[3 + i][4] += prices.NG_PRICE * Qgas  # CHF
                        result[3 + i][
                            5] += lca.NG_BACKUPBOILER_TO_CO2_STD * Qgas * 3600E-6  # kgCO2
                        result[3 + i][
                            6] += lca.NG_BACKUPBOILER_TO_OIL_STD * Qgas * 3600E-6  # MJ-oil-eq

                        QannualB_GHP[i][0] += qhotdot_missing
                        resourcesRes[3 + i][0] += qhotdot_missing

                    QtoBoiler = Qload[hour] - QnomGHP
                    QannualB_GHP[i][0] += QtoBoiler

                    BoilerEff = Boiler.calc_Cop_boiler(QtoBoiler, QnomBoiler,
                                                       TexitGHP)
                    Qgas = QtoBoiler / BoilerEff

                    result[3 + i][4] += prices.NG_PRICE * Qgas  # CHF
                    result[3 + i][
                        5] += lca.NG_BACKUPBOILER_TO_CO2_STD * Qgas * 3600E-6  # kgCO2
                    result[3 + i][
                        6] += lca.NG_BACKUPBOILER_TO_OIL_STD * Qgas * 3600E-6  # MJ-oil-eq
                    resourcesRes[3 + i][0] += QtoBoiler

        # Investment Costs / CO2 / Prim
        Capex_a_Boiler, Opex_Boiler = Boiler.calc_Cinv_boiler(
            Qnom, locator, config, 'BO1')
        InvCosts[0][0] = Capex_a_Boiler + Opex_Boiler
        InvCosts[1][0] = Capex_a_Boiler + Opex_Boiler

        Capex_a_FC, Opex_FC = FC.calc_Cinv_FC(Qnom, locator, config)
        InvCosts[2][0] = Capex_a_FC + Opex_FC

        for i in range(10):
            result[3 + i][0] = i / 10
            result[3 + i][3] = 1 - i / 10

            QnomBoiler = i / 10 * Qnom

            Capex_a_Boiler, Opex_Boiler = Boiler.calc_Cinv_boiler(
                QnomBoiler, locator, config, 'BO1')

            InvCosts[3 + i][0] = Capex_a_Boiler + Opex_Boiler

            Capex_a_GHP, Opex_GHP = HP.calc_Cinv_GHP(Wel_GHP[i][0], locator,
                                                     config)
            InvCaGHP = Capex_a_GHP + Opex_GHP
            InvCosts[3 + i][0] += InvCaGHP * prices.EURO_TO_CHF

        # Best configuration
        Best = np.zeros((13, 1))
        indexBest = 0

        TotalCosts = np.zeros((13, 2))
        TotalCO2 = np.zeros((13, 2))
        TotalPrim = np.zeros((13, 2))

        for i in range(13):
            TotalCosts[i][0] = TotalCO2[i][0] = TotalPrim[i][0] = i

            TotalCosts[i][1] = InvCosts[i][0] + result[i][4]
            TotalCO2[i][1] = result[i][5]
            TotalPrim[i][1] = result[i][6]

        CostsS = TotalCosts[np.argsort(TotalCosts[:, 1])]
        CO2S = TotalCO2[np.argsort(TotalCO2[:, 1])]
        PrimS = TotalPrim[np.argsort(TotalPrim[:, 1])]

        el = len(CostsS)
        rank = 0
        Bestfound = False

        optsearch = np.empty(el)
        optsearch.fill(3)
        indexBest = 0
        geothermal_potential = geothermal_potential_data.set_index('Name')

        # Check the GHP area constraint
        for i in range(10):
            QGHP = (1 - i / 10) * Qnom
            areaAvail = geothermal_potential.ix[building_name, 'Area_geo']
            Qallowed = np.ceil(areaAvail / GHP_A) * GHP_HMAX_SIZE  # [W_th]
            if Qallowed < QGHP:
                optsearch[i + 3] += 1
                Best[i + 3][0] = -1

        while not Bestfound and rank < el:

            optsearch[int(CostsS[rank][0])] -= 1
            optsearch[int(CO2S[rank][0])] -= 1
            optsearch[int(PrimS[rank][0])] -= 1

            if np.count_nonzero(optsearch) != el:
                Bestfound = True
                indexBest = np.where(optsearch == 0)[0][0]

            rank += 1

        # get the best option according to the ranking.
        Best[indexBest][0] = 1
        Qnom_array = np.ones(len(Best[:, 0])) * Qnom

        # Save results in csv file
        dico = {}
        dico["BoilerNG Share"] = result[:, 0]
        dico["BoilerBG Share"] = result[:, 1]
        dico["FC Share"] = result[:, 2]
        dico["GHP Share"] = result[:, 3]
        dico["Operation Costs [CHF]"] = result[:, 4]
        dico["CO2 Emissions [kgCO2-eq]"] = result[:, 5]
        dico["Primary Energy Needs [MJoil-eq]"] = result[:, 6]
        dico["Annualized Investment Costs [CHF]"] = InvCosts[:, 0]
        dico["Total Costs [CHF]"] = TotalCosts[:, 1]
        dico["Best configuration"] = Best[:, 0]
        dico["Nominal Power"] = Qnom_array
        dico["QfromNG"] = resourcesRes[:, 0]
        dico["QfromBG"] = resourcesRes[:, 1]
        dico["EforGHP"] = resourcesRes[:, 2]
        dico["QfromGHP"] = resourcesRes[:, 3]

        results_to_csv = pd.DataFrame(dico)

        fName_result = locator.get_optimization_disconnected_folder_building_result_heating(
            building_name)
        results_to_csv.to_csv(fName_result, sep=',')

        BestComb = {}
        BestComb["BoilerNG Share"] = result[indexBest, 0]
        BestComb["BoilerBG Share"] = result[indexBest, 1]
        BestComb["FC Share"] = result[indexBest, 2]
        BestComb["GHP Share"] = result[indexBest, 3]
        BestComb["Operation Costs [CHF]"] = result[indexBest, 4]
        BestComb["CO2 Emissions [kgCO2-eq]"] = result[indexBest, 5]
        BestComb["Primary Energy Needs [MJoil-eq]"] = result[indexBest, 6]
        BestComb["Annualized Investment Costs [CHF]"] = InvCosts[indexBest, 0]
        BestComb["Total Costs [CHF]"] = TotalCosts[indexBest, 1]
        BestComb["Best configuration"] = Best[indexBest, 0]
        BestComb["Nominal Power"] = Qnom

        BestData[building_name] = BestComb

    if 0:
        fName = locator.get_optimization_disconnected_folder_disc_op_summary_heating(
        )
        results_to_csv = pd.DataFrame(BestData)
        results_to_csv.to_csv(fName, sep=',')

    print time.clock(
    ) - t0, "seconds process time for the Disconnected Building Routine \n"
Example #15
0
def least_cost_main(locator, master_to_slave_vars, solar_features, gv, prices, lca, config):
    """
    This function runs the least cost optimization code and returns cost, co2 and primary energy required. \
    On the go, it saves the operation pattern

    :param locator: locator class
    :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: solar features class
    :param gv: global variables class
    :type locator: class
    :type master_to_slave_vars: class
    :type solar_features: class
    :type gv: 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

    """

    MS_Var = master_to_slave_vars

    t = time.time()

    # Import data from storage optimization
    centralized_plant_data = pd.read_csv(
        locator.get_optimization_slave_storage_operation_data(MS_Var.individual_number,
                                                              MS_Var.generation_number))
    Q_DH_networkload_W = np.array(centralized_plant_data['Q_DH_networkload_W'])
    E_aux_ch_W = np.array(centralized_plant_data['E_aux_ch_W'])
    E_aux_dech_W = np.array(centralized_plant_data['E_aux_dech_W'])
    Q_missing_W = np.array(centralized_plant_data['Q_missing_W'])
    Q_storage_content_W = np.array(centralized_plant_data['Q_storage_content_W'])
    Q_to_storage_W = np.array(centralized_plant_data['Q_to_storage_W'])
    Q_from_storage_W = np.array(centralized_plant_data['Q_from_storage_used_W'])
    Q_uncontrollable_W = np.array(centralized_plant_data['Q_uncontrollable_hot_W'])
    E_PV_gen_W = np.array(centralized_plant_data['E_PV_Wh'])
    E_PVT_gen_W = np.array(centralized_plant_data['E_PVT_Wh'])
    E_aux_solar_and_heat_recovery_W = np.array(centralized_plant_data['E_aux_solar_and_heat_recovery_Wh'])
    Q_SC_ET_gen_Wh = np.array(centralized_plant_data['Q_SC_ET_gen_Wh'])
    Q_SC_FP_gen_Wh = np.array(centralized_plant_data['Q_SC_FP_gen_Wh'])
    Q_PVT_gen_Wh = np.array(centralized_plant_data['Q_PVT_gen_Wh'])
    Q_SCandPVT_gen_Wh = Q_SC_ET_gen_Wh + Q_SC_FP_gen_Wh + Q_PVT_gen_Wh
    E_produced_solar_W = np.array(centralized_plant_data['E_produced_from_solar_W'])

    # Q_StorageToDHNpipe_sum = np.sum(E_aux_dech_W) + np.sum(Q_from_storage_W)
    #
    # HP_operation_Data_sum_array = np.sum(HPServerHeatDesignArray_kWh), \
    #                               np.sum(HPpvt_designArray_Wh), \
    #                               np.sum(HPCompAirDesignArray_kWh), \
    #                               np.sum(HPScDesignArray_Wh)

    Q_missing_copy_W = Q_missing_W.copy()

    # Import Temperatures from Network Summary:
    network_data = pd.read_csv(locator.get_optimization_network_data_folder(MS_Var.network_data_file_heating))
    tdhret_K = network_data['T_DHNf_re_K']

    mdot_DH_kgpers = network_data['mdot_DH_netw_total_kgpers']
    tdhsup_K = network_data['T_DHNf_sup_K']
    # import Marginal Cost of PP Data :
    # os.chdir(Cost_Maps_Path)

    # FIXED ORDER ACTIVATION STARTS
    # Import Data - Sewage
    if HP_SEW_ALLOWED == 1:
        HPSew_Data = pd.read_csv(locator.get_sewage_heat_potential())
        QcoldsewArray = np.array(HPSew_Data['Qsw_kW']) * 1E3
        TretsewArray_K = np.array(HPSew_Data['ts_C']) + 273

    # Initiation of the variables
    Opex_var_HP_Sewage = []
    Opex_var_HP_Lake = []
    Opex_var_GHP = []
    Opex_var_CHP = []
    Opex_var_Furnace = []
    Opex_var_BaseBoiler = []
    Opex_var_PeakBoiler = []

    source_HP_Sewage = []
    source_HP_Lake = []
    source_GHP = []
    source_CHP = []
    source_Furnace = []
    source_BaseBoiler = []
    source_PeakBoiler = []

    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_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_HPSew_W = []
    E_gas_HPLake_W = []
    E_gas_GHP_W = []
    E_gas_CHP_W = []
    E_gas_Furnace_W = []
    E_gas_BaseBoiler_W = []
    E_gas_PeakBoiler_W = []

    E_wood_HPSew_W = []
    E_wood_HPLake_W = []
    E_wood_GHP_W = []
    E_wood_CHP_W = []
    E_wood_Furnace_W = []
    E_wood_BaseBoiler_W = []
    E_wood_PeakBoiler_W = []

    E_coldsource_HPSew_W = []
    E_coldsource_HPLake_W = []
    E_coldsource_GHP_W = []
    E_coldsource_CHP_W = []
    E_coldsource_Furnace_W = []
    E_coldsource_BaseBoiler_W = []
    E_coldsource_PeakBoiler_W = []

    Q_excess_W = np.zeros(8760)
    weather_data = epwreader.epw_reader(config.weather)[['year', 'drybulb_C', 'wetbulb_C','relhum_percent',
                                                              'windspd_ms', 'skytemp_C']]
    ground_temp = calc_ground_temperature(locator, weather_data['drybulb_C'], depth_m=10)

    weather_data = epwreader.epw_reader(config.weather)[['year', 'drybulb_C', 'wetbulb_C',
                                                         'relhum_percent', 'windspd_ms', 'skytemp_C']]
    ground_temp = calc_ground_temperature(locator, weather_data['drybulb_C'], depth_m=10)

    for hour in range(8760):
        Q_therm_req_W = Q_missing_W[hour]
        # cost_data_centralPlant_op[hour, :], source_info[hour, :], Q_source_data_W[hour, :], E_coldsource_data_W[hour,
        #                                                                                     :], \
        # E_PP_el_data_W[hour, :], E_gas_data_W[hour, :], E_wood_data_W[hour, :], Q_excess_W[hour] = source_activator(
        #     Q_therm_req_W, hour, master_to_slave_vars, mdot_DH_kgpers[hour], tdhsup_K,
        #     tdhret_K[hour], TretsewArray_K[hour], gv, prices)
        opex_output, source_output, Q_output, E_output, Gas_output, Wood_output, coldsource_output, Q_excess_W[
            hour] = heating_source_activator(
            Q_therm_req_W, hour, master_to_slave_vars, mdot_DH_kgpers[hour], tdhsup_K[hour],
            tdhret_K[hour], TretsewArray_K[hour], gv, prices, lca, ground_temp[hour])

        Opex_var_HP_Sewage.append(opex_output['Opex_var_HP_Sewage'])
        Opex_var_HP_Lake.append(opex_output['Opex_var_HP_Lake'])
        Opex_var_GHP.append(opex_output['Opex_var_GHP'])
        Opex_var_CHP.append(opex_output['Opex_var_CHP'])
        Opex_var_Furnace.append(opex_output['Opex_var_Furnace'])
        Opex_var_BaseBoiler.append(opex_output['Opex_var_BaseBoiler'])
        Opex_var_PeakBoiler.append(opex_output['Opex_var_PeakBoiler'])

        source_HP_Sewage.append(source_output['HP_Sewage'])
        source_HP_Lake.append(source_output['HP_Lake'])
        source_GHP.append(source_output['GHP'])
        source_CHP.append(source_output['CHP'])
        source_Furnace.append(source_output['Furnace'])
        source_BaseBoiler.append(source_output['BaseBoiler'])
        source_PeakBoiler.append(source_output['PeakBoiler'])

        Q_HPSew_gen_W.append(Q_output['Q_HPSew_gen_W'])
        Q_HPLake_gen_W.append(Q_output['Q_HPLake_gen_W'])
        Q_GHP_gen_W.append(Q_output['Q_GHP_gen_W'])
        Q_CHP_gen_W.append(Q_output['Q_CHP_gen_W'])
        Q_Furnace_gen_W.append(Q_output['Q_Furnace_gen_W'])
        Q_BaseBoiler_gen_W.append(Q_output['Q_BaseBoiler_gen_W'])
        Q_PeakBoiler_gen_W.append(Q_output['Q_PeakBoiler_gen_W'])
        Q_uncovered_W.append(Q_output['Q_uncovered_W'])

        E_HPSew_req_W.append(E_output['E_HPSew_req_W'])
        E_HPLake_req_W.append(E_output['E_HPLake_req_W'])
        E_GHP_req_W.append(E_output['E_GHP_req_W'])
        E_CHP_gen_W.append(E_output['E_CHP_gen_W'])
        E_Furnace_gen_W.append(E_output['E_Furnace_gen_W'])
        E_BaseBoiler_req_W.append(E_output['E_BaseBoiler_req_W'])
        E_PeakBoiler_req_W.append(E_output['E_PeakBoiler_req_W'])

        E_gas_HPSew_W.append(Gas_output['E_gas_HPSew_W'])
        E_gas_HPLake_W.append(Gas_output['E_gas_HPLake_W'])
        E_gas_GHP_W.append(Gas_output['E_gas_GHP_W'])
        E_gas_CHP_W.append(Gas_output['E_gas_CHP_W'])
        E_gas_Furnace_W.append(Gas_output['E_gas_Furnace_W'])
        E_gas_BaseBoiler_W.append(Gas_output['E_gas_BaseBoiler_W'])
        E_gas_PeakBoiler_W.append(Gas_output['E_gas_PeakBoiler_W'])

        E_wood_HPSew_W.append(Wood_output['E_wood_HPSew_W'])
        E_wood_HPLake_W.append(Wood_output['E_wood_HPLake_W'])
        E_wood_GHP_W.append(Wood_output['E_wood_GHP_W'])
        E_wood_CHP_W.append(Wood_output['E_wood_CHP_W'])
        E_wood_Furnace_W.append(Wood_output['E_wood_Furnace_W'])
        E_wood_BaseBoiler_W.append(Wood_output['E_wood_BaseBoiler_W'])
        E_wood_PeakBoiler_W.append(Wood_output['E_wood_PeakBoiler_W'])

        E_coldsource_HPSew_W.append(coldsource_output['E_coldsource_HPSew_W'])
        E_coldsource_HPLake_W.append(coldsource_output['E_coldsource_HPLake_W'])
        E_coldsource_GHP_W.append(coldsource_output['E_coldsource_GHP_W'])
        E_coldsource_CHP_W.append(coldsource_output['E_coldsource_CHP_W'])
        E_coldsource_Furnace_W.append(coldsource_output['E_coldsource_Furnace_W'])
        E_coldsource_BaseBoiler_W.append(coldsource_output['E_coldsource_BaseBoiler_W'])
        E_coldsource_PeakBoiler_W.append(coldsource_output['E_coldsource_PeakBoiler_W'])

    # save data

    elapsed = time.time() - t
    # sum up the uncovered demand, get average and peak load
    Q_uncovered_design_W = np.amax(Q_uncovered_W)
    Q_uncovered_annual_W = np.sum(Q_uncovered_W)
    Opex_var_BackupBoiler = np.zeros(8760)
    Q_BackupBoiler_W = np.zeros(8760)
    E_aux_AddBoiler_req_W = []

    Opex_var_Furnace_wet = np.zeros(8760)
    Opex_var_Furnace_dry = np.zeros(8760)
    Opex_var_CHP_NG = np.zeros(8760)
    Opex_var_CHP_BG = np.zeros(8760)
    Opex_var_BaseBoiler_NG = np.zeros(8760)
    Opex_var_BaseBoiler_BG = np.zeros(8760)
    Opex_var_PeakBoiler_NG = np.zeros(8760)
    Opex_var_PeakBoiler_BG = np.zeros(8760)
    Opex_var_BackupBoiler_NG = np.zeros(8760)
    Opex_var_BackupBoiler_BG = np.zeros(8760)

    Opex_var_PV = np.zeros(8760)
    Opex_var_PVT = np.zeros(8760)
    Opex_var_SC = np.zeros(8760)

    if Q_uncovered_design_W != 0:
        for hour in range(8760):
            tdhret_req_K = tdhret_K[hour]
            BoilerBackup_Cost_Data = cond_boiler_op_cost(Q_uncovered_W[hour], Q_uncovered_design_W, tdhret_req_K, \
                                                         master_to_slave_vars.BoilerBackupType,
                                                         master_to_slave_vars.EL_TYPE, gv, prices, lca)
            Opex_var_BackupBoiler[hour], C_boil_per_WhBackup, Q_BackupBoiler_W[
                hour], E_aux_AddBoiler_req_W_hour = BoilerBackup_Cost_Data
            E_aux_AddBoiler_req_W.append(E_aux_AddBoiler_req_W_hour)
        Q_BackupBoiler_sum_W = np.sum(Q_BackupBoiler_W)
        Opex_var_BackupBoiler_total = np.sum(Opex_var_BackupBoiler)

    else:
        for hour in range(8760):
            E_aux_AddBoiler_req_W.append(0)
        Q_BackupBoiler_sum_W = 0.0
        Opex_var_BackupBoiler_total = 0.0

    if master_to_slave_vars.Furn_Moist_type == "wet":
        Opex_var_Furnace_wet = Opex_var_Furnace
    elif master_to_slave_vars.Furn_Moist_type == "dry":
        Opex_var_Furnace_dry = Opex_var_Furnace

    if master_to_slave_vars.gt_fuel == "NG":
        Opex_var_CHP_NG = Opex_var_CHP
        Opex_var_BaseBoiler_NG = Opex_var_BaseBoiler
        Opex_var_PeakBoiler_NG = Opex_var_PeakBoiler
        Opex_var_BackupBoiler_NG = Opex_var_BackupBoiler

    elif master_to_slave_vars.gt_fuel == "BG":
        Opex_var_CHP_BG = Opex_var_CHP
        Opex_var_BaseBoiler_BG = Opex_var_BaseBoiler
        Opex_var_PeakBoiler_BG = Opex_var_PeakBoiler
        Opex_var_BackupBoiler_BG = Opex_var_BackupBoiler

    # Sum up all electricity needs
    intermediate_sum_1 = np.add(E_HPSew_req_W, E_HPLake_req_W)
    intermediate_sum_2 = np.add(E_GHP_req_W, E_BaseBoiler_req_W)
    intermediate_sum_3 = np.add(E_PeakBoiler_req_W, E_aux_AddBoiler_req_W)
    intermediate_sum_4 = np.add(intermediate_sum_1, intermediate_sum_2)
    E_aux_activation_req_W = np.add(intermediate_sum_3, intermediate_sum_4)
    E_aux_storage_solar_and_heat_recovery_req_W = np.add(np.add(E_aux_ch_W, E_aux_dech_W),
                                                         E_aux_solar_and_heat_recovery_W)

    # Sum up all electricity produced by CHP (CC and Furnace)
    # cost already accounted for in System Models (selling electricity --> cheaper thermal energy)
    E_CHP_and_Furnace_gen_W = np.add(E_CHP_gen_W, E_Furnace_gen_W)
    # price from PV and PVT electricity (both are in E_PV_Wh, see Storage_Design_and..., about Line 133)
    E_solar_gen_W = np.add(E_PV_gen_W, E_PVT_gen_W)
    E_total_gen_W = np.add(E_produced_solar_W, E_CHP_and_Furnace_gen_W)
    E_without_buildingdemand_req_W = np.add(E_aux_storage_solar_and_heat_recovery_req_W, E_aux_activation_req_W)

    E_total_req_W = np.add(np.array(network_data['Electr_netw_total_W']), E_without_buildingdemand_req_W)

    E_PV_to_grid_W = np.zeros(8760)
    E_PVT_to_grid_W = np.zeros(8760)
    E_CHP_to_grid_W = np.zeros(8760)
    E_Furnace_to_grid_W = np.zeros(8760)
    E_PV_directload_W = np.zeros(8760)
    E_PVT_directload_W = np.zeros(8760)
    E_CHP_directload_W = np.zeros(8760)
    E_Furnace_directload_W = np.zeros(8760)
    E_from_grid_W = np.zeros(8760)

    for hour in range(8760):
        E_hour_W = E_total_req_W[hour]

        if E_PV_gen_W[hour] <= E_hour_W:
            E_PV_directload_W[hour] = E_PV_gen_W[hour]
            E_hour_W = E_hour_W - E_PV_directload_W[hour]
        else:
            E_PV_directload_W[hour] = E_hour_W
            E_PV_to_grid_W[hour] = E_PV_gen_W[hour] - E_hour_W
            E_hour_W = 0

        if E_PVT_gen_W[hour] <= E_hour_W:
            E_PVT_directload_W[hour] = E_PVT_gen_W[hour]
            E_hour_W = E_hour_W - E_PVT_directload_W[hour]
        else:
            E_PVT_directload_W[hour] = E_hour_W
            E_PVT_to_grid_W[hour] = E_PVT_gen_W[hour] - E_hour_W
            E_hour_W = 0

        if E_CHP_gen_W[hour] <= E_hour_W:
            E_CHP_directload_W[hour] = E_CHP_gen_W[hour]
            E_hour_W = E_hour_W - E_CHP_directload_W[hour]
        else:
            E_CHP_directload_W[hour] = E_hour_W
            E_CHP_to_grid_W[hour] = E_CHP_gen_W[hour] - E_hour_W
            E_hour_W = 0

        if E_Furnace_gen_W[hour] <= E_hour_W:
            E_Furnace_directload_W[hour] = E_Furnace_gen_W[hour]
            E_hour_W = E_hour_W - E_Furnace_directload_W[hour]
        else:
            E_Furnace_directload_W[hour] = E_hour_W
            E_Furnace_to_grid_W[hour] = E_Furnace_gen_W[hour] - E_hour_W
            E_hour_W = 0

        E_from_grid_W[hour] = E_hour_W

    # saving pattern activation to disk
    date = network_data.DATE.values
    results = pd.DataFrame({"DATE": date,
                            "Q_Network_Demand_after_Storage_W": Q_missing_copy_W,
                            "Opex_var_HP_Sewage": Opex_var_HP_Sewage,
                            "Opex_var_HP_Lake": Opex_var_HP_Lake,
                            "Opex_var_GHP": Opex_var_GHP,
                            "Opex_var_CHP_BG": Opex_var_CHP_BG,
                            "Opex_var_CHP_NG": Opex_var_CHP_NG,
                            "Opex_var_Furnace_wet": Opex_var_Furnace_wet,
                            "Opex_var_Furnace_dry": Opex_var_Furnace_dry,
                            "Opex_var_BaseBoiler_BG": Opex_var_BaseBoiler_BG,
                            "Opex_var_BaseBoiler_NG": Opex_var_BaseBoiler_NG,
                            "Opex_var_PeakBoiler_BG": Opex_var_PeakBoiler_BG,
                            "Opex_var_PeakBoiler_NG": Opex_var_PeakBoiler_NG,
                            "Opex_var_BackupBoiler_BG": Opex_var_BackupBoiler_BG,
                            "Opex_var_BackupBoiler_NG": Opex_var_BackupBoiler_NG,
                            "HPSew_Status": source_HP_Sewage,
                            "HPLake_Status": source_HP_Lake,
                            "GHP_Status": source_GHP,
                            "CHP_Status": source_CHP,
                            "Furnace_Status": source_Furnace,
                            "BoilerBase_Status": source_BaseBoiler,
                            "BoilerPeak_Status": source_PeakBoiler,
                            "Q_HPSew_W": Q_HPSew_gen_W,
                            "Q_HPLake_W": Q_HPLake_gen_W,
                            "Q_GHP_W": Q_GHP_gen_W,
                            "Q_CHP_W": Q_CHP_gen_W,
                            "Q_Furnace_W": Q_Furnace_gen_W,
                            "Q_BaseBoiler_W": Q_BaseBoiler_gen_W,
                            "Q_PeakBoiler_W": Q_PeakBoiler_gen_W,
                            "Q_AddBoiler_W": Q_uncovered_W,
                            "Q_coldsource_HPLake_W": E_coldsource_HPLake_W,
                            "Q_coldsource_HPSew_W": E_coldsource_HPSew_W,
                            "Q_coldsource_GHP_W": E_coldsource_GHP_W,
                            "Q_coldsource_CHP_W": E_coldsource_CHP_W,
                            "Q_coldsource_Furnace_W": E_coldsource_Furnace_W,
                            "Q_coldsource_BaseBoiler_W": E_coldsource_BaseBoiler_W,
                            "Q_coldsource_PeakBoiler_W": E_coldsource_PeakBoiler_W,
                            "Q_excess_W": Q_excess_W
                            })

    results.to_csv(locator.get_optimization_slave_heating_activation_pattern(MS_Var.individual_number,
                                                                             MS_Var.generation_number), index=False)

    results = pd.DataFrame({"DATE": date,
                            "E_total_req_W": E_total_req_W,
                            "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,
                            "E_AddBoiler_req_W": E_aux_AddBoiler_req_W,
                            "E_PV_gen_W": E_PV_gen_W,
                            "E_PVT_gen_W": E_PVT_gen_W,
                            "E_CHP_and_Furnace_gen_W": E_CHP_and_Furnace_gen_W,
                            "E_gen_total_W": E_total_gen_W,
                            "E_PV_to_directload_W": E_PV_directload_W,
                            "E_PVT_to_directload_W": E_PVT_directload_W,
                            "E_CHP_to_directload_W": E_CHP_directload_W,
                            "E_Furnace_to_directload_W": E_Furnace_directload_W,
                            "E_PV_to_grid_W": E_PV_to_grid_W,
                            "E_PVT_to_grid_W": E_PVT_to_grid_W,
                            "E_CHP_to_grid_W": E_CHP_to_grid_W,
                            "E_Furnace_to_grid_W": E_Furnace_to_grid_W,
                            "E_aux_storage_solar_and_heat_recovery_req_W": E_aux_storage_solar_and_heat_recovery_req_W,
                            "E_consumed_without_buildingdemand_W": E_without_buildingdemand_req_W,
                            "E_from_grid_W": E_from_grid_W
                            })

    results.to_csv(locator.get_optimization_slave_electricity_activation_pattern_heating(MS_Var.individual_number,
                                                                                         MS_Var.generation_number), index=False)

    E_aux_storage_operation_sum_W = np.sum(E_aux_storage_solar_and_heat_recovery_req_W)
    E_aux_solar_and_heat_recovery_W = np.sum(E_aux_solar_and_heat_recovery_W)

    CO2_emitted, Eprim_used = calc_primary_energy_and_CO2(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_coldsource_HPSew_W, E_coldsource_HPLake_W,
                                                          E_coldsource_GHP_W,
                                                          E_CHP_gen_W, E_Furnace_gen_W, E_BaseBoiler_req_W,
                                                          E_PeakBoiler_req_W,
                                                          E_gas_CHP_W, E_gas_BaseBoiler_W, E_gas_PeakBoiler_W,
                                                          E_wood_Furnace_W, Q_BackupBoiler_sum_W,
                                                          np.sum(E_aux_AddBoiler_req_W),
                                                          np.sum(E_solar_gen_W), np.sum(Q_SCandPVT_gen_Wh),
                                                          Q_storage_content_W,
                                                          master_to_slave_vars, locator,
                                                          E_aux_solar_and_heat_recovery_W,
                                                          E_aux_storage_operation_sum_W, gv, lca)

    # sum up results from PP Activation
    E_consumed_sum_W = np.sum(E_aux_storage_solar_and_heat_recovery_req_W) + np.sum(E_aux_activation_req_W)

    # Differenciate between Normal and green electricity for
    if MS_Var.EL_TYPE == 'green':
        ELEC_PRICE = gv.ELEC_PRICE_GREEN

    else:
        ELEC_PRICE = lca.ELEC_PRICE

    # Area available in NEtwork
    Area_AvailablePV_m2 = solar_features.A_PV_m2 * MS_Var.SOLAR_PART_PV
    Area_AvailablePVT_m2 = solar_features.A_PVT_m2 * MS_Var.SOLAR_PART_PVT
    #    import from master
    eta_m2_to_kW = ETA_AREA_TO_PEAK  # Data from Jimeno
    Q_PowerPeakAvailablePV_kW = Area_AvailablePV_m2 * eta_m2_to_kW
    Q_PowerPeakAvailablePVT_kW = Area_AvailablePVT_m2 * eta_m2_to_kW
    # calculate with conversion factor m'2-kWPeak

    KEV_RpPerkWhPVT = calc_Crem_pv(Q_PowerPeakAvailablePVT_kW * 1000.0)
    KEV_RpPerkWhPV = calc_Crem_pv(Q_PowerPeakAvailablePV_kW * 1000.0)

    KEV_total = KEV_RpPerkWhPVT / 100 * np.sum(E_PVT_gen_W) / 1000 + KEV_RpPerkWhPV / 100 * np.sum(E_PV_gen_W) / 1000
    # Units: from Rp/kWh to CHF/Wh

    price_obtained_from_KEV_for_PVandPVT = KEV_total
    cost_CHP_maintenance = np.sum(E_CHP_gen_W) * prices.CC_MAINTENANCE_PER_KWHEL / 1000.0

    # Fill up storage if end-of-season energy is lower than beginning of season
    Q_Storage_SeasonEndReheat_W = Q_storage_content_W[-1] - Q_storage_content_W[0]

    gas_price = prices.NG_PRICE

    if Q_Storage_SeasonEndReheat_W > 0:
        cost_Boiler_for_Storage_reHeat_at_seasonend = float(Q_Storage_SeasonEndReheat_W) / 0.8 * gas_price
    else:
        cost_Boiler_for_Storage_reHeat_at_seasonend = 0

    # CHANGED AS THE COST_DATA INCLUDES COST_ELECTRICITY_TOTAL ALREADY! (= double accounting)
    cost_HP_aux_uncontrollable = np.sum(E_aux_solar_and_heat_recovery_W) * ELEC_PRICE
    cost_HP_storage_operation = np.sum(E_aux_storage_solar_and_heat_recovery_req_W) * ELEC_PRICE

    cost_sum = np.sum(Opex_var_HP_Sewage) + np.sum(Opex_var_HP_Lake) + np.sum(Opex_var_GHP) + np.sum(
        Opex_var_CHP) + np.sum(Opex_var_Furnace) + np.sum(Opex_var_BaseBoiler) + np.sum(
        Opex_var_PeakBoiler) - price_obtained_from_KEV_for_PVandPVT - lca.ELEC_PRICE * np.sum(
        E_CHP_gen_W) + Opex_var_BackupBoiler_total + cost_CHP_maintenance + \
               cost_Boiler_for_Storage_reHeat_at_seasonend + cost_HP_aux_uncontrollable + cost_HP_storage_operation

    save_cost = 1

    E_oil_eq_MJ = Eprim_used
    CO2_kg_eq = CO2_emitted

    # Calculate primary energy from ressources:
    E_gas_Primary_W = Q_BackupBoiler_sum_W + np.sum(E_gas_HPSew_W) + np.sum(E_gas_HPLake_W) + np.sum(
        E_gas_GHP_W) + np.sum(E_gas_CHP_W) + np.sum(E_gas_Furnace_W) + np.sum(E_gas_BaseBoiler_W) + np.sum(
        E_gas_PeakBoiler_W)
    E_wood_Primary_W = np.sum(E_wood_HPSew_W) + np.sum(E_wood_HPLake_W) + np.sum(E_wood_GHP_W) + np.sum(
        E_wood_CHP_W) + np.sum(E_wood_Furnace_W) + np.sum(E_wood_BaseBoiler_W) + np.sum(E_wood_PeakBoiler_W)
    E_Import_Slave_req_W = E_consumed_sum_W + np.sum(E_aux_AddBoiler_req_W)
    E_Export_gen_W = np.sum(E_total_gen_W)
    E_groundheat_W = np.sum(E_coldsource_HPSew_W) + np.sum(E_coldsource_HPLake_W) + np.sum(E_coldsource_GHP_W) + np.sum(
        E_coldsource_CHP_W) + np.sum(E_coldsource_Furnace_W) + np.sum(E_coldsource_BaseBoiler_W) + np.sum(
        E_coldsource_PeakBoiler_W)
    E_solar_gen_W = np.sum(E_solar_gen_W) + np.sum(Q_SCandPVT_gen_Wh)
    intermediate_max_1 = max(np.amax(E_gas_HPSew_W), np.amax(E_gas_HPLake_W))
    intermediate_max_2 = max(intermediate_max_1, np.amax(E_gas_GHP_W))
    intermediate_max_3 = max(intermediate_max_2, np.amax(E_gas_CHP_W))
    intermediate_max_4 = max(intermediate_max_3, np.amax(E_gas_Furnace_W))
    intermediate_max_5 = max(intermediate_max_4, np.amax(E_gas_BaseBoiler_W))
    intermediate_max_6 = max(intermediate_max_5, np.amax(E_gas_PeakBoiler_W))
    E_gas_PrimaryPeakPower_W = intermediate_max_6 + np.amax(Q_BackupBoiler_W)

    if save_cost == 1:
        results = pd.DataFrame({
            "total cost": [cost_sum],
            "KEV_Remuneration": [price_obtained_from_KEV_for_PVandPVT],
            "costAddBackup_total": [Opex_var_BackupBoiler_total],
            "cost_CHP_maintenance": [cost_CHP_maintenance],
            "costHPSew_sum": np.sum(Opex_var_HP_Sewage),
            "costHPLake_sum": np.sum(Opex_var_HP_Lake),
            "costGHP_sum": np.sum(Opex_var_GHP),
            "costCHP_sum": np.sum(Opex_var_CHP),
            "costFurnace_sum": np.sum(Opex_var_Furnace),
            "costBaseBoiler_sum": np.sum(Opex_var_BaseBoiler),
            "costPeakBoiler_sum": np.sum(Opex_var_PeakBoiler),
            "cost_Boiler_for_Storage_reHeat_at_seasonend": [cost_Boiler_for_Storage_reHeat_at_seasonend],
            "cost_HP_aux_uncontrollable": [cost_HP_aux_uncontrollable],
            "cost_HP_storage_operation": [cost_HP_storage_operation],
            "E_oil_eq_MJ": [E_oil_eq_MJ],
            "CO2_kg_eq": [CO2_kg_eq],
            "cost_sum": [cost_sum],
            "E_gas_Primary_W": [E_gas_Primary_W],
            "E_gas_PrimaryPeakPower_W": [E_gas_PrimaryPeakPower_W],
            "E_wood_Primary_W": [E_wood_Primary_W],
            "E_Import_Slave_req_W": [E_Import_Slave_req_W],
            "E_Export_gen_W": [E_Export_gen_W],
            "E_groundheat_W": [E_groundheat_W],
            "E_solar_gen_Wh": [E_solar_gen_W]
        })
        results.to_csv(locator.get_optimization_slave_cost_prime_primary_energy_data(MS_Var.individual_number,
                                                                                     MS_Var.generation_number), sep=',')

    return E_oil_eq_MJ, CO2_kg_eq, cost_sum, Q_uncovered_design_W, Q_uncovered_annual_W
Example #16
0
def heating_calculations_of_DH_buildings(locator, master_to_slave_vars, gv,
                                         config, prices, lca):
    """
    Computes the parameters for the heating of the complete DHN

    :param locator: locator class
    :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: solar features class
    :param gv: global variables class
    :type locator: class
    :type master_to_slave_vars: class
    :type solar_features: class
    :type gv: 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

    """
    t = time.time()

    # Import data from storage optimization
    centralized_plant_data = pd.read_csv(
        locator.get_optimization_slave_storage_operation_data(
            master_to_slave_vars.individual_number,
            master_to_slave_vars.generation_number))
    E_aux_ch_W = np.array(centralized_plant_data['E_aux_ch_W'])
    E_aux_dech_W = np.array(centralized_plant_data['E_aux_dech_W'])
    Q_missing_W = np.array(centralized_plant_data['Q_missing_W'])
    E_aux_solar_and_heat_recovery_W = np.array(
        centralized_plant_data['E_aux_solar_and_heat_recovery_Wh'])
    Q_SC_ET_gen_Wh = np.array(centralized_plant_data['Q_SC_ET_gen_Wh'])
    Q_SC_FP_gen_Wh = np.array(centralized_plant_data['Q_SC_FP_gen_Wh'])
    Q_PVT_gen_Wh = np.array(centralized_plant_data['Q_PVT_gen_Wh'])
    Q_SCandPVT_gen_Wh = Q_SC_ET_gen_Wh + Q_SC_FP_gen_Wh + Q_PVT_gen_Wh
    E_PV_gen_W = np.array(centralized_plant_data['E_PV_Wh'])
    E_PVT_gen_W = np.array(centralized_plant_data['E_PVT_Wh'])
    E_produced_solar_W = np.array(
        centralized_plant_data['E_produced_from_solar_W'])

    E_solar_gen_W = np.add(E_PV_gen_W, E_PVT_gen_W)

    Q_missing_copy_W = Q_missing_W.copy()

    # Import Temperatures from Network Summary:
    network_data = pd.read_csv(
        locator.get_optimization_network_data_folder(
            master_to_slave_vars.network_data_file_heating))
    tdhret_K = network_data['T_DHNf_re_K']

    mdot_DH_kgpers = network_data['mdot_DH_netw_total_kgpers']
    tdhsup_K = network_data['T_DHNf_sup_K']
    # import Marginal Cost of PP Data :
    # os.chdir(Cost_Maps_Path)

    # FIXED ORDER ACTIVATION STARTS
    # Import Data - Sewage
    if HP_SEW_ALLOWED == 1:
        HPSew_Data = pd.read_csv(locator.get_sewage_heat_potential())
        QcoldsewArray = np.array(HPSew_Data['Qsw_kW']) * 1E3
        TretsewArray_K = np.array(HPSew_Data['ts_C']) + 273

    # Initiation of the variables
    Opex_var_HP_Sewage_USD = np.zeros(8760)
    Opex_var_HP_Lake_USD = np.zeros(8760)
    Opex_var_GHP_USD = np.zeros(8760)
    Opex_var_CHP_USD = np.zeros(8760)
    Opex_var_Furnace_USD = np.zeros(8760)
    Opex_var_BaseBoiler_USD = np.zeros(8760)
    Opex_var_PeakBoiler_USD = np.zeros(8760)

    source_HP_Sewage = np.zeros(8760)
    source_HP_Lake = np.zeros(8760)
    source_GHP = np.zeros(8760)
    source_CHP = np.zeros(8760)
    source_Furnace = np.zeros(8760)
    source_BaseBoiler = np.zeros(8760)
    source_PeakBoiler = np.zeros(8760)

    Q_HPSew_gen_W = np.zeros(8760)
    Q_HPLake_gen_W = np.zeros(8760)
    Q_GHP_gen_W = np.zeros(8760)
    Q_CHP_gen_W = np.zeros(8760)
    Q_Furnace_gen_W = np.zeros(8760)
    Q_BaseBoiler_gen_W = np.zeros(8760)
    Q_PeakBoiler_gen_W = np.zeros(8760)
    Q_uncovered_W = np.zeros(8760)

    E_HPSew_req_W = np.zeros(8760)
    E_HPLake_req_W = np.zeros(8760)
    E_GHP_req_W = np.zeros(8760)
    E_CHP_gen_W = np.zeros(8760)
    E_Furnace_gen_W = np.zeros(8760)
    E_BaseBoiler_req_W = np.zeros(8760)
    E_PeakBoiler_req_W = np.zeros(8760)

    NG_used_HPSew_W = np.zeros(8760)
    NG_used_HPLake_W = np.zeros(8760)
    NG_used_GHP_W = np.zeros(8760)
    NG_used_CHP_W = np.zeros(8760)
    NG_used_Furnace_W = np.zeros(8760)
    NG_used_BaseBoiler_W = np.zeros(8760)
    NG_used_PeakBoiler_W = np.zeros(8760)
    NG_used_BackupBoiler_W = np.zeros(8760)

    BG_used_HPSew_W = np.zeros(8760)
    BG_used_HPLake_W = np.zeros(8760)
    BG_used_GHP_W = np.zeros(8760)
    BG_used_CHP_W = np.zeros(8760)
    BG_used_Furnace_W = np.zeros(8760)
    BG_used_BaseBoiler_W = np.zeros(8760)
    BG_used_PeakBoiler_W = np.zeros(8760)

    Wood_used_HPSew_W = np.zeros(8760)
    Wood_used_HPLake_W = np.zeros(8760)
    Wood_used_GHP_W = np.zeros(8760)
    Wood_used_CHP_W = np.zeros(8760)
    Wood_used_Furnace_W = np.zeros(8760)
    Wood_used_BaseBoiler_W = np.zeros(8760)
    Wood_used_PeakBoiler_W = np.zeros(8760)

    Q_coldsource_HPSew_W = np.zeros(8760)
    Q_coldsource_HPLake_W = np.zeros(8760)
    Q_coldsource_GHP_W = np.zeros(8760)
    Q_coldsource_CHP_W = np.zeros(8760)
    Q_coldsource_Furnace_W = np.zeros(8760)
    Q_coldsource_BaseBoiler_W = np.zeros(8760)
    Q_coldsource_PeakBoiler_W = np.zeros(8760)

    Q_excess_W = np.zeros(8760)
    weather_data = epwreader.epw_reader(config.weather)[[
        'year', 'drybulb_C', 'wetbulb_C', 'relhum_percent', 'windspd_ms',
        'skytemp_C'
    ]]
    ground_temp = calc_ground_temperature(locator,
                                          weather_data['drybulb_C'],
                                          depth_m=10)

    weather_data = epwreader.epw_reader(config.weather)[[
        'year', 'drybulb_C', 'wetbulb_C', 'relhum_percent', 'windspd_ms',
        'skytemp_C'
    ]]
    ground_temp = calc_ground_temperature(locator,
                                          weather_data['drybulb_C'],
                                          depth_m=10)

    for hour in range(8760):
        Q_therm_req_W = Q_missing_W[hour]
        # cost_data_centralPlant_op[hour, :], source_info[hour, :], Q_source_data_W[hour, :], E_coldsource_data_W[hour,
        #                                                                                     :], \
        # E_PP_el_data_W[hour, :], E_gas_data_W[hour, :], E_wood_data_W[hour, :], Q_excess_W[hour] = source_activator(
        #     Q_therm_req_W, hour, master_to_slave_vars, mdot_DH_kgpers[hour], tdhsup_K,
        #     tdhret_K[hour], TretsewArray_K[hour], gv, prices)
        opex_output, source_output, Q_output, E_output, Gas_output, Wood_output, coldsource_output, Q_excess_W[
            hour] = heating_source_activator(Q_therm_req_W, hour,
                                             master_to_slave_vars,
                                             mdot_DH_kgpers[hour],
                                             tdhsup_K[hour], tdhret_K[hour],
                                             TretsewArray_K[hour], gv, prices,
                                             lca, ground_temp[hour])

        Opex_var_HP_Sewage_USD[hour] = opex_output['Opex_var_HP_Sewage_USD']
        Opex_var_HP_Lake_USD[hour] = opex_output['Opex_var_HP_Lake_USD']
        Opex_var_GHP_USD[hour] = opex_output['Opex_var_GHP_USD']
        Opex_var_CHP_USD[hour] = opex_output['Opex_var_CHP_USD']
        Opex_var_Furnace_USD[hour] = opex_output['Opex_var_Furnace_USD']
        Opex_var_BaseBoiler_USD[hour] = opex_output['Opex_var_BaseBoiler_USD']
        Opex_var_PeakBoiler_USD[hour] = opex_output['Opex_var_PeakBoiler_USD']

        source_HP_Sewage[hour] = source_output['HP_Sewage']
        source_HP_Lake[hour] = source_output['HP_Lake']
        source_GHP[hour] = source_output['GHP']
        source_CHP[hour] = source_output['CHP']
        source_Furnace[hour] = source_output['Furnace']
        source_BaseBoiler[hour] = source_output['BaseBoiler']
        source_PeakBoiler[hour] = source_output['PeakBoiler']

        Q_HPSew_gen_W[hour] = Q_output['Q_HPSew_gen_W']
        Q_HPLake_gen_W[hour] = Q_output['Q_HPLake_gen_W']
        Q_GHP_gen_W[hour] = Q_output['Q_GHP_gen_W']
        Q_CHP_gen_W[hour] = Q_output['Q_CHP_gen_W']
        Q_Furnace_gen_W[hour] = Q_output['Q_Furnace_gen_W']
        Q_BaseBoiler_gen_W[hour] = Q_output['Q_BaseBoiler_gen_W']
        Q_PeakBoiler_gen_W[hour] = Q_output['Q_PeakBoiler_gen_W']
        Q_uncovered_W[hour] = Q_output['Q_uncovered_W']

        E_HPSew_req_W[hour] = E_output['E_HPSew_req_W']
        E_HPLake_req_W[hour] = E_output['E_HPLake_req_W']
        E_GHP_req_W[hour] = E_output['E_GHP_req_W']
        E_CHP_gen_W[hour] = E_output['E_CHP_gen_W']
        E_Furnace_gen_W[hour] = E_output['E_Furnace_gen_W']
        E_BaseBoiler_req_W[hour] = E_output['E_BaseBoiler_req_W']
        E_PeakBoiler_req_W[hour] = E_output['E_PeakBoiler_req_W']

        if master_to_slave_vars.gt_fuel == "NG":
            NG_used_HPSew_W[hour] = Gas_output['Gas_used_HPSew_W']
            NG_used_HPLake_W[hour] = Gas_output['Gas_used_HPLake_W']
            NG_used_GHP_W[hour] = Gas_output['Gas_used_GHP_W']
            NG_used_CHP_W[hour] = Gas_output['Gas_used_CHP_W']
            NG_used_Furnace_W[hour] = Gas_output['Gas_used_Furnace_W']
            NG_used_BaseBoiler_W[hour] = Gas_output['Gas_used_BaseBoiler_W']
            NG_used_PeakBoiler_W[hour] = Gas_output['Gas_used_PeakBoiler_W']

        elif master_to_slave_vars.gt_fuel == "BG":
            BG_used_HPSew_W[hour] = Gas_output['Gas_used_HPSew_W']
            BG_used_HPLake_W[hour] = Gas_output['Gas_used_HPLake_W']
            BG_used_GHP_W[hour] = Gas_output['Gas_used_GHP_W']
            BG_used_CHP_W[hour] = Gas_output['Gas_used_CHP_W']
            BG_used_Furnace_W[hour] = Gas_output['Gas_used_Furnace_W']
            BG_used_BaseBoiler_W[hour] = Gas_output['Gas_used_BaseBoiler_W']
            BG_used_PeakBoiler_W[hour] = Gas_output['Gas_used_PeakBoiler_W']

        Wood_used_HPSew_W[hour] = Wood_output['Wood_used_HPSew_W']
        Wood_used_HPLake_W[hour] = Wood_output['Wood_used_HPLake_W']
        Wood_used_GHP_W[hour] = Wood_output['Wood_used_GHP_W']
        Wood_used_CHP_W[hour] = Wood_output['Wood_used_CHP_W']
        Wood_used_Furnace_W[hour] = Wood_output['Wood_used_Furnace_W']
        Wood_used_BaseBoiler_W[hour] = Wood_output['Wood_used_BaseBoiler_W']
        Wood_used_PeakBoiler_W[hour] = Wood_output['Wood_used_PeakBoiler_W']

        Q_coldsource_HPSew_W[hour] = coldsource_output['Q_coldsource_HPSew_W']
        Q_coldsource_HPLake_W[hour] = coldsource_output[
            'Q_coldsource_HPLake_W']
        Q_coldsource_GHP_W[hour] = coldsource_output['Q_coldsource_GHP_W']
        Q_coldsource_CHP_W[hour] = coldsource_output['Q_coldsource_CHP_W']
        Q_coldsource_Furnace_W[hour] = coldsource_output[
            'Q_coldsource_Furnace_W']
        Q_coldsource_BaseBoiler_W[hour] = coldsource_output[
            'Q_coldsource_BaseBoiler_W']
        Q_coldsource_PeakBoiler_W[hour] = coldsource_output[
            'Q_coldsource_PeakBoiler_W']

    # save data

    elapsed = time.time() - t
    # sum up the uncovered demand, get average and peak load
    Q_uncovered_design_W = np.amax(Q_uncovered_W)
    Q_uncovered_annual_W = np.sum(Q_uncovered_W)
    Opex_var_BackupBoiler_USD = np.zeros(8760)
    Q_BackupBoiler_W = np.zeros(8760)
    E_BackupBoiler_req_W = np.zeros(8760)

    Opex_var_Furnace_wet_USD = np.zeros(8760)
    Opex_var_Furnace_dry_USD = np.zeros(8760)
    Opex_var_CHP_NG_USD = np.zeros(8760)
    Opex_var_CHP_BG_USD = np.zeros(8760)
    Opex_var_BaseBoiler_NG_USD = np.zeros(8760)
    Opex_var_BaseBoiler_BG_USD = np.zeros(8760)
    Opex_var_PeakBoiler_NG_USD = np.zeros(8760)
    Opex_var_PeakBoiler_BG_USD = np.zeros(8760)
    Opex_var_BackupBoiler_NG_USD = np.zeros(8760)
    Opex_var_BackupBoiler_BG_USD = np.zeros(8760)

    Opex_var_PV_USD = np.zeros(8760)
    Opex_var_PVT_USD = np.zeros(8760)
    Opex_var_SC_USD = np.zeros(8760)

    if Q_uncovered_design_W != 0:
        for hour in range(8760):
            tdhret_req_K = tdhret_K[hour]
            BoilerBackup_Cost_Data = cond_boiler_op_cost(Q_uncovered_W[hour], Q_uncovered_design_W, tdhret_req_K, \
                                                         master_to_slave_vars.BoilerBackupType,
                                                         master_to_slave_vars.EL_TYPE, gv, prices, lca)
            Opex_var_BackupBoiler_USD[
                hour], Opex_var_BackupBoiler_per_Wh_USD, Q_BackupBoiler_W[
                    hour], E_BackupBoiler_req_W_hour = BoilerBackup_Cost_Data
            E_BackupBoiler_req_W[hour] = E_BackupBoiler_req_W_hour
            NG_used_BackupBoiler_W[hour] = Q_BackupBoiler_W[hour]
        Q_BackupBoiler_sum_W = np.sum(Q_BackupBoiler_W)
        Opex_t_var_BackupBoiler_USD = np.sum(Opex_var_BackupBoiler_USD)

    else:
        Q_BackupBoiler_sum_W = 0.0
        Opex_t_var_BackupBoiler_USD = 0.0

    if master_to_slave_vars.Furn_Moist_type == "wet":
        Opex_var_Furnace_wet_USD = Opex_var_Furnace_USD
    elif master_to_slave_vars.Furn_Moist_type == "dry":
        Opex_var_Furnace_dry_USD = Opex_var_Furnace_USD

    if master_to_slave_vars.gt_fuel == "NG":
        Opex_var_CHP_NG_USD = Opex_var_CHP_USD
        Opex_var_BaseBoiler_NG_USD = Opex_var_BaseBoiler_USD
        Opex_var_PeakBoiler_NG_USD = Opex_var_PeakBoiler_USD
        Opex_var_BackupBoiler_NG_USD = Opex_var_BackupBoiler_USD

    elif master_to_slave_vars.gt_fuel == "BG":
        Opex_var_CHP_BG_USD = Opex_var_CHP_USD
        Opex_var_BaseBoiler_BG_USD = Opex_var_BaseBoiler_USD
        Opex_var_PeakBoiler_BG_USD = Opex_var_PeakBoiler_USD
        Opex_var_BackupBoiler_BG_USD = Opex_var_BackupBoiler_USD

    # saving pattern activation to disk
    date = network_data.DATE.values
    results = pd.DataFrame({
        "DATE": date,
        "Q_Network_Demand_after_Storage_W": Q_missing_copy_W,
        "Opex_var_HP_Sewage": Opex_var_HP_Sewage_USD,
        "Opex_var_HP_Lake": Opex_var_HP_Lake_USD,
        "Opex_var_GHP": Opex_var_GHP_USD,
        "Opex_var_CHP_BG": Opex_var_CHP_BG_USD,
        "Opex_var_CHP_NG": Opex_var_CHP_NG_USD,
        "Opex_var_Furnace_wet": Opex_var_Furnace_wet_USD,
        "Opex_var_Furnace_dry": Opex_var_Furnace_dry_USD,
        "Opex_var_BaseBoiler_BG": Opex_var_BaseBoiler_BG_USD,
        "Opex_var_BaseBoiler_NG": Opex_var_BaseBoiler_NG_USD,
        "Opex_var_PeakBoiler_BG": Opex_var_PeakBoiler_BG_USD,
        "Opex_var_PeakBoiler_NG": Opex_var_PeakBoiler_NG_USD,
        "Opex_var_BackupBoiler_BG": Opex_var_BackupBoiler_BG_USD,
        "Opex_var_BackupBoiler_NG": Opex_var_BackupBoiler_NG_USD,
        "HPSew_Status": source_HP_Sewage,
        "HPLake_Status": source_HP_Lake,
        "GHP_Status": source_GHP,
        "CHP_Status": source_CHP,
        "Furnace_Status": source_Furnace,
        "BoilerBase_Status": source_BaseBoiler,
        "BoilerPeak_Status": source_PeakBoiler,
        "Q_HPSew_W": Q_HPSew_gen_W,
        "Q_HPLake_W": Q_HPLake_gen_W,
        "Q_GHP_W": Q_GHP_gen_W,
        "Q_CHP_W": Q_CHP_gen_W,
        "Q_Furnace_W": Q_Furnace_gen_W,
        "Q_BaseBoiler_W": Q_BaseBoiler_gen_W,
        "Q_PeakBoiler_W": Q_PeakBoiler_gen_W,
        "Q_AddBoiler_W": Q_uncovered_W,
        "Q_coldsource_HPLake_W": Q_coldsource_HPLake_W,
        "Q_coldsource_HPSew_W": Q_coldsource_HPSew_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,
        "Q_excess_W": Q_excess_W,
        "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,
        "E_BackupBoiler_req_W": E_BackupBoiler_req_W,
        "NG_used_HPSew_W": NG_used_HPSew_W,
        "NG_used_HPLake_W": NG_used_HPLake_W,
        "NG_used_GHP_W": NG_used_GHP_W,
        "NG_used_CHP_W": NG_used_CHP_W,
        "NG_used_Furnace_W": NG_used_Furnace_W,
        "NG_used_BaseBoiler_W": NG_used_BaseBoiler_W,
        "NG_used_PeakBoiler_W": NG_used_PeakBoiler_W,
        "NG_used_BackupBoiler_W": NG_used_BackupBoiler_W,
        "BG_used_HPSew_W": BG_used_HPSew_W,
        "BG_used_HPLake_W": BG_used_HPLake_W,
        "BG_used_GHP_W": BG_used_GHP_W,
        "BG_used_CHP_W": BG_used_CHP_W,
        "BG_used_Furnace_W": BG_used_Furnace_W,
        "BG_used_BaseBoiler_W": BG_used_BaseBoiler_W,
        "BG_used_PeakBoiler_W": BG_used_PeakBoiler_W,
        "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_": 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
    })

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

    if master_to_slave_vars.gt_fuel == "NG":

        CO2_emitted, PEN_used = calc_primary_energy_and_CO2(
            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, Q_coldsource_HPSew_W, Q_coldsource_HPLake_W,
            Q_coldsource_GHP_W, E_CHP_gen_W, E_Furnace_gen_W,
            E_BaseBoiler_req_W, E_PeakBoiler_req_W, NG_used_CHP_W,
            NG_used_BaseBoiler_W, NG_used_PeakBoiler_W,
            Wood_used_Furnace_W, Q_BackupBoiler_sum_W,
            np.sum(E_BackupBoiler_req_W), master_to_slave_vars, locator, lca)
    elif master_to_slave_vars.gt_fuel == "BG":

        CO2_emitted, PEN_used = calc_primary_energy_and_CO2(
            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, Q_coldsource_HPSew_W, Q_coldsource_HPLake_W,
            Q_coldsource_GHP_W, E_CHP_gen_W, E_Furnace_gen_W,
            E_BaseBoiler_req_W, E_PeakBoiler_req_W, BG_used_CHP_W,
            BG_used_BaseBoiler_W, BG_used_PeakBoiler_W,
            Wood_used_Furnace_W, Q_BackupBoiler_sum_W,
            np.sum(E_BackupBoiler_req_W), master_to_slave_vars, locator, lca)

    cost_sum = np.sum(Opex_var_HP_Sewage_USD) + np.sum(
        Opex_var_HP_Lake_USD) + np.sum(Opex_var_GHP_USD) + np.sum(
            Opex_var_CHP_USD) + np.sum(Opex_var_Furnace_USD) + np.sum(
                Opex_var_BaseBoiler_USD) + np.sum(
                    Opex_var_PeakBoiler_USD) + Opex_t_var_BackupBoiler_USD

    E_oil_eq_MJ = PEN_used
    CO2_kg_eq = CO2_emitted

    return E_oil_eq_MJ, CO2_kg_eq, cost_sum, Q_uncovered_design_W, Q_uncovered_annual_W
def extract_loads_individual(locator, config, individual_with_name_dict,
                             DCN_barcode, DHN_barcode,
                             district_heating_network,
                             district_cooling_network,
                             column_names_buildings_heating,
                             column_names_buildings_cooling):
    # local variables
    weather_file = locator.get_weather_file()
    network_depth_m = Z0
    T_ambient = epwreader.epw_reader(weather_file)['drybulb_C']
    ground_temp = calc_ground_temperature(locator,
                                          T_ambient,
                                          depth_m=network_depth_m)

    # EVALUATE CASES TO CREATE A NETWORK OR NOT
    if district_heating_network:  # network exists
        if DHN_barcode.count("1") == len(column_names_buildings_heating):
            network_file_name_heating = "DH_Network_summary_result_" + hex(
                int(str(DHN_barcode), 2)) + ".csv"
            Q_DHNf_W = pd.read_csv(
                locator.get_optimization_network_results_summary(
                    'DH', DHN_barcode),
                usecols=["Q_DHNf_W"]).values
            Q_heating_max_W = Q_DHNf_W.max()
        elif DHN_barcode.count("1") == 0:  # no network at all
            network_file_name_heating = "DH_Network_summary_result_" + hex(
                int(str(DHN_barcode), 2)) + ".csv"
            Q_heating_max_W = 0
        else:
            network_file_name_heating = "DH_Network_summary_result_" + hex(
                int(str(DHN_barcode), 2)) + ".csv"
            if not os.path.exists(
                    locator.get_optimization_network_results_summary(
                        'DH', DHN_barcode)):
                total_demand = createTotalNtwCsv(
                    DHN_barcode, locator, column_names_buildings_heating)
                num_total_buildings = len(column_names_buildings_heating)
                buildings_in_heating_network = total_demand.Name.values
                # Run the substation and distribution routines
                substation.substation_main_heating(
                    locator,
                    total_demand,
                    buildings_in_heating_network,
                    DHN_barcode=DHN_barcode)
                summarize_network.network_main(locator,
                                               buildings_in_heating_network,
                                               ground_temp,
                                               num_total_buildings, "DH",
                                               DHN_barcode)

            Q_DHNf_W = pd.read_csv(
                locator.get_optimization_network_results_summary(
                    'DH', DHN_barcode),
                usecols=["Q_DHNf_W"]).values
            Q_heating_max_W = Q_DHNf_W.max()
    else:
        Q_heating_max_W = 0.0
        network_file_name_heating = ""

    if district_cooling_network:  # network exists
        if DCN_barcode.count("1") == len(column_names_buildings_cooling):
            network_file_name_cooling = "DC_Network_summary_result_" + hex(
                int(str(DCN_barcode), 2)) + ".csv"
            if individual_with_name_dict['HPServer'] == 1:
                # if heat recovery is ON, then only need to satisfy cooling load of space cooling and refrigeration
                Q_DCNf_W_no_server_demand = pd.read_csv(
                    locator.get_optimization_network_results_summary(
                        'DC', DCN_barcode),
                    usecols=["Q_DCNf_space_cooling_and_refrigeration_W"
                             ]).values
                Q_DCNf_W_with_server_demand = pd.read_csv(
                    locator.get_optimization_network_results_summary(
                        'DC', DCN_barcode),
                    usecols=[
                        "Q_DCNf_space_cooling_data_center_and_refrigeration_W"
                    ]).values

                Q_DCNf_W = Q_DCNf_W_no_server_demand + (
                    (Q_DCNf_W_with_server_demand - Q_DCNf_W_no_server_demand) *
                    (individual_with_name_dict['HPShare']))

            else:
                Q_DCNf_W = pd.read_csv(
                    locator.get_optimization_network_results_summary(
                        'DC', DCN_barcode),
                    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 = "DC_Network_summary_result_" + hex(
                int(str(DCN_barcode), 2)) + ".csv"
            Q_cooling_max_W = 0.0
        else:
            network_file_name_cooling = "DC_Network_summary_result_" + hex(
                int(str(DCN_barcode), 2)) + ".csv"

            if not os.path.exists(
                    locator.get_optimization_network_results_summary(
                        'DC', DCN_barcode)):
                total_demand = createTotalNtwCsv(
                    DCN_barcode, locator, column_names_buildings_cooling)
                num_total_buildings = len(column_names_buildings_cooling)
                buildings_in_cooling_network = total_demand.Name.values

                # Run the substation and distribution routines
                substation.substation_main_cooling(
                    locator,
                    total_demand,
                    buildings_in_cooling_network,
                    DCN_barcode=DCN_barcode)
                summarize_network.network_main(locator,
                                               buildings_in_cooling_network,
                                               ground_temp,
                                               num_total_buildings, 'DC',
                                               DCN_barcode)

            Q_DCNf_W_no_server_demand = pd.read_csv(
                locator.get_optimization_network_results_summary(
                    'DC', DCN_barcode),
                usecols=["Q_DCNf_space_cooling_and_refrigeration_W"]).values
            Q_DCNf_W_with_server_demand = pd.read_csv(
                locator.get_optimization_network_results_summary(
                    'DC', DCN_barcode),
                usecols=[
                    "Q_DCNf_space_cooling_data_center_and_refrigeration_W"
                ]).values

            # if heat recovery is ON, then only need to satisfy cooling load of space cooling and refrigeration
            if district_heating_network and individual_with_name_dict[
                    'HPServer'] == 1:
                Q_DCNf_W = Q_DCNf_W_no_server_demand + (
                    (Q_DCNf_W_with_server_demand - Q_DCNf_W_no_server_demand) *
                    (individual_with_name_dict['HPShare']))
            else:
                Q_DCNf_W = Q_DCNf_W_with_server_demand

            Q_cooling_max_W = Q_DCNf_W.max()
    else:
        Q_cooling_max_W = 0.0
        network_file_name_cooling = ""

    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)

    return Q_cooling_nom_W, Q_heating_nom_W, network_file_name_cooling, network_file_name_heating