示例#1
0
def test_raised_exception_05():
    """Test if an exception is raised if ... """
    with pytest.raises(ValueError):
        cmpr_hp_chllr.calc_cops(temp_high=[39],
                                temp_low=[17],
                                quality_grade=0.4,
                                mode='chiller',
                                temp_threshold_icing=2,
                                factor_icing=0.8)
示例#2
0
def test_raised_exception_01():
    """Test if an exception is raised if temp_low is not a list."""
    with pytest.raises(TypeError):
        cmpr_hp_chllr.calc_cops(
            temp_high=[40],
            temp_low=12,  # ERROR - temp_low has to be a list!
            quality_grade=0.4,
            mode='heat_pump',
            temp_threshold_icing=2,
            factor_icing=0.8)
示例#3
0
def test_raised_exception_03():
    """Test if an exception is raised if temp_high and
    temp_low have different length AND none of them is of length 1."""
    with pytest.raises(IndexError):
        cmpr_hp_chllr.calc_cops(
            temp_high=[40, 39, 39],
            temp_low=[12, 10],  # ERROR - len(temp_low) has
            # to be 1 or equal to len(temp_high)
            quality_grade=0.4,
            mode='heat_pump',
            temp_threshold_icing=2,
            factor_icing=0.8)
示例#4
0
def test_cop_calculation_airsource_hp_with_icing_02():
    cops_ASHP = cmpr_hp_chllr.calc_cops(temp_high=[40],
                                        temp_low=[2.3],
                                        quality_grade=0.5,
                                        mode='heat_pump',
                                        temp_threshold_icing=2,
                                        factor_icing=0.8)
    assert cops_ASHP == [4.15318302387268]
示例#5
0
def test_calc_cops_with_Series_02():
    set_temp_each_hour = {'01:00': 40, '02:00': 40, '03:00': 40}
    temp_h_series = pd.Series(set_temp_each_hour)
    cops_HP = cmpr_hp_chllr.calc_cops(temp_high=temp_h_series,
                                      temp_low=[12],
                                      quality_grade=0.4,
                                      mode='heat_pump')
    assert cops_HP == [4.473571428571428, 4.473571428571428, 4.473571428571428]
示例#6
0
def test_calc_cops_with_Series_01():
    ambient_temp_each_hour = {'01:00': 12, '02:00': 12, '03:00': 12}
    temp_l_series = pd.Series(ambient_temp_each_hour)
    cops_HP = cmpr_hp_chllr.calc_cops(temp_high=[40],
                                      temp_low=temp_l_series,
                                      quality_grade=0.4,
                                      mode='heat_pump')
    assert cops_HP == [4.473571428571428, 4.473571428571428, 4.473571428571428]
示例#7
0
def test_cop_calculation_airsource_hp_with_icing_01():
    cops_ASHP = cmpr_hp_chllr.calc_cops(temp_high=[40],
                                        temp_low=[1.3],
                                        quality_grade=0.5,
                                        mode='heat_pump',
                                        temp_threshold_icing=2,
                                        factor_icing=0.8)
    assert cops_ASHP == [3.236692506459949]
示例#8
0
# Delta t
temp_difference = range(10, 71, 1)
temp_difference_industrial = range(20, 142, 2)
temperature_diff_q_grade = range(5, 147, 2)

# Quality grades
quality_grades = [q / 10 for q in range(2, 11, 2)]

cops = pd.DataFrame()

# COPs of ax exemplary heat pump for domestic hot water
# (sink temperature below 100 degC)
cops['temperature_difference'] = temp_difference
list_temp_low = [temp_high - temp_diff for temp_diff in temp_difference]
cops[temp_high] = cmpr_hp_chiller.calc_cops(temp_high=[temp_high],
                                            temp_low=list_temp_low,
                                            quality_grade=0.35,
                                            mode='heat_pump')

