From 56182a65b3465ecdfc7758193834a4aa1d25ba75 Mon Sep 17 00:00:00 2001 From: wouterpeere Date: Thu, 18 Jan 2024 12:43:13 +0100 Subject: [PATCH 1/6] Changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 74f18051..4e010b89 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ## [2.2.1] - 2024-01-18 ## Added +- Possibility to start in another month (issue #140). - Equal functions for HourlyGeothermalLoad and MonthlyGeothermalLoadAbsolute (issue #189). - Cylindrical borehole correction (issue #187). - __add__ functionality for the load classes (issue #202). From 5cfd9a94b7f66fb174b053adf3df003c5dd68413 Mon Sep 17 00:00:00 2001 From: wouterpeere Date: Thu, 18 Jan 2024 15:26:40 +0100 Subject: [PATCH 2/6] implement start month --- GHEtool/VariableClasses/LoadData/_LoadData.py | 57 +++++++++++++++++++ .../test/unit-tests/test_monthly_load_data.py | 28 +++++++++ 2 files changed, 85 insertions(+) diff --git a/GHEtool/VariableClasses/LoadData/_LoadData.py b/GHEtool/VariableClasses/LoadData/_LoadData.py index 145259ae..7c67d8e8 100644 --- a/GHEtool/VariableClasses/LoadData/_LoadData.py +++ b/GHEtool/VariableClasses/LoadData/_LoadData.py @@ -35,6 +35,44 @@ def __init__(self, hourly_resolution: bool, simulation_period: int = DEFAULT_SIM self.tm: int = _LoadData.AVG_UPM * 3600 # time in a month in seconds self._all_months_equal: bool = True # true if it is assumed that all months are of the same length self._dhw_yearly: float = 0. + self._start_month: float = 0 + + @property + def start_month(self) -> int: + """ + This function returns the start month. + + Returns + ------- + float + Start month + """ + return self._start_month + + @start_month.setter + def start_month(self, month: int) -> None: + """ + This function sets the start month. + + Parameters + ---------- + month : int + Start month (jan: 1, feb: 2 ...) + + Returns + ------- + None + + Raises + ---------- + ValueError + When the start month is smaller than 1, larger than 12 or non-integer + """ + + if not isinstance(month, int) or month < 1 or month > 12: + raise ValueError(f'The value for month is: {month} which is not an integer in [1,12].') + + self._start_month = month @property def all_months_equal(self) -> bool: @@ -626,3 +664,22 @@ def dhw_power(self) -> float: dhw power : float """ return self._dhw_yearly / 8760 + + @abc.abstractmethod + def correct_for_start_month(self, array: np.ndarray, start_month) -> np.ndarray: + """ + This function corrects the load for the correct start month. + If the simulation starts in september, the start month is 9 and hence the array should start + at index 9. + + Parameters + ---------- + array : np.ndarray + Load array + start_month : int + Start month + + Returns + ------- + load : np.ndarray + """ diff --git a/GHEtool/test/unit-tests/test_monthly_load_data.py b/GHEtool/test/unit-tests/test_monthly_load_data.py index 192e9322..0162405d 100644 --- a/GHEtool/test/unit-tests/test_monthly_load_data.py +++ b/GHEtool/test/unit-tests/test_monthly_load_data.py @@ -15,6 +15,30 @@ def test_checks(): assert load._check_input(np.ones(12)) +def test_start_month_general(): + load = MonthlyGeothermalLoadAbsolute() + assert load.start_month == 1 + try: + load.start_month = 1.5 + assert False # pragma: no cover + except ValueError: + assert True + try: + load.start_month = 0 + assert False # pragma: no cover + except ValueError: + assert True + try: + load.start_month = 13 + assert False # pragma: no cover + except ValueError: + assert True + load.start_month = 12 + assert load.start_month == 12 + load.start_month = 1 + assert load.start_month == 1 + + def test_imbalance(): load = MonthlyGeothermalLoadAbsolute(np.ones(12)*10, np.ones(12), np.ones(12), np.ones(12)) assert load.imbalance == -108 @@ -33,6 +57,7 @@ def test_baseload_heating(): assert np.array_equal(load.baseload_heating_power, load.peak_heating) try: load.set_baseload_heating(np.ones(11)) + assert False # pragma: no cover except ValueError: assert True @@ -49,6 +74,7 @@ def test_baseload_cooling(): try: load.set_baseload_cooling(np.ones(11)) + assert False # pragma: no cover except ValueError: assert True @@ -64,6 +90,7 @@ def test_peak_heating(): assert np.array_equal(load.peak_heating, np.array([5., 5., 5., 5., 5., 6., 7., 8., 9., 10., 11., 12.])) try: load.set_peak_heating(np.ones(11)) + assert False # pragma: no cover except ValueError: assert True @@ -79,6 +106,7 @@ def test_peak_cooling(): assert np.array_equal(load.peak_cooling, np.array([5., 5., 5., 5., 5., 6., 7., 8., 9., 10., 11., 12.])) try: load.set_peak_cooling(np.ones(11)) + assert False # pragma: no cover except ValueError: assert True From 9ecc18e97c7ddf5f88827b1f0821df87f9e91aa9 Mon Sep 17 00:00:00 2001 From: wouterpeere Date: Thu, 18 Jan 2024 16:15:58 +0100 Subject: [PATCH 3/6] Implement tests --- .../GeothermalLoad/HourlyGeothermalLoad.py | 35 ++++++++++++++- .../MonthlyGeothermalLoadAbsolute.py | 31 +++++++++++-- GHEtool/VariableClasses/LoadData/_LoadData.py | 6 +-- .../test/unit-tests/test_hourly_load_data.py | 43 +++++++++++++++++++ .../test/unit-tests/test_monthly_load_data.py | 13 ++++++ 5 files changed, 118 insertions(+), 10 deletions(-) diff --git a/GHEtool/VariableClasses/LoadData/GeothermalLoad/HourlyGeothermalLoad.py b/GHEtool/VariableClasses/LoadData/GeothermalLoad/HourlyGeothermalLoad.py index bc9d241b..930f5c74 100644 --- a/GHEtool/VariableClasses/LoadData/GeothermalLoad/HourlyGeothermalLoad.py +++ b/GHEtool/VariableClasses/LoadData/GeothermalLoad/HourlyGeothermalLoad.py @@ -94,7 +94,7 @@ def hourly_heating_load(self) -> np.ndarray: hourly heating : np.ndarray Hourly heating values (incl. DHW) [kWh/h] for one year, so the length of the array is 8760 """ - return self._hourly_heating_load + self.dhw / 8760 + 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: @@ -152,7 +152,7 @@ def hourly_cooling_load(self) -> np.ndarray: hourly cooling : np.ndarray Hourly cooling values [kWh/h] for one year, so the length of the array is 8760 """ - return self._hourly_cooling_load + 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: @@ -387,3 +387,34 @@ def __add__(self, other): return other.__add__(self) except TypeError: # pragma: no cover raise TypeError('Cannot perform addition. Please check if you use correct classes.') # pragma: no cover + + @property + def _start_hour(self) -> int: + """ + This function returns the hour at which the year starts based on the start month. + + Returns + ------- + int + Start hour of the year + """ + return int(np.sum([self.UPM[i] for i in range(self.start_month - 1)])) + + def correct_for_start_month(self, array: np.ndarray) -> np.ndarray: + """ + This function corrects the load for the correct start month. + If the simulation starts in september, the start month is 9 and hence the array should start + at index 9. + + Parameters + ---------- + array : np.ndarray + Load array + + Returns + ------- + load : np.ndarray + """ + if self.start_month == 1: + return array + return np.concatenate((array[self._start_hour:], array[:self._start_hour])) diff --git a/GHEtool/VariableClasses/LoadData/GeothermalLoad/MonthlyGeothermalLoadAbsolute.py b/GHEtool/VariableClasses/LoadData/GeothermalLoad/MonthlyGeothermalLoadAbsolute.py index e6003583..ed89389f 100644 --- a/GHEtool/VariableClasses/LoadData/GeothermalLoad/MonthlyGeothermalLoadAbsolute.py +++ b/GHEtool/VariableClasses/LoadData/GeothermalLoad/MonthlyGeothermalLoadAbsolute.py @@ -95,7 +95,8 @@ def baseload_cooling(self) -> np.ndarray: baseload cooling : np.ndarray Baseload cooling values [kWh/month] for one year, so the length of the array is 12 """ - return self._baseload_cooling + return self.correct_for_start_month( + self._baseload_cooling) @baseload_cooling.setter def baseload_cooling(self, load: Union[np.ndarray, list, tuple]) -> None: @@ -157,7 +158,8 @@ def baseload_heating(self) -> np.ndarray: baseload heating : np.ndarray Baseload heating values (incl. DHW) [kWh/month] for one year, so the length of the array is 12 """ - return self._baseload_heating + self.dhw / 8760 * self.UPM + 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: @@ -219,7 +221,8 @@ def peak_cooling(self) -> np.ndarray: peak cooling : np.ndarray Peak cooling values for one year, so the length of the array is 12 """ - return np.maximum(self._peak_cooling, self.baseload_cooling_power) + return self.correct_for_start_month( + np.maximum(self._peak_cooling, self.baseload_cooling_power)) @peak_cooling.setter def peak_cooling(self, load) -> None: @@ -279,7 +282,8 @@ def peak_heating(self) -> np.ndarray: peak heating : np.ndarray Peak heating values for one year, so the length of the array is 12 """ - return np.maximum(np.array(self._peak_heating) + self.dhw_power, self.baseload_heating_power) + 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: @@ -397,3 +401,22 @@ def __add__(self, other): return result raise TypeError('Cannot perform addition. Please check if you use correct classes.') + + def correct_for_start_month(self, array: np.ndarray) -> np.ndarray: + """ + This function corrects the load for the correct start month. + If the simulation starts in september, the start month is 9 and hence the array should start + at index 9. + + Parameters + ---------- + array : np.ndarray + Load array + + Returns + ------- + load : np.ndarray + """ + if self.start_month == 1: + return array + return np.concatenate((array[self.start_month-1:], array[:self.start_month-1])) diff --git a/GHEtool/VariableClasses/LoadData/_LoadData.py b/GHEtool/VariableClasses/LoadData/_LoadData.py index 7c67d8e8..1335bdb1 100644 --- a/GHEtool/VariableClasses/LoadData/_LoadData.py +++ b/GHEtool/VariableClasses/LoadData/_LoadData.py @@ -35,7 +35,7 @@ def __init__(self, hourly_resolution: bool, simulation_period: int = DEFAULT_SIM self.tm: int = _LoadData.AVG_UPM * 3600 # time in a month in seconds self._all_months_equal: bool = True # true if it is assumed that all months are of the same length self._dhw_yearly: float = 0. - self._start_month: float = 0 + self._start_month: float = 1 @property def start_month(self) -> int: @@ -666,7 +666,7 @@ def dhw_power(self) -> float: return self._dhw_yearly / 8760 @abc.abstractmethod - def correct_for_start_month(self, array: np.ndarray, start_month) -> np.ndarray: + def correct_for_start_month(self, array: np.ndarray) -> np.ndarray: """ This function corrects the load for the correct start month. If the simulation starts in september, the start month is 9 and hence the array should start @@ -676,8 +676,6 @@ def correct_for_start_month(self, array: np.ndarray, start_month) -> np.ndarray: ---------- array : np.ndarray Load array - start_month : int - Start month Returns ------- diff --git a/GHEtool/test/unit-tests/test_hourly_load_data.py b/GHEtool/test/unit-tests/test_hourly_load_data.py index 16be9933..83e50adc 100644 --- a/GHEtool/test/unit-tests/test_hourly_load_data.py +++ b/GHEtool/test/unit-tests/test_hourly_load_data.py @@ -368,3 +368,46 @@ def test_add_multiyear(): assert False # pragma: no cover except TypeError: assert True + + +def test_start_month_general(): + load = HourlyGeothermalLoad() + assert load.start_month == 1 + try: + load.start_month = 1.5 + assert False # pragma: no cover + except ValueError: + assert True + try: + load.start_month = 0 + assert False # pragma: no cover + except ValueError: + assert True + try: + load.start_month = 13 + assert False # pragma: no cover + except ValueError: + assert True + load.start_month = 12 + assert load.start_month == 12 + assert load._start_hour == 11 * 730 + load.start_month = 1 + assert load.start_month == 1 + assert load._start_hour == 0 + load.start_month = 3 + assert load.start_month == 3 + assert load._start_hour == 730 * 2 + + load.all_months_equal = False + assert load._start_hour == 1416 + + +def test_different_start_month(): + load = HourlyGeothermalLoad(np.arange(1, 8761, 1), np.arange(1, 8761, 1)) + load.start_month = 3 + assert load.start_month == 3 + assert load.hourly_cooling_load[0] == 731 * 2 - 1 + assert load.hourly_heating_load[0] == 731 * 2 - 1 + load.all_months_equal = False + assert load.hourly_cooling_load[0] == 1417 + assert load.hourly_heating_load[0] == 1417 diff --git a/GHEtool/test/unit-tests/test_monthly_load_data.py b/GHEtool/test/unit-tests/test_monthly_load_data.py index 0162405d..e93fe68d 100644 --- a/GHEtool/test/unit-tests/test_monthly_load_data.py +++ b/GHEtool/test/unit-tests/test_monthly_load_data.py @@ -363,3 +363,16 @@ def test_add(): load_hourly.simulation_period = 20 with pytest.warns(): result = load_1 + load_hourly + + +def test_different_start_month(): + load = MonthlyGeothermalLoadAbsolute(baseload_heating=np.arange(1, 13, 1), + baseload_cooling=np.arange(1, 13, 1), + peak_cooling=np.arange(1, 13, 1), + peak_heating=np.arange(1, 13, 1)) + load.start_month = 2 + result = np.array([2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 1]) + assert np.array_equal(load.baseload_heating, result) + assert np.array_equal(load.baseload_cooling, result) + assert np.array_equal(load.peak_heating, result) + assert np.array_equal(load.peak_cooling, result) From edeb7f7c3362f83403d9d3b0cdebee1b3bb4ec79 Mon Sep 17 00:00:00 2001 From: wouterpeere Date: Thu, 18 Jan 2024 17:05:59 +0100 Subject: [PATCH 4/6] Added example --- GHEtool/Examples/start_in_different_month.py | 43 +++++++++++++++++++ GHEtool/test/methods/cases/test_BS2023.py | 1 - GHEtool/test/test_examples.py | 6 +++ .../Examples/start_in_different_month.rst | 7 +++ docs/sources/code/examples.md | 1 + 5 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 GHEtool/Examples/start_in_different_month.py delete mode 100644 GHEtool/test/methods/cases/test_BS2023.py create mode 100644 docs/sources/code/Examples/start_in_different_month.rst diff --git a/GHEtool/Examples/start_in_different_month.py b/GHEtool/Examples/start_in_different_month.py new file mode 100644 index 00000000..503f3db4 --- /dev/null +++ b/GHEtool/Examples/start_in_different_month.py @@ -0,0 +1,43 @@ +""" +This example illustrates the importance of when a borefield is 'started' (i.e. when the first month of operation is). +""" + +from GHEtool import * +from GHEtool.Validation.cases import load_case + +import matplotlib.pyplot as plt + + +def start_in_different_month(): + # set data + ground_data = GroundTemperatureGradient(2.5, 10) + load = MonthlyGeothermalLoadAbsolute(*load_case(1)) + + # create borefield object + borefield = Borefield(load=load) + borefield.ground_data = ground_data + borefield.create_rectangular_borefield(10, 8, 6, 6, 100) + + borefield.set_max_avg_fluid_temperature(17) + borefield.set_min_avg_fluid_temperature(3) + borefield.calculation_setup(max_nb_of_iterations=100) + + depth_list = [] + + # iterate over all the start months + for month in range(1, 13, 1): + borefield.load.start_month = month + depth_list.append(borefield.size_L3()) + + plt.figure() + plt.bar(range(1, 13, 1), depth_list) + plt.ylabel('Required depth [m]') + plt.xlabel('First month of operation') + plt.xlim(0) + plt.ylim(0) + plt.title('Required depth as a function of the first month of operation') + plt.show() + + +if __name__ == "__main__": # pragma: no cover + start_in_different_month() diff --git a/GHEtool/test/methods/cases/test_BS2023.py b/GHEtool/test/methods/cases/test_BS2023.py deleted file mode 100644 index 8b137891..00000000 --- a/GHEtool/test/methods/cases/test_BS2023.py +++ /dev/null @@ -1 +0,0 @@ - diff --git a/GHEtool/test/test_examples.py b/GHEtool/test/test_examples.py index a66dfd4d..a51c3192 100644 --- a/GHEtool/test/test_examples.py +++ b/GHEtool/test/test_examples.py @@ -65,3 +65,9 @@ def test_optimise_load_profile(monkeypatch): # optimise the load for a 10x10 field (see data above) and a fixed depth of 150m. borefield.optimise_load_profile(load, depth=150, print_results=True) + + +def test_start_in_different_month(monkeypatch): + monkeypatch.setattr(plt, 'show', lambda: None) + from GHEtool.Examples.start_in_different_month import start_in_different_month + start_in_different_month() \ No newline at end of file diff --git a/docs/sources/code/Examples/start_in_different_month.rst b/docs/sources/code/Examples/start_in_different_month.rst new file mode 100644 index 00000000..548c238e --- /dev/null +++ b/docs/sources/code/Examples/start_in_different_month.rst @@ -0,0 +1,7 @@ +*********************************************************** +Start simulation in a different month +*********************************************************** + +.. literalinclude:: ../../../../GHEtool/Examples/start_in_different_month.py + :language: python + :linenos: \ No newline at end of file diff --git a/docs/sources/code/examples.md b/docs/sources/code/examples.md index ce5a227e..f7729b61 100644 --- a/docs/sources/code/examples.md +++ b/docs/sources/code/examples.md @@ -10,4 +10,5 @@ Examples/import_data.rst Examples/main_functionalities.rst Examples/optimise_load_profile.rst Examples/sizing_with_Rb_calculation.rst +Examples/start_in_different_month.rst ``` \ No newline at end of file From c03d4b4a8066d8e49ac0a156f659aabde802895a Mon Sep 17 00:00:00 2001 From: wouterpeere Date: Thu, 18 Jan 2024 17:15:00 +0100 Subject: [PATCH 5/6] Fix broken image in README --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 5fd5f405..cf26ba56 100644 --- a/README.md +++ b/README.md @@ -26,15 +26,15 @@ GHEtool Pro is the official and supported version of GHEtool which supports dril With GHEtool Pro they can minimize the environmental and societal impact while maximizing the cost-effective utilization of geothermal projects. Visit our website at [https://ghetool.eu](https://ghetool.eu) to learn more about the synergy between this open-source package and GHEtool Pro. +

