Skip to content

Commit d8e0c25

Browse files
authored
Merge pull request #407 from wouterpeere/issue406-speed-up-optimise-for-energy
Issue406 speed up optimise for energy
2 parents 308f66a + 8a804db commit d8e0c25

File tree

4 files changed

+143
-34
lines changed

4 files changed

+143
-34
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
1919
- Return multiyear external load if multiyear load is given as an input (issue #380).
2020
- Change how DHW is stored in the classes (issue #381).
2121
- Speed up calculate required depth (issue #403).
22+
- Speed up optimise energy profile (issue #406).
2223

2324
### Fixed
2425

GHEtool/Methods/optimise_load_profile.py

Lines changed: 46 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from math import pi
55
from typing import Union
66
from GHEtool.VariableClasses import HourlyBuildingLoad, MonthlyBuildingLoadMultiYear, HourlyBuildingLoadMultiYear, \
7-
ConstantFluidData, ConstantFlowRate, TemperatureDependentFluidData, EERCombined
7+
ConstantFluidData, ConstantFlowRate, TemperatureDependentFluidData, EERCombined, SCOP, SEER
88
from GHEtool.VariableClasses.LoadData.Baseclasses import _LoadDataBuilding
99

1010

@@ -105,19 +105,19 @@ def optimise_load_profile_power(
105105
borefield.calculate_temperatures(length=borefield.H, hourly=use_hourly_resolution)
106106

107107
# deviation from minimum temperature
108-
if abs(min(borefield.results.peak_extraction) - borefield.Tf_min) > temperature_threshold:
108+
if abs(borefield.results.min_temperature - borefield.Tf_min) > temperature_threshold:
109109
# check if it goes below the threshold
110-
if min(borefield.results.peak_extraction) < borefield.Tf_min:
110+
if borefield.results.min_temperature < borefield.Tf_min:
111111
if (dhw_preferential and peak_heat_load > 0.1) \
112112
or (not dhw_preferential and peak_dhw_load <= 0.1) \
113113
or dhw_preferential is None:
114114
# first reduce the peak load in heating before touching the dhw load
115115
# if dhw_preferential is None, it is not optimised and kept constant
116116
peak_heat_load = max(0.1, peak_heat_load - 1 * max(1, 10 * (
117-
borefield.Tf_min - min(borefield.results.peak_extraction))))
117+
borefield.Tf_min - borefield.results.min_temperature)))
118118
else:
119119
peak_dhw_load = max(0.1, peak_dhw_load - 1 * max(1, 10 * (
120-
borefield.Tf_min - min(borefield.results.peak_extraction))))
120+
borefield.Tf_min - borefield.results.min_temperature)))
121121
heat_ok = False
122122
else:
123123
if (dhw_preferential and peak_heat_load != init_peak_heating) or (
@@ -131,11 +131,11 @@ def optimise_load_profile_power(
131131
heat_ok = True
132132

133133
# deviation from maximum temperature
134-
if abs(np.max(borefield.results.peak_injection) - borefield.Tf_max) > temperature_threshold:
134+
if abs(borefield.results.max_temperature - borefield.Tf_max) > temperature_threshold:
135135
# check if it goes above the threshold
136-
if np.max(borefield.results.peak_injection) > borefield.Tf_max:
136+
if borefield.results.max_temperature > borefield.Tf_max:
137137
peak_cool_load = max(0.1, peak_cool_load - 1 * max(1, 10 * (
138-
-borefield.Tf_max + np.max(borefield.results.peak_injection))))
138+
-borefield.Tf_max + borefield.results.max_temperature)))
139139
cool_ok = False
140140
else:
141141
peak_cool_load = min(init_peak_cooling, peak_cool_load * 1.01)
@@ -301,11 +301,35 @@ def optimise_load_profile_energy(
301301
g_value = borefield.gfunction(borefield.load.time_L3, borefield.H)[0]
302302
k_s = borefield.ground_data.k_s(borefield.calculate_depth(borefield.H, borefield.D), borefield.D)
303303

304+
Rb_min_const = borefield.borehole.get_Rb(borefield.H, borefield.D,
305+
borefield.r_b,
306+
k_s, borefield.depth,
307+
temperature=borefield.Tf_min)
308+
Rb_max_const = borefield.borehole.get_Rb(borefield.H,
309+
borefield.D,
310+
borefield.r_b,
311+
k_s, borefield.depth,
312+
temperature=borefield.Tf_max)
313+
variable_efficiency = isinstance(borefield.load, _LoadDataBuilding) and not (
314+
isinstance(borefield.load.cop, SCOP) and isinstance(borefield.load.cop_dhw, SCOP) and isinstance(
315+
borefield.load.eer, SEER))
316+
304317
def update_last_month(idx, init_load) -> (float, float):
305318
def calculate(Tmin: float = None, Tmax: float = None, *args):
306-
if Tmin is None:
307-
Tmin = borefield.Tf_min
308-
Tmax = borefield.Tf_max
319+
if Tmin is None or (not variable_efficiency and borefield.USE_SPEED_UP_IN_SIZING):
320+
Rb_min = Rb_min_const
321+
Rb_max = Rb_max_const
322+
else:
323+
Rb_min = borefield.borehole.get_Rb(borefield.H, borefield.D,
324+
borefield.r_b,
325+
k_s, borefield.depth,
326+
temperature=Tmin)
327+
Rb_max = borefield.borehole.get_Rb(borefield.H,
328+
borefield.D,
329+
borefield.r_b,
330+
k_s, borefield.depth,
331+
temperature=Tmax)
332+
309333
Tb = borefield.results.Tb[idx]
310334

311335
# convert to result
@@ -321,30 +345,22 @@ def calculate(Tmin: float = None, Tmax: float = None, *args):
321345
# calculate new temperature
322346
extraction = Tb + \
323347
(-borefield.load.monthly_peak_extraction_simulation_period[idx] *
324-
(g_value_peak_extraction / (k_s * 2 * pi) + borefield.borehole.get_Rb(borefield.H,
325-
borefield.D,
326-
borefield.r_b,
327-
k_s, borefield.depth,
328-
temperature=Tmin))
348+
(g_value_peak_extraction / (k_s * 2 * pi) + Rb_min)
329349
+ borefield.load.monthly_baseload_extraction_power_simulation_period[idx] *
330350
(g_value_peak_extraction / (
331351
k_s * 2 * pi))) * 1000 / borefield.number_of_boreholes / borefield.H
332352

333353
injection = Tb + \
334354
(borefield.load.monthly_peak_injection_simulation_period[idx] *
335-
(g_value_peak_injection / (k_s * 2 * pi) + borefield.borehole.get_Rb(borefield.H, borefield.D,
336-
borefield.r_b,
337-
k_s, borefield.depth,
338-
temperature=Tmax))
355+
(g_value_peak_injection / (k_s * 2 * pi) + Rb_max)
339356
- borefield.load.monthly_baseload_injection_power_simulation_period[idx] *
340357
(g_value_peak_injection / (k_s * 2 * pi))) * 1000 / borefield.number_of_boreholes / borefield.H
341358
return extraction, injection, Tb
342359

343360
# add some iteration for convergence
344361
# check if active_passive, because then, threshold should be taken
345362
if isinstance(borefield.load, _LoadDataBuilding) and \
346-
isinstance(borefield.load.eer,
347-
EERCombined) and borefield.load.eer.threshold_temperature is not None:
363+
isinstance(borefield.load.eer, EERCombined) and borefield.load.eer.threshold_temperature is not None:
348364
borefield.load.reset_results(borefield.Tf_min, borefield.load.eer.threshold_temperature)
349365
else:
350366
borefield.load.reset_results(borefield.Tf_min, borefield.Tf_max)
@@ -389,6 +405,7 @@ def calculate_difference(results_old, result_new) -> float:
389405
if abs(peak_extraction - borefield.Tf_min) > temperature_threshold:
390406
# check if it goes below the threshold
391407
current_heating_peak = borefield.load.monthly_peak_heating_simulation_period[i]
408+
392409
if peak_extraction < borefield.Tf_min:
393410
current_heating_peak = max(0.1, current_heating_peak - 1 * max(1, 10 * (
394411
borefield.Tf_min - peak_extraction)))
@@ -498,7 +515,7 @@ def optimise_load_profile_balance(
498515
imbalance_factor : float
499516
Maximum allowed imbalance w.r.t. to the maximum of either the heat injection or extraction.
500517
It should be given in a range of 0-1. At 1, it converges to the solution for optimise for power.
501-
518+
502519
Returns
503520
-------
504521
tuple [HourlyBuildingLoad, HourlyBuildingLoad] or tuple [HourlyBuildingLoadMultiYear, HourlyBuildingLoadMultiYear]
@@ -569,20 +586,20 @@ def optimise_load_profile_balance(
569586
imbalance = borefield.load.imbalance / np.maximum(borefield.load.yearly_average_injection_load,
570587
borefield.load.yearly_average_extraction_load)
571588
# deviation from minimum temperature
572-
if abs(min(borefield.results.peak_extraction) - borefield.Tf_min) > temperature_threshold or \
589+
if abs(borefield.results.min_temperature - borefield.Tf_min) > temperature_threshold or \
573590
(abs(imbalance) > imbalance_factor and imbalance < 0):
574591
# check if it goes below the threshold
575-
if min(borefield.results.peak_extraction) < borefield.Tf_min:
592+
if borefield.results.min_temperature < borefield.Tf_min:
576593
if (dhw_preferential and peak_heat_load > 0.1) \
577594
or (not dhw_preferential and peak_dhw_load <= 0.1) \
578595
or dhw_preferential is None:
579596
# first reduce the peak load in heating before touching the dhw load
580597
# if dhw_preferential is None, it is not optimised and kept constant
581598
peak_heat_load = max(0.1, peak_heat_load - 1 * max(1, 10 * (
582-
borefield.Tf_min - min(borefield.results.peak_extraction))))
599+
borefield.Tf_min - borefield.results.min_temperature)))
583600
else:
584601
peak_dhw_load = max(0.1, peak_dhw_load - 1 * max(1, 10 * (
585-
borefield.Tf_min - min(borefield.results.peak_extraction))))
602+
borefield.Tf_min - borefield.results.min_temperature)))
586603
heat_ok = False
587604
else:
588605
if abs(imbalance) > imbalance_factor and imbalance < 0:
@@ -610,12 +627,12 @@ def optimise_load_profile_balance(
610627
heat_ok = True
611628

612629
# deviation from maximum temperature
613-
if abs(np.max(borefield.results.peak_injection) - borefield.Tf_max) > temperature_threshold or \
630+
if abs(borefield.results.max_temperature - borefield.Tf_max) > temperature_threshold or \
614631
(abs(imbalance) > imbalance_factor and imbalance > 0):
615632
# check if it goes above the threshold
616633
if np.max(borefield.results.peak_injection) > borefield.Tf_max:
617634
peak_cool_load = max(0.1, peak_cool_load - 1 * max(1, 10 * (
618-
-borefield.Tf_max + np.max(borefield.results.peak_injection))))
635+
-borefield.Tf_max + borefield.results.max_temperature)))
619636
cool_ok = False
620637
else:
621638
if abs(imbalance) > imbalance_factor and imbalance > 0:

0 commit comments

Comments
 (0)