# COPs of ax exemplary hight temperature heat pump for industrial applications
# (sink temperature above 100 degC and higher quality grade)
cops['temperature_difference_industrial'] = temp_difference_industrial
temp_l_ind = [
    temp_high_industrial - temp_diff
    for temp_diff in temp_difference_industrial
]
cops[temp_high_industrial] = cmpr_hp_chiller.calc_cops(
    temp_high=[temp_high_industrial],
    temp_low=temp_l_ind,
    quality_grade=0.45,
    mode='heat_pump')
def calculate_cops_and_eers(
    weather,
    lat,
    lon,
    mode,
    temperature_col="temp_air",
    user_inputs_pvcompare_directory=None,
    user_inputs_mvs_directory=None,
):
    r"""
    Calculates the COPs of a heat pump or EERs of a chiller depending on `mode`.

    Temperature dependency is taken into consideration.
    For these calculations the ``calc_cops()` <functionality>`_ functionality of
    `oemof.thermal <https://oemof-thermal.readthedocs.io/en/stable/>`_  is
    used. Data like quality grade and factor icing is read from the file
    `heat_pumps_and_chillers.csv` in the `input_directory`.
    Negative values, which might occur due to high ambient temperatures in summer are
    set to zero.

    Parameters
    ----------
    weather : :pandas:`pandas.DataFrame<frame>`
        Contains weather data time series. Required: ambient temperature in
        column `temperature_col`.
    lat : float
        Latitude of ambient temperature location in `weather`.
    lon : float
        Longitude of ambient temperature location in `weather`.
    temperature_col : str
        Name of column in `weather` containing ambient temperature.
        Default: "temp_air".
    mode : str
        Defines whether COPs of heat pump ("heat_pump") or EERs of chiller
        ("chiller") are calculated. Default: "heat_pump".
    user_inputs_pvcompare_directory: str or None
        Path to user input directory. If None,
        `constants.DEFAULT_USER_INPUTS_PVCOMPARE_DIRECTORY` is used.
        Default: None.
    user_inputs_mvs_directory: str or None
        Path to input directory containing files that describe the energy
        system and that are an input to MVS. If None,
        `constants.DEFAULT_USER_INPUTS_MVS_DIRECTORY` is used.
        Default: None.

    Returns
    -------
    None
    """

    # read parameters from file
    if user_inputs_pvcompare_directory == None:
        user_inputs_pvcompare_directory = (
            constants.DEFAULT_USER_INPUTS_PVCOMPARE_DIRECTORY)
    if user_inputs_mvs_directory == None:
        user_inputs_mvs_directory = constants.DEFAULT_USER_INPUTS_MVS_DIRECTORY
    filename = os.path.join(user_inputs_pvcompare_directory,
                            "heat_pumps_and_chillers.csv")

    try:
        parameters_complete = pd.read_csv(filename)
        parameters = pd.read_csv(filename, header=0, index_col=0).loc[mode]
    except KeyError:
        raise ValueError(
            f"Parameter `mode` should be 'heat_pump' or 'chiller' but is {mode}"
        )
    # prepare parameters for calc_cops

    def process_temperatures(temperature, level, mode, technology):
        r"""
        Processes temperatures for specific `level`, `mode`, and `technology`.

        `temperature` can be passed in the following way:
        1. As NaN - The lower/higher temperature of the heat pump/chiller equals the ambient temperature time series
        2. As single value (float or int) - The temperature is constant
        3. As time series - The temperature is not constant or differs from ambient temperature (eg. ground source)

        Parameters
        ----------
        temperature : float, int, np.nan, :pandas:`pandas.Series<series>
            Passed temperature which was written from input data.
        level : str
            Defines whether high or low temperature has been passed.
        mode : str
            Defines whether COPs of heat pump ("heat_pump") or EERs of chiller
            ("chiller") are calculated.
        technology: str
            Defines whether technology is a "brine-water", "air-air"
            or "air-water".

        Returns
        -------
        temperature: list
            Temperature adjusted to use case of plant.
        """

        if isinstance(temperature, float):
            if pd.isna(temperature):
                # In case of NaN
                if (level == "low"
                        and mode == "heat_pump") or (level == "high"
                                                     and mode == "chiller"):
                    if technology == "brine-water":
                        # Prepare mean yearly ambient temperature for calc_cops (numeric)
                        temperature = np.average(
                            weather[temperature_col].values)
                        temperature = [temperature]
                    elif technology == "air-air" or technology == "air-water":
                        # Prepare ambient temperature for calc_cops (list)
                        temperature = weather[temperature_col].values.tolist()
                        logging.info(
                            f"The {mode} is modeled with the ambient temperature from weather data as {level} temperature."
                        )
                    else:
                        # Prepare ambient temperature for calc_cops (list)
                        temperature = weather[temperature_col].values.tolist()
                        logging.warning(
                            f"The technology of the {mode} should be either 'air-air', 'air-water' or 'brine-water'."
                            f"'{technology}' is not a valid technology. The {mode} is modeled as an air source {mode} by default"
                            f" and with the ambient temperature from weather data as {level} temperature."
                        )
                    return temperature
                else:
                    # Required parameter is missing
                    raise ValueError(
                        f"Missing required value of {mode}: Please provide a numeric as {mode}'s {level} temperature in heat_pumps_and_chillers.csv."
                    )
            elif isinstance(temperature, (float, int)):
                # Numerics pass
                temperature = [temperature]
                logging.info(
                    f"The {mode} is modeled with the constant {level} temperature of {temperature} °C"
                )
                return temperature
        elif isinstance(temperature, str):
            # In case temperatures are provided as time series in separate file
            try:
                temp_string = temperature.split("'")
                temp_filename = temp_string[3]
                temp_header = temp_string[7]
                temperature_df = pd.read_csv(
                    os.path.join(user_inputs_pvcompare_directory,
                                 temp_filename))
                temperature_df = temperature_df.set_index(temp_header)
                temperature = temperature_df.index.tolist()
                logging.info(
                    f"The {mode} is modeled with passed time series as {level} temperature."
                )
                return temperature

            except AttributeError:
                raise ValueError(
                    f"Wrong value: Please check the {level} temperature of the {mode}. See the documentation on passing the {mode}'s temperatures for further information"
                )
        else:
            # Required parameter is missing in case of None or else
            raise ValueError(
                f"Missing required value of {mode}: Please provide a numeric as {mode}'s {level} temperature in heat_pumps_and_chillers.csv."
            )

    low_temperature = process_temperatures(parameters.temp_low, "low", mode,
                                           parameters.technology)
    high_temperature = process_temperatures(parameters.temp_high, "high", mode,
                                            parameters.technology)

    if pd.isna(parameters.quality_grade):
        if parameters.technology == "air-air":
            if mode == "heat_pump":
                quality_grade = 0.1852
            elif mode == "chiller":
                quality_grade = 0.3
        elif parameters.technology == "air-water":
            if mode == "heat_pump":
                quality_grade = 0.403
            elif mode == "chiller":
                # Required parameter is missing in case of None or else
                raise ValueError(
                    f"Missing required value of {mode}: There is no default value of a quality grade provided for an {parameters.technology} {mode}"
                    f"Please provide a valid value of the quality grade.")
        elif parameters.technology == "brine-water":
            if mode == "heat_pump":
                quality_grade = 0.53
            elif mode == "chiller":
                # Required parameter is missing in case of None or else
                raise ValueError(
                    f"Missing required value of {mode}: There is no default value of a quality grade provided for a {parameters.technology} {mode}. "
                    f"Please provide a valid value of the quality grade.")
        else:
            # Required parameter is missing in case of different technology
            raise ValueError(
                f"Missing required value of {mode}: '{parameters.quality_grade}' could not be processed as quality grade. "
                f"Please provide a valid value or the technology of the {mode} in order to model with default quality grade."
            )
    elif isinstance(parameters.quality_grade, (float, int)):
        quality_grade = float(parameters.quality_grade)
    else:
        # Required parameter is missing in case of None or else
        raise ValueError(
            f"Missing required value of {mode}: '{parameters.quality_grade}' could not be processed as quality grade."
            f"Please provide a valid value or the technology of the {mode} in order to model from default quality grade."
        )

    # Save default quality grade to heat_pumps_and_chillers.csv
    parameters_complete.quality_grade = quality_grade
    parameters_complete.to_csv(filename,
                               index=False,
                               header=True,
                               float_format="%g")

    # create add on to filename (year, lat, lon)
    year = maya.parse(weather.index[int(len(weather) / 2)]).datetime().year

    # calculate COPs or EERs with oemof thermal
    if mode == "heat_pump":
        if len(high_temperature) > 1:
            add_on = f"_{year}_{lat}_{lon}"
        elif len(high_temperature) == 1:
            add_on = f"_{year}_{lat}_{lon}_{high_temperature[0]}"
        # additional parameters for heat_pump mode
        factor_icing = (None if parameters.factor_icing == "None" else float(
            parameters.factor_icing))
        temp_threshold_icing = (None
                                if parameters.temp_threshold_icing == "None"
                                else float(parameters.temp_threshold_icing))

        efficiency = cmpr_hp_chiller.calc_cops(
            temp_high=high_temperature,
            temp_low=low_temperature,
            quality_grade=quality_grade,
            mode=mode,
            temp_threshold_icing=temp_threshold_icing,
            factor_icing=factor_icing,
        )

        # define variables for later proceeding
        column_name = "cop"
        filename = f"cops_heat_pump{add_on}.csv"

    elif mode == "chiller":
        if len(low_temperature) > 1:
            add_on = f"_{year}_{lat}_{lon}"
        elif len(low_temperature) == 1:
            add_on = f"_{year}_{lat}_{lon}_{low_temperature[0]}"
        efficiency = cmpr_hp_chiller.calc_cops(
            temp_high=high_temperature,
            temp_low=low_temperature,
            quality_grade=quality_grade,
            mode=mode,
        )
        column_name = "eer"
        filename = f"eers_chiller{add_on}.csv"

    # add list of cops/eers to data frame
    df = pd.DataFrame(weather[temperature_col])

    try:
        df[column_name] = efficiency
    except ValueError:
        df[column_name] = np.multiply(efficiency, np.ones(len(df)))

    # set negative COPs/EERs to np.inf
    # COP/EER below zero results from temp_low > temp_high
    # and will therefore be represented with COP/EER -> infinity
    indices = df.loc[df[column_name] < 0].index
    df[column_name][indices] = np.inf

    # extract COPs/EERs as pd.Series from data frame
    efficiency_series = df[column_name]
    efficiency_series.name = "no_unit"

    # save time series to `user_inputs_mvs_directory/time_series`
    time_series_directory = os.path.join(user_inputs_mvs_directory,
                                         "time_series")

    logging.info(
        f"The cops of a heat pump are calculated and saved under {time_series_directory}."
    )

    efficiency_series.to_csv(os.path.join(time_series_directory, filename),
                             index=False,
                             header=True)

    return efficiency_series