+ +

+ #### GHEtool Community Besides GHEtool Pro, an open-source alternative for the graphical user interface is available in the form of *GHEtool Community*. This version is built and maintained by the community, and **has no official support like GHEtool Pro**. You can read all about this *GHEtool Community* on their [GitHub repo](https://github.com/wouterpeere/ghetool-gui). -

- -

- ### Development GHEtool is in constant development with new methods, enhancements and features added to every new version. Please visit our [project board](https://github.com/users/wouterpeere/projects/2) to check our progress. From b43d28974814699d9ad1e9b7f559f2068a502c6c Mon Sep 17 00:00:00 2001 From: wouterpeere Date: Thu, 18 Jan 2024 17:19:36 +0100 Subject: [PATCH 6/6] Fix broken icon --- README.md | 4 ++-- docs/Icon.png | Bin 0 -> 24580 bytes 2 files changed, 2 insertions(+), 2 deletions(-) create mode 100644 docs/Icon.png diff --git a/README.md b/README.md index cf26ba56..13f760db 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ [![Downloads](https://static.pepy.tech/personalized-badge/ghetool?period=week&units=international_system&left_color=black&right_color=orange&left_text=Downloads%20last%20week)](https://pepy.tech/project/ghetool) [![Read the Docs](https://readthedocs.org/projects/ghetool/badge/?version=latest)](https://ghetool.readthedocs.io/en/latest/) ## What is *GHEtool*? - + GHEtool is a Python package that contains all the functionalities needed to deal with borefield design. GHEtool has been developed as a joint effort of KU Leuven (The SySi Team), boydens engineering (part of Sweco) and FH Aachen. The core of this package is the automated sizing of borefield under different conditions. By making use of combination of just-in-time calculations of thermal ground responses (using [pygfunction](https://github.com/MassimoCimmino/pygfunction)) with @@ -27,7 +27,7 @@ With GHEtool Pro they can minimize the environmental and societal impact while m Visit our website at [https://ghetool.eu](https://ghetool.eu) to learn more about the synergy between this open-source package and GHEtool Pro.

- +

#### GHEtool Community diff --git a/docs/Icon.png b/docs/Icon.png new file mode 100644 index 0000000000000000000000000000000000000000..29c1026065b339aac8255d571174207e9433e0f2 GIT binary patch literal 24580 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