diff --git a/GHEtool/VariableClasses/LoadData/GeothermalLoad/HourlyGeothermalLoad.py b/GHEtool/VariableClasses/LoadData/GeothermalLoad/HourlyGeothermalLoad.py index 2d1ac3af..754dfc95 100644 --- a/GHEtool/VariableClasses/LoadData/GeothermalLoad/HourlyGeothermalLoad.py +++ b/GHEtool/VariableClasses/LoadData/GeothermalLoad/HourlyGeothermalLoad.py @@ -5,13 +5,13 @@ import warnings -from typing import Union, Tuple, TYPE_CHECKING +from typing import Tuple, TYPE_CHECKING from GHEtool.VariableClasses.LoadData._LoadData import _LoadData from GHEtool.logger import ghe_logger if TYPE_CHECKING: - from numpy.typing import ArrayLike, NDArray + from numpy.typing import ArrayLike class HourlyGeothermalLoad(_LoadData): @@ -27,7 +27,10 @@ class HourlyGeothermalLoad(_LoadData): END = pd.to_datetime("2019-12-31 23:59:00") HOURS_SERIES = pd.Series(pd.date_range(START, END, freq="1h")) - def __init__(self, heating_load: ArrayLike | None = None, cooling_load: ArrayLike | None = None, simulation_period: int = 20, dhw: float = 0.0): + def __init__(self, heating_load: ArrayLike | None = None, + cooling_load: ArrayLike | None = None, + simulation_period: int = 20, + dhw: float = 0.): """ Parameters @@ -45,15 +48,15 @@ def __init__(self, heating_load: ArrayLike | None = None, cooling_load: ArrayLik super().__init__(hourly_resolution=True, simulation_period=simulation_period) # initiate variables - self._hourly_heating_load: NDArray[np.float64] = np.zeros(8760) - self._hourly_cooling_load: NDArray[np.float64] = np.zeros(8760) + self._hourly_heating_load: np.ndarray = np.zeros(8760) + self._hourly_cooling_load: np.ndarray = np.zeros(8760) # set variables - self.hourly_heating_load: NDArray[np.float64] = np.zeros(8760) if heating_load is None else np.array(heating_load) - self.hourly_cooling_load: NDArray[np.float64] = np.zeros(8760) if cooling_load is None else np.array(cooling_load) + self.hourly_heating_load: np.ndarray = np.zeros(8760) if heating_load is None else np.array(heating_load) + self.hourly_cooling_load: np.ndarray = np.zeros(8760) if cooling_load is None else np.array(cooling_load) self.dhw = dhw - def _check_input(self, input: Union[np.ndarray, list, tuple]) -> bool: + def _check_input(self, load_array: ArrayLike) -> bool: """ This function checks whether the input is valid or not. The input is correct if and only if: @@ -63,20 +66,20 @@ def _check_input(self, input: Union[np.ndarray, list, tuple]) -> bool: Parameters ---------- - input : np.ndarray, list or tuple + load_array : np.ndarray, list or tuple Returns ------- bool True if the inputs are valid """ - if not isinstance(input, (np.ndarray, list, tuple)): + if not isinstance(load_array, (np.ndarray, list, tuple)): ghe_logger.error("The load should be of type np.ndarray, list or tuple.") return False - if not len(input) == 8760: + if not len(load_array) == 8760: ghe_logger.error("The length of the load should be 8760.") return False - if np.min(input) < 0: + if np.min(load_array) < 0: ghe_logger.error("No value in the load can be smaller than zero.") return False return True @@ -94,7 +97,7 @@ def hourly_heating_load(self) -> np.ndarray: return self.correct_for_start_month(self._hourly_heating_load + self.dhw / 8760) @hourly_heating_load.setter - def hourly_heating_load(self, load: Union[np.ndarray, list, tuple]) -> None: + def hourly_heating_load(self, load: ArrayLike) -> None: """ This function sets the hourly heating load [kWh/h] after it has been checked. @@ -118,7 +121,7 @@ def hourly_heating_load(self, load: Union[np.ndarray, list, tuple]) -> None: return raise ValueError - def set_hourly_heating(self, load: Union[np.ndarray, list, tuple]) -> None: + def set_hourly_heating(self, load: ArrayLike) -> None: """ This function sets the hourly heating load [kWh/h] after it has been checked. @@ -152,7 +155,7 @@ def hourly_cooling_load(self) -> np.ndarray: return self.correct_for_start_month(self._hourly_cooling_load) @hourly_cooling_load.setter - def hourly_cooling_load(self, load: Union[np.ndarray, list, tuple]) -> None: + def hourly_cooling_load(self, load: ArrayLike) -> None: """ This function sets the hourly cooling load [kWh/h] after it has been checked. @@ -176,7 +179,7 @@ def hourly_cooling_load(self, load: Union[np.ndarray, list, tuple]) -> None: return raise ValueError - def set_hourly_cooling(self, load: Union[np.ndarray, list, tuple]) -> None: + def set_hourly_cooling(self, load: ArrayLike) -> None: """ This function sets the hourly cooling load [kWh/h] after it has been checked. diff --git a/GHEtool/VariableClasses/LoadData/GeothermalLoad/HourlyGeothermalLoadMultiYear.py b/GHEtool/VariableClasses/LoadData/GeothermalLoad/HourlyGeothermalLoadMultiYear.py index 663036b8..7319a8e8 100644 --- a/GHEtool/VariableClasses/LoadData/GeothermalLoad/HourlyGeothermalLoadMultiYear.py +++ b/GHEtool/VariableClasses/LoadData/GeothermalLoad/HourlyGeothermalLoadMultiYear.py @@ -4,12 +4,12 @@ import numpy as np -from typing import TYPE_CHECKING, Union +from typing import TYPE_CHECKING from GHEtool.logger import ghe_logger from GHEtool.VariableClasses.LoadData.GeothermalLoad.HourlyGeothermalLoad import HourlyGeothermalLoad if TYPE_CHECKING: - from numpy.typing import ArrayLike, NDArray + from numpy.typing import ArrayLike class HourlyGeothermalLoadMultiYear(HourlyGeothermalLoad): @@ -34,7 +34,6 @@ def __init__(self, heating_load: ArrayLike | None = None, cooling_load: ArrayLik # initiate variables self._hourly_heating_load: np.ndarray = np.zeros(8760) self._hourly_cooling_load: np.ndarray = np.zeros(8760) - self.range_month: range = range(0) # set variables heating_load = np.zeros(8760) if heating_load is None and cooling_load is None else heating_load @@ -104,7 +103,6 @@ def hourly_heating_load(self, load: ArrayLike) -> None: if self._check_input(load): self._hourly_heating_load = load self.simulation_period = int(len(load) / 8760) - self.range_month = range(730, len(load) + 1, 730) return raise ValueError @@ -143,7 +141,6 @@ def hourly_cooling_load(self, load: ArrayLike) -> None: if self._check_input(load): self._hourly_cooling_load = load self.simulation_period = int(len(load) / 8760) - self.range_month = range(730, len(load) + 1, 730) return raise ValueError @@ -171,163 +168,6 @@ def hourly_heating_load_simulation_period(self) -> np.ndarray: """ return self._hourly_heating_load - @property - def baseload_cooling(self) -> np.ndarray: - """ - This function returns the baseload cooling in kWh/month. - - Returns - ------- - baseload cooling : np.ndarray - Baseload cooling values [kWh/month] for one year, so the length of the array is 12 - """ - return self.resample_to_monthly(self._hourly_cooling_load)[1] - - @property - def baseload_heating(self) -> np.ndarray: - """ - This function returns the baseload heating in kWh/month. - - Returns - ------- - baseload heating : np.ndarray - Baseload heating values [kWh/month] for one year, so the length of the array is 12 - """ - return self.resample_to_monthly(self._hourly_heating_load)[1] - - @property - def peak_cooling(self) -> np.ndarray: - """ - This function returns the peak cooling load in kW/month. - - Returns - ------- - peak cooling : np.ndarray - Peak cooling values for one year, so the length of the array is 12 - """ - return self.resample_to_monthly(self._hourly_cooling_load)[0] - - @property - def peak_heating(self) -> np.ndarray: - """ - This function returns the peak cooling load in kW/month. - - Returns - ------- - peak cooling : np.ndarray - Peak cooling values for one year, so the length of the array is 12 - """ - return self.resample_to_monthly(self._hourly_heating_load)[0] - - @property - def baseload_heating_power(self) -> np.ndarray: - """ - This function returns the baseload heating in kW avg/month. - - Returns - ------- - baseload heating : np.ndarray - """ - return self.baseload_heating / 730 - - @property - def baseload_cooling_power(self) -> np.ndarray: - """ - This function returns the baseload heating in kW avg/month. - - Returns - ------- - baseload heating : np.ndarray - """ - return self.baseload_cooling / 730 - - @property - def baseload_heating_simulation_period(self) -> np.ndarray: - """ - This function returns the baseload heating in kWh/month for a whole simulation period. - - Returns - ------- - baseload heating : np.ndarray - baseload heating for the whole simulation period - """ - return self.baseload_heating - - @property - def baseload_cooling_simulation_period(self) -> np.ndarray: - """ - This function returns the baseload cooling in kWh/month for a whole simulation period. - - Returns - ------- - baseload cooling : np.ndarray - baseload cooling for the whole simulation period - """ - return self.baseload_cooling - - @property - def peak_heating_simulation_period(self) -> np.ndarray: - """ - This function returns the peak heating in kW/month for a whole simulation period. - - Returns - ------- - peak heating : np.ndarray - peak heating for the whole simulation period - """ - return self.peak_heating - - @property - def peak_cooling_simulation_period(self) -> np.ndarray: - """ - This function returns the peak cooling in kW/month for a whole simulation period. - - Returns - ------- - peak cooling : np.ndarray - peak cooling for the whole simulation period - """ - return self.peak_cooling - - @property - def baseload_heating_power_simulation_period(self) -> np.ndarray: - """ - This function returns the avergae heating power in kW avg/month for a whole simulation period. - - Returns - ------- - average heating power : np.ndarray - average heating power for the whole simulation period - """ - return self.baseload_heating_power - - @property - def baseload_cooling_power_simulation_period(self) -> np.ndarray: - """ - This function returns the average cooling power in kW avg/month for a whole simulation period. - - Returns - ------- - average cooling power : np.ndarray - average cooling for the whole simulation period - """ - return self.baseload_cooling_power - - @property - def monthly_average_load_simulation_period(self) -> np.ndarray: - """ - This function calculates the average monthly load in kW for the whole simulation period. - - Returns - ------- - monthly average load : np.ndarray - """ - return self.monthly_average_load - - def resample_to_monthly(self, hourly_load: np.ndarray) -> tuple[np.ndarray, np.ndarray]: - res = np.array([hourly_load[i - 730 : i] for i in self.range_month]) - return np.max(res, axis=1), np.sum(res, axis=1) - def __eq__(self, other) -> bool: if not isinstance(other, HourlyGeothermalLoad): return False diff --git a/GHEtool/VariableClasses/LoadData/GeothermalLoad/MonthlyGeothermalLoadAbsolute.py b/GHEtool/VariableClasses/LoadData/GeothermalLoad/MonthlyGeothermalLoadAbsolute.py index 0eb5324d..d6b4070d 100644 --- a/GHEtool/VariableClasses/LoadData/GeothermalLoad/MonthlyGeothermalLoadAbsolute.py +++ b/GHEtool/VariableClasses/LoadData/GeothermalLoad/MonthlyGeothermalLoadAbsolute.py @@ -2,12 +2,14 @@ import numpy as np -from typing import Union +from typing import TYPE_CHECKING from GHEtool.VariableClasses.LoadData._LoadData import _LoadData from GHEtool.VariableClasses.LoadData.GeothermalLoad import HourlyGeothermalLoad from GHEtool.VariableClasses.LoadData.GeothermalLoad.HourlyGeothermalLoadMultiYear import HourlyGeothermalLoadMultiYear from GHEtool.logger.ghe_logger import ghe_logger +from numpy.typing import ArrayLike + class MonthlyGeothermalLoadAbsolute(_LoadData): """ @@ -19,10 +21,10 @@ class MonthlyGeothermalLoadAbsolute(_LoadData): def __init__( self, - baseload_heating: Union[np.ndarray, list, tuple] = np.zeros(12), - baseload_cooling: Union[np.ndarray, list, tuple] = np.zeros(12), - peak_heating: Union[np.ndarray, list, tuple] = np.zeros(12), - peak_cooling: Union[np.ndarray, list, tuple] = np.zeros(12), + baseload_heating: ArrayLike | None = None, + baseload_cooling: ArrayLike | None = None, + peak_heating: ArrayLike | None = None, + peak_cooling: ArrayLike | None = None, simulation_period: int = 20, dhw: float = 0.0, ): @@ -53,13 +55,13 @@ def __init__( self._peak_cooling: np.ndarray = np.zeros(12) # set variables - self.baseload_heating = baseload_heating - self.baseload_cooling = baseload_cooling - self.peak_heating = peak_heating - self.peak_cooling = peak_cooling + self.baseload_heating = np.zeros(12) if baseload_heating is None else baseload_heating + self.baseload_cooling = np.zeros(12) if baseload_cooling is None else baseload_cooling + self.peak_heating = np.zeros(12) if peak_heating is None else peak_heating + self.peak_cooling = np.zeros(12) if peak_cooling is None else peak_cooling self.dhw = dhw - def _check_input(self, input: Union[np.ndarray, list, tuple]) -> bool: + def _check_input(self, load_array: ArrayLike) -> bool: """ This function checks whether the input is valid or not. The input is correct if and only if: @@ -69,20 +71,20 @@ def _check_input(self, input: Union[np.ndarray, list, tuple]) -> bool: Parameters ---------- - input : np.ndarray, list or tuple + load_array : np.ndarray, list or tuple Returns ------- bool True if the inputs are valid """ - if not isinstance(input, (np.ndarray, list, tuple)): + if not isinstance(load_array, (np.ndarray, list, tuple)): ghe_logger.error("The load should be of type np.ndarray, list or tuple.") return False - if not len(input) == 12: + if not len(load_array) == 12: ghe_logger.error("The length of the load should be 12.") return False - if np.min(input) < 0: + if np.min(load_array) < 0: ghe_logger.error("No value in the load can be smaller than zero.") return False return True @@ -100,7 +102,7 @@ def baseload_cooling(self) -> np.ndarray: return self.correct_for_start_month(self._baseload_cooling) @baseload_cooling.setter - def baseload_cooling(self, load: Union[np.ndarray, list, tuple]) -> None: + def baseload_cooling(self, load: ArrayLike) -> None: """ This function sets the baseload cooling [kWh/month] after it has been checked. If the baseload cooling gives a higher average power than the peak power, @@ -126,7 +128,7 @@ def baseload_cooling(self, load: Union[np.ndarray, list, tuple]) -> None: return raise ValueError - def set_baseload_cooling(self, load: Union[np.ndarray, list, tuple]) -> None: + def set_baseload_cooling(self, load: ArrayLike) -> None: """ This function sets the baseload cooling [kWh/month] after it has been checked. If the baseload cooling gives a higher average power than the peak power, @@ -162,7 +164,7 @@ def baseload_heating(self) -> np.ndarray: return self.correct_for_start_month(self._baseload_heating + self.dhw / 8760 * self.UPM) @baseload_heating.setter - def baseload_heating(self, load: Union[np.ndarray, list, tuple]) -> None: + def baseload_heating(self, load: ArrayLike) -> None: """ This function sets the baseload heating [kWh/month] after it has been checked. If the baseload heating gives a higher average power than the peak power, @@ -188,7 +190,7 @@ def baseload_heating(self, load: Union[np.ndarray, list, tuple]) -> None: return raise ValueError - def set_baseload_heating(self, load: Union[np.ndarray, list, tuple]) -> None: + def set_baseload_heating(self, load: ArrayLike) -> None: """ This function sets the baseload heating [kWh/month] after it has been checked. If the baseload heating gives a higher average power than the peak power, @@ -249,7 +251,7 @@ def peak_cooling(self, load) -> None: return raise ValueError - def set_peak_cooling(self, load: Union[np.ndarray, list, tuple]) -> None: + def set_peak_cooling(self, load: ArrayLike) -> None: """ This function sets the peak cooling load [kW/month] after it has been checked. If the baseload cooling gives a higher average power, this is taken as the peak power in that month. @@ -284,7 +286,7 @@ def peak_heating(self) -> np.ndarray: return self.correct_for_start_month(np.maximum(np.array(self._peak_heating) + self.dhw_power, self.baseload_heating_power)) @peak_heating.setter - def peak_heating(self, load: Union[np.ndarray, list, tuple]) -> None: + def peak_heating(self, load: ArrayLike) -> None: """ This function sets the peak heating load [kW/month] after it has been checked. If the baseload heating gives a higher average power, this is taken as the peak power in that month. @@ -309,7 +311,7 @@ def peak_heating(self, load: Union[np.ndarray, list, tuple]) -> None: return raise ValueError - def set_peak_heating(self, load: Union[np.ndarray, list, tuple]) -> None: + def set_peak_heating(self, load: ArrayLike) -> None: """ This function sets the peak heating load [kW/month] after it has been checked. If the baseload heating gives a higher average power, this is taken as the peak power in that month. diff --git a/GHEtool/test/unit-tests/test_hourly_load_data.py b/GHEtool/test/unit-tests/test_hourly_load_data.py index f0eff424..16614301 100644 --- a/GHEtool/test/unit-tests/test_hourly_load_data.py +++ b/GHEtool/test/unit-tests/test_hourly_load_data.py @@ -1,9 +1,8 @@ import pytest import numpy as np -from _pytest.python_api import raises -from GHEtool import FOLDER, MonthlyGeothermalLoadMultiYear +from GHEtool import FOLDER from GHEtool.VariableClasses import HourlyGeothermalLoad, HourlyGeothermalLoadMultiYear, MonthlyGeothermalLoadAbsolute from GHEtool.Validation.cases import load_case @@ -160,21 +159,6 @@ def test_set_hourly_values_multi_year(): except ValueError: assert True - -def test_checks_multiyear_monthly(): - load = MonthlyGeothermalLoadMultiYear() - assert not load._check_input(2) - assert not load._check_input(np.ones(11)) - assert not load._check_input(-1*np.ones(12*2)) - assert load._check_input([1]*12*2) - assert load._check_input(np.ones(12)) - assert load._check_input(np.ones(12 * 3)) - assert not load._check_input(np.ones(30)) - with raises(ValueError): - load.baseload_heating = np.ones(13) - with raises(ValueError): - load.baseload_cooling = np.ones(13) - def test_dhw(): load = HourlyGeothermalLoad() assert load.dhw == 0. diff --git a/GHEtool/test/unit-tests/test_monthly_load_data.py b/GHEtool/test/unit-tests/test_monthly_load_data.py index e93fe68d..f3c9bdf8 100644 --- a/GHEtool/test/unit-tests/test_monthly_load_data.py +++ b/GHEtool/test/unit-tests/test_monthly_load_data.py @@ -2,9 +2,11 @@ import numpy as np -from GHEtool.VariableClasses import MonthlyGeothermalLoadAbsolute, HourlyGeothermalLoad +from GHEtool.VariableClasses import MonthlyGeothermalLoadAbsolute, HourlyGeothermalLoad, MonthlyGeothermalLoadMultiYear from GHEtool.Validation.cases import load_case +from _pytest.python_api import raises + def test_checks(): load = MonthlyGeothermalLoadAbsolute() @@ -376,3 +378,18 @@ def test_different_start_month(): assert np.array_equal(load.baseload_cooling, result) assert np.array_equal(load.peak_heating, result) assert np.array_equal(load.peak_cooling, result) + + +def test_checks_multiyear_monthly(): + load = MonthlyGeothermalLoadMultiYear() + assert not load._check_input(2) + assert not load._check_input(np.ones(11)) + assert not load._check_input(-1*np.ones(12*2)) + assert load._check_input([1]*12*2) + assert load._check_input(np.ones(12)) + assert load._check_input(np.ones(12 * 3)) + assert not load._check_input(np.ones(30)) + with raises(ValueError): + load.baseload_heating = np.ones(13) + with raises(ValueError): + load.baseload_cooling = np.ones(13)