示例#10
0
"""
Example on how to use the 'calc_cops' function to get the
COPs of a compression chiller.

We use the ambient air as heat sink (high temperature reservoir). The input is
a list to show how the function can be applied on several time steps. The
output is a list as well and may serve as input (conversion_factor) for a
oemof.solph.transformer.
"""

import oemof.thermal.compression_heatpumps_and_chillers as cmpr_hp_chiller

# Ambient temperatures in degC for a single day (24h)
temp_ambient = [
    24, 24, 24, 25, 25, 25, 26, 27, 28, 29, 31, 32, 35, 34, 27, 26, 25, 24, 24,
    24, 24, 24, 24, 23
]

cops_chiller = cmpr_hp_chiller.calc_cops(temp_high=temp_ambient,
                                         temp_low=[18],
                                         quality_grade=0.3,
                                         mode='chiller')

print("")
print("Coefficients of Performance (COP):")
t = 1
for cop_chiller in cops_chiller:
    print(t, "h: {:2.2f}".format(cop_chiller))
    t += 1
print("")
示例#11
0
def test_cop_calculation_chiller():
    cops_chiller = cmpr_hp_chllr.calc_cops(temp_high=[35],
                                           temp_low=[17],
                                           quality_grade=0.45,
                                           mode='chiller')
    assert cops_chiller == [7.25375]
