Skip to content

Commit

Permalink
Add None as option of dhw_preferential
Browse files Browse the repository at this point in the history
  • Loading branch information
wouterpeere committed Feb 14, 2025
1 parent dc16c8b commit 7f0ecbd
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 21 deletions.
25 changes: 7 additions & 18 deletions GHEtool/Methods/optimise_load_profile.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ def optimise_load_profile_power(
use_hourly_resolution: bool = True,
max_peak_heating: float = None,
max_peak_cooling: float = None,
dhw_preferential: bool = True
dhw_preferential: bool = None
) -> tuple[HourlyBuildingLoad, HourlyBuildingLoad]:
"""
This function optimises the load for maximum power in extraction and injection based on the given borefield and
Expand All @@ -38,6 +38,7 @@ def optimise_load_profile_power(
The maximum peak power for the cooling (building side) [kW]
dhw_preferential : bool
True if heating should first be reduced only after which the dhw share is reduced.
If it is None, then the dhw profile is not optimised and kept constant.
Returns
-------
Expand Down Expand Up @@ -104,16 +105,19 @@ def optimise_load_profile_power(
if abs(min(borefield.results.peak_extraction) - borefield.Tf_min) > temperature_threshold:
# check if it goes below the threshold
if min(borefield.results.peak_extraction) < borefield.Tf_min:
if (dhw_preferential and peak_heat_load > 0.1) or (not dhw_preferential and peak_dhw_load <= 0.1):
if (dhw_preferential and peak_heat_load > 0.1) \
or (not dhw_preferential and peak_dhw_load <= 0.1) \
or dhw_preferential is None:
# first reduce the peak load in heating before touching the dhw load
# if dhw_preferential is None, it is not optimised and kept constant
peak_heat_load = max(0.1, peak_heat_load - 1 * max(1, 10 * (
borefield.Tf_min - min(borefield.results.peak_extraction))))
else:
peak_dhw_load = max(0.1, peak_dhw_load - 1 * max(1, 10 * (
borefield.Tf_min - min(borefield.results.peak_extraction))))
else:
if (dhw_preferential and peak_heat_load != init_peak_heating) or (
not dhw_preferential and 0.1 >= peak_dhw_load):
not dhw_preferential and 0.1 >= peak_dhw_load) or dhw_preferential is None:
peak_heat_load = min(init_peak_heating, peak_heat_load * 1.01)
else:
peak_dhw_load = min(init_peak_dhw, peak_dhw_load * 1.01)
Expand Down Expand Up @@ -153,7 +157,6 @@ def optimise_load_profile_energy(
temperature_threshold: float = 0.05,
max_peak_heating: float = None,
max_peak_cooling: float = None,
dhw_preferential: bool = True
) -> tuple[HourlyBuildingLoadMultiYear, HourlyBuildingLoadMultiYear]:
"""
This function optimises the load for maximum energy extraction and injection based on the given borefield and
Expand All @@ -173,8 +176,6 @@ def optimise_load_profile_energy(
The maximum peak power for heating (building side) [kW]
max_peak_cooling : float
The maximum peak power for cooling (building side) [kW]
dhw_preferential : bool
True if heating should first be reduced only after which the dhw share is reduced.
Returns
-------
Expand Down Expand Up @@ -216,7 +217,6 @@ def optimise_load_profile_energy(
# set max peak values
init_peak_heating = building_load.hourly_heating_load_simulation_period.copy()
init_peak_cooling = building_load.hourly_cooling_load_simulation_period.copy()
init_peak_dhw = building_load.hourly_dhw_load_simulation_period.copy()

# correct for max peak powers
if max_peak_heating is not None:
Expand All @@ -227,27 +227,22 @@ def optimise_load_profile_energy(
# update loads
building_load.hourly_heating_load = init_peak_heating
building_load.hourly_cooling_load = init_peak_cooling
building_load.set_hourly_dhw_load(init_peak_dhw)

# set relation qh-qm
nb_points = 100

power_heating_range = np.linspace(0.001, building_load.max_peak_heating, nb_points)
power_cooling_range = np.linspace(0.001, building_load.max_peak_cooling, nb_points)
power_dhw_range = np.linspace(0.001, building_load.max_peak_dhw, nb_points)

# relationship between the peak load and the corresponding monthly load
heating_peak_bl = np.zeros((nb_points, 12 * building_load.simulation_period))
cooling_peak_bl = np.zeros((nb_points, 12 * building_load.simulation_period))
dhw_peak_bl = np.zeros((nb_points, 12 * building_load.simulation_period))

for idx in range(nb_points):
heating_peak_bl[idx] = building_load.resample_to_monthly(
np.minimum(power_heating_range[idx], building_load.hourly_heating_load_simulation_period))[1]
cooling_peak_bl[idx] = building_load.resample_to_monthly(
np.minimum(power_cooling_range[idx], building_load.hourly_cooling_load_simulation_period))[1]
dhw_peak_bl[idx] = building_load.resample_to_monthly(
np.minimum(power_dhw_range[idx], building_load.hourly_dhw_load_simulation_period))[1]

# create monthly multi-load
monthly_load = \
Expand All @@ -266,7 +261,6 @@ def optimise_load_profile_energy(
# store initial monthly peak loads
peak_heating = copy.copy(monthly_load.monthly_peak_heating_simulation_period)
peak_cooling = copy.copy(monthly_load.monthly_peak_cooling_simulation_period)
peak_dhw = copy.copy(monthly_load.monthly_peak_dhw_simulation_period)

for i in range(12 * borefield.load.simulation_period):
# set iteration criteria
Expand Down Expand Up @@ -339,8 +333,6 @@ def f(hourly_load, monthly_peak) -> np.ndarray:
borefield.load.monthly_peak_heating_simulation_period)
borefield_load.hourly_cooling_load = f(building_load.hourly_cooling_load_simulation_period,
borefield.load.monthly_peak_cooling_simulation_period)
borefield_load.set_hourly_dhw_load = f(building_load.hourly_dhw_load_simulation_period,
borefield.load.monthly_peak_dhw_simulation_period)

# calculate external load
external_load = HourlyBuildingLoadMultiYear()
Expand All @@ -350,8 +342,5 @@ def f(hourly_load, monthly_peak) -> np.ndarray:
external_load.set_hourly_cooling_load(
np.maximum(0,
building_load_copy.hourly_cooling_load_simulation_period - borefield_load.hourly_cooling_load_simulation_period))
external_load.set_hourly_dhw_load(
np.maximum(0,
building_load_copy.hourly_dhw_load_simulation_period - borefield_load.hourly_dhw_load_simulation_period))

return borefield_load, external_load
Original file line number Diff line number Diff line change
Expand Up @@ -607,6 +607,7 @@ def _monthly_peak_extraction_heating_simulation_period(self) -> np.ndarray:
def _monthly_peak_extraction_dhw_simulation_period(self) -> np.ndarray:
"""
This function returns the monthly extraction peak of the DHW production in kW/month for the whole simulation period.
Returns
-------
peak extraction : np.ndarray
Expand Down
17 changes: 14 additions & 3 deletions GHEtool/test/methods/temp.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import numpy as np
from GHEtool.Methods.optimise_load_profile import optimise_load_profile_power

Check warning on line 4 in GHEtool/test/methods/temp.py

View check run for this annotation

Codecov / codecov/patch

GHEtool/test/methods/temp.py#L1-L4

Added lines #L1 - L4 were not covered by tests

borefield_gt = gt.boreholes.rectangle_field(10, 12, 6, 6, 110, 1, 0.075)
borefield_gt = gt.boreholes.rectangle_field(10, 12, 6, 6, 150, 4, 0.075)
hourly_load = HourlyBuildingLoad(efficiency_heating=10 ** 6, efficiency_cooling=10 ** 6, efficiency_dhw=10 ** 6)

Check warning on line 7 in GHEtool/test/methods/temp.py

View check run for this annotation

Codecov / codecov/patch

GHEtool/test/methods/temp.py#L6-L7

Added lines #L6 - L7 were not covered by tests

borefield = Borefield()
Expand All @@ -18,8 +18,19 @@
hourly_load.hourly_heating_load = np.zeros(8760)
borefield.load = hourly_load

Check warning on line 19 in GHEtool/test/methods/temp.py

View check run for this annotation

Codecov / codecov/patch

GHEtool/test/methods/temp.py#L18-L19

Added lines #L18 - L19 were not covered by tests

result = optimise_load_profile_power(borefield, hourly_load, dhw_preferential=False)
print(result[1].max_peak_heating, result[1].max_peak_cooling)
borefield_load, external_load = optimise_load_profile_power(borefield, hourly_load, dhw_preferential=True)
_percentage_extraction = (np.sum(borefield_load.hourly_heating_load_simulation_period) + np.sum(

Check warning on line 22 in GHEtool/test/methods/temp.py

View check run for this annotation

Codecov / codecov/patch

GHEtool/test/methods/temp.py#L21-L22

Added lines #L21 - L22 were not covered by tests
borefield_load.hourly_dhw_load_simulation_period)) / \
(np.sum(hourly_load.hourly_heating_load_simulation_period) + np.sum(
hourly_load.hourly_dhw_load_simulation_period)) * 100
_percentage_injection = np.sum(borefield_load.hourly_cooling_load_simulation_period) / \

Check warning on line 26 in GHEtool/test/methods/temp.py

View check run for this annotation

Codecov / codecov/patch

GHEtool/test/methods/temp.py#L26

Added line #L26 was not covered by tests
np.sum(hourly_load.hourly_cooling_load_simulation_period) * 100
print(_percentage_extraction)
print(_percentage_injection)
print(borefield_load.max_peak_extraction)
print(borefield_load.max_peak_injection)
print(external_load.max_peak_heating)
print(external_load.max_peak_cooling)

Check warning on line 33 in GHEtool/test/methods/temp.py

View check run for this annotation

Codecov / codecov/patch

GHEtool/test/methods/temp.py#L28-L33

Added lines #L28 - L33 were not covered by tests
# list_of_test_objects.add(OptimiseLoadProfileObject(borefield, hourly_load, 150, 99.976, 66.492,
# 643.137, 195.331, 33.278, 340.705,
# name='Optimise load profile 1, reversed (power, dhw not preferential)',
Expand Down

0 comments on commit 7f0ecbd

Please sign in to comment.