示例#12
0
"""
Example on how to use the 'calc_cops' function to get the
COPs of an exemplary ground-source heat pump (GSHP).

We use the soil temperature as low temperature heat reservoir.
"""

import oemof.thermal.compression_heatpumps_and_chillers as cmpr_hp_chiller
import pandas as pd
import os

# set path
path_data= r'C:\Users\Stefanie.nguyen\git\COP_calculation\oemof-thermal\examples\compression_heatpump_and_chiller'
# Precalculation of COPs
cops_GSHP = cmpr_hp_chiller.calc_cops(
    temp_high=[37.43],
    temp_low=[10],
    quality_grade=0.53,
    mode='heat_pump')

GSHP_dict={'ground_temperature':[10],
           'temperature_sink':[37.43],
           'COP':cops_GSHP}

data=pd.DataFrame(GSHP_dict)
#data.to_csv(os.path.join(os.path.dirname(__file__) , 'data/results/2021-03-16_GSHP_COP.csv'))
示例#13
0
def test_cop_calculation_hp_list_input_02():
    cops_HP = cmpr_hp_chllr.calc_cops(temp_high=[40],
                                      temp_low=[12, 12],
                                      quality_grade=0.4,
                                      mode='heat_pump')
    assert cops_HP == [4.473571428571428, 4.473571428571428]
示例#14
0
# Borehole that acts as heat source for the heat pump with
# limited extraction heat flow rate
energysystem.add(
    solph.Source(label='ambient',
                 outputs={b_th_low: solph.Flow(nominal_value=30)}))

energysystem.add(
    solph.Sink(label='demand',
               inputs={
                   b_th_high: solph.Flow(fix=data['demand_heat'],
                                         nominal_value=1)
               }))

# Precalculation of COPs
cops_GSHP = cmpr_hp_chiller.calc_cops(temp_high=[40],
                                      temp_low=data['ground_temperature'],
                                      quality_grade=0.4,
                                      mode='heat_pump')

# Ground-Source Heat Pump
energysystem.add(
    solph.Transformer(
        label="GSHP",
        inputs={
            b_el: solph.Flow(),
            b_th_low: solph.Flow()
        },
        outputs={b_th_high: solph.Flow(nominal_value=25, variable_costs=5)},
        conversion_factors={
            b_el: [1 / cop for cop in cops_GSHP],
            b_th_low: [(cop - 1) / cop for cop in cops_GSHP]
        }))
    label='backup_heating',
    outputs={b_heat: solph.Flow(variable_costs=10)}))

energysystem.add(solph.Sink(
    label='demand',
    inputs={b_heat: solph.Flow(actual_value=data['demand_heat'],
                               fixed=True,
                               nominal_value=1)}))

temp_threshold_icing = 2

# Pre-Calculate COPs
cops_ASHP = cmpr_hp_chiller.calc_cops(
    temp_high=[40],
    temp_low=data['ambient_temperature'],
    quality_grade=0.4,
    mode='heat_pump',
    consider_icing=True,
    temp_threshold_icing=temp_threshold_icing,
    factor_icing=0.8)

# Air-Source Heat Pump
energysystem.add(solph.Transformer(
    label="ASHP",
    inputs={b_el: solph.Flow()},
    outputs={b_heat: solph.Flow(nominal_value=25, variable_costs=5)},
    conversion_factors={b_heat: cops_ASHP}))

model = solph.Model(energysystem)

model.solve(solver=solver, solve_kwargs={'tee': solver_verbose})
    def __init__(self, params):
        """Constructor method
        """
        # Call the init function of the mother class.
        Component.__init__(self)

        # ------------------- PARAMETERS -------------------
        self.name = 'Heat_pump_default_name'

        self.bus_el = None
        self.bus_th = None

        # Max. heating output [W]
        self.power_max = 1000e3
        # Life time [a]
        self.life_time = 20

        self.csv_filename = None
        self.csv_separator = ','
        self.column_title = 0
        self.path = os.path.dirname(__file__)

        # ------------------- PARAMETERS BASED ON OEMOF THERMAL EXAMPLE -------------------
        # Temperature below which icing occurs [K]
        self.temp_threshold_icing = 275.15
        # Convert to degrees C for oemof_thermal function
        self.temp_threshold_icing_C = self.temp_threshold_icing - 273.15
        # The output temperature from the heat pump [K]
        self.temp_high = 313.15
        # Convert to degrees C for oemof_thermal function
        self.temp_high_C = self.temp_high - 273.15
        # Convert to a list for oemof_thermal function
        self.temp_high_C_list = [self.temp_high_C]
        # The ambient temperature [K]
        self.temp_low = 283.15
        # Convert to degrees C for oemof_thermal function
        self.temp_low_C = self.temp_low - 273.15
        # Quality grade of heat pump [-]
        self.quality_grade = 0.4
        # Can be set to heat pump or chiller
        self.mode = 'heat_pump'
        # COP reduction caused by icing [-]
        self.factor_icing = 0.8
        # Ask Jann about this/look more into detail
        # self.consider_icing = False

        # ------------------- UPDATE PARAMETER DEFAULT VALUES -------------------
        self.set_parameters(params)

        if self.csv_filename is not None:
            # A csv file containing data for the ambient temperature is required [deg C]
            self.temp_low = func.read_data_file(self.path, self.csv_filename,
                                                self.csv_separator,
                                                self.column_title)
            self.temp_low_series = self.temp_low[self.column_title]
            self.temp_low_series_C = pd.Series(self.temp_low_series - 273.15)
        else:
            self.temp_low_list = [self.temp_low_C
                                  ] * self.sim_params.n_intervals
            self.temp_low_series_C = pd.Series(self.temp_low_list)

        # A function taken from oemof thermal that calculates the coefficient
        # of performance (pre-calculated)
        self.cops = cmpr_hp_chiller.calc_cops(
            self.mode,
            self.temp_high_C_list,
            self.temp_low_series_C,
            self.quality_grade,
            self.temp_threshold_icing_C,
            # self.consider_icing,
            self.factor_icing)
示例#17
0
    data_reduct = data.loc['2016-01-01 00:00:00':'2017-01-01 00:00:00'].reset_index()
    #print(data_reduct)
else:
    raise Exception('Date time range does not exist. Please try another data set.')

dataframe = pd.concat([data_reduct['date_time'],
                       data_reduct['ambient_temperature'],
                       data_reduct['temperature_sink']], axis=1).set_index('date_time')

#if ambient temperature is higher than 20°C, set temperature sinks to 46.9°C for warm water use only
dataframe.loc[dataframe.ambient_temperature > 20, 'temperature_sink'] = 46.9

# Precalculation of COPs
cops_ASHP = cmpr_hp_chiller.calc_cops(
    temp_high=dataframe['temperature_sink'],
    temp_low=dataframe['ambient_temperature'],
    quality_grade=0.4030,
    mode='heat_pump')

COP=pd.DataFrame(cops_ASHP, data_reduct['date_time'], columns=['COP'])

#pre processing sink temperature
list_temp_low = dataframe['ambient_temperature'].values.tolist()  # External temperature of evaporator
list_temp_medium = dataframe['temperature_sink'].values.tolist()  # External temperature of condenser

# Calculate temperature difference between condenser and evaporator
temp_diff = [(t_m - t_l) for (t_m, t_l) in zip(list_temp_medium, list_temp_low)]
temp_diff_dataframe = pd.DataFrame(temp_diff, data_reduct['date_time'], columns=['temp_diff'])

#Concatenate final data and save
COP_data=pd.concat([dataframe, COP, temp_diff_dataframe], axis=1)