Skip to content

Commit aa1a4df

Browse files
authored
Merge pull request #427 from wouterpeere/explicit_models
Explicit models
2 parents 6abb9d0 + 6aa6be1 commit aa1a4df

37 files changed

+1817
-330
lines changed

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
1616
- Add set_min_fluid_temperature and set_max_fluid_temperature to the Borefield class (issue #271).
1717
- Add flow per borefield to flow classes (issue #408).
1818
- Average baseload fluid temperature (issue #418).
19+
- Explicit formulations of the multipole method (issue #425).
20+
- Convective resistance calculation with array inputs (issue #425).
21+
- Option to change pipe configuration in MultipleUTube (either diagonal (default) or adjacent) (issue #425).
1922

2023
## Changed
2124

@@ -27,6 +30,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
2730
- Remove Python 3.9 compatibility (issue #420).
2831
- Change default test to 3.13 instead of 3.12 (issue #420).
2932

33+
## Fixed
34+
35+
- Fixed minor mistake in Separatus Rb* calculation (issue #425).
36+
3037
## [2.4.0] - 2025-12-19
3138

3239
### Added

GHEtool/Borefield.py

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -583,7 +583,8 @@ def Rb(self) -> float:
583583
"""
584584
return self.borehole.get_Rb(self.H, self.D, self.r_b, self.ground_data.k_s, self.depth,
585585
temperature=self.results.min_temperature if self.results.min_temperature is not None else self.Tf_min,
586-
nb_of_boreholes=self.number_of_boreholes)
586+
nb_of_boreholes=self.number_of_boreholes,
587+
use_explicit_models=self._calculation_setup.use_explicit_multipole)
587588

588589
@Rb.setter
589590
def Rb(self, Rb: float) -> None:
@@ -908,7 +909,9 @@ def _Ahmadfard(self, th: float, qh: float, qm: float, qa: float, Tf: float) -> f
908909
# calculate the total borehole length
909910
L = (qa * Ra + qm * Rm + qh * Rd + qh *
910911
self.borehole.get_Rb(self.H, self.D, self.r_b, self.ground_data.k_s, self.depth, temperature=Tfint,
911-
nb_of_boreholes=self.number_of_boreholes)) / abs(Tfint - self._Tg())
912+
nb_of_boreholes=self.number_of_boreholes,
913+
use_explicit_models=self._calculation_setup.use_explicit_multipole)) / abs(
914+
Tfint - self._Tg())
912915
# updating the borehole length values
913916
H_prev = self.H
914917
self.H = L / self.number_of_boreholes
@@ -980,7 +983,8 @@ def _Carcel(self, th: float, tcm: float, qh: float, qpm: float, qm: float, Tf: f
980983
# calculate the total length
981984
L = (qh * self.borehole.get_Rb(self.H, self.D, self.r_b, self.ground_data.k_s, self.depth,
982985
temperature=Tfint,
983-
nb_of_boreholes=self.number_of_boreholes) + qh * Rh + qm * Rcm + qpm * Rpm) / abs(
986+
nb_of_boreholes=self.number_of_boreholes,
987+
use_explicit_models=self._calculation_setup.use_explicit_multipole) + qh * Rh + qm * Rcm + qpm * Rpm) / abs(
984988
Tfint - self._Tg())
985989

986990
# updating the borehole lengths
@@ -1835,27 +1839,31 @@ def calculate_temperatures(H, hourly=hourly, results_temperature=ResultsMonthly(
18351839
results = None
18361840

18371841
def get_rb(temperature, limit=None):
1838-
18391842
if self.USE_SPEED_UP_IN_SIZING and sizing and not variable_efficiency:
18401843
# use only extreme temperatures when sizing
18411844
if limit is not None:
18421845
if len(temperature) == 0:
18431846
return self.borehole.get_Rb(H, self.D, self.r_b, self.ground_data.k_s(depth, self.D), depth,
1844-
temperature=Tmin, nb_of_boreholes=self.number_of_boreholes)
1847+
temperature=Tmin, nb_of_boreholes=self.number_of_boreholes,
1848+
use_explicit_models=self._calculation_setup.use_explicit_multipole)
18451849
elif limit == (Tmax if Tmax is not None else self.Tf_max):
18461850
return self.borehole.get_Rb(H, self.D, self.r_b, self.ground_data.k_s(depth, self.D), depth,
18471851
temperature=max(temperature),
1848-
nb_of_boreholes=self.number_of_boreholes)
1852+
nb_of_boreholes=self.number_of_boreholes,
1853+
use_explicit_models=self._calculation_setup.use_explicit_multipole)
18491854
else:
18501855
return self.borehole.get_Rb(H, self.D, self.r_b, self.ground_data.k_s(depth, self.D), depth,
18511856
temperature=min(temperature),
1852-
nb_of_boreholes=self.number_of_boreholes)
1857+
nb_of_boreholes=self.number_of_boreholes,
1858+
use_explicit_models=self._calculation_setup.use_explicit_multipole)
18531859
if len(temperature) == 0:
18541860
return self.borehole.get_Rb(H, self.D, self.r_b, self.ground_data.k_s(depth, self.D), depth,
1855-
temperature=Tmin, nb_of_boreholes=self.number_of_boreholes)
1861+
temperature=Tmin, nb_of_boreholes=self.number_of_boreholes,
1862+
use_explicit_models=self._calculation_setup.use_explicit_multipole)
18561863

18571864
return self.borehole.get_Rb(H, self.D, self.r_b, self.ground_data.k_s(depth, self.D), depth,
1858-
temperature=temperature, nb_of_boreholes=self.number_of_boreholes)
1865+
temperature=temperature, nb_of_boreholes=self.number_of_boreholes,
1866+
use_explicit_models=self._calculation_setup.use_explicit_multipole)
18591867

18601868
if not hourly:
18611869
# self.g-function is a function that uses the precalculated data to interpolate the correct values of the

GHEtool/Examples/HF_14obs.kmz

-190 KB
Binary file not shown.

GHEtool/Examples/pipe.py

Lines changed: 0 additions & 26 deletions
This file was deleted.

GHEtool/Examples/readkml.py

Lines changed: 0 additions & 4 deletions
This file was deleted.

GHEtool/Examples/regex.py

Lines changed: 0 additions & 22 deletions
This file was deleted.

GHEtool/Examples/turbocollector.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
The correlations for both the convective heat transfer coefficient and the friction factor, which are used internally
77
to calculate respectively the effective borehole thermal resistance and the pressure drop, were created by Niklas Hidman,
88
Division of Fluid Dynamics, Department of Mechanical and Maritime Sciences, Chalmers University of Technology, Gothenburg, Sweden.
9-
The study can be found here: https://www.muovitech.com/studies/Thermohydraulic_performance_evaluation_250519.pdf
9+
The study can be found here: https://www.sciencedirect.com/science/article/pii/S0017931025014498?via%3Dihub
1010
"""
1111
import matplotlib.pyplot as plt
1212
import numpy as np

GHEtool/Validation/comparison_with_other_sizing_tools/test1a/test1a.py

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -107,16 +107,15 @@ def test_1a_6h():
107107
f"The sizing according to L3 has a depth of {depth_L3:.2f}m (using dynamic Rb* of {Rb_L3:.3f}) and {depth_L3s:.2f}m (using constant Rb*)")
108108
print(
109109
f"The sizing according to L4 has a depth of {depth_L4:.2f}m (using dynamic Rb* of {Rb_L4:.3f}) and {depth_L4s:.2f}m (using constant Rb*)")
110-
111-
assert np.isclose(depth_L2, 59.366333293365)
112-
assert np.isclose(depth_L3, 59.542511807290666)
113-
assert np.isclose(depth_L4, 56.2659729399716)
114-
assert np.isclose(depth_L2s, 59.83238790604271)
115-
assert np.isclose(depth_L3s, 60.00736579796592)
110+
assert np.isclose(depth_L2, 59.3636198458606)
111+
assert np.isclose(depth_L3, 59.539512919146844)
112+
assert np.isclose(depth_L4, 56.263487685923195)
113+
assert np.isclose(depth_L2s, 59.8323879060427)
114+
assert np.isclose(depth_L3s, 60.00760582636102)
116115
assert np.isclose(depth_L4s, 56.732044011668464)
117-
assert np.isclose(Rb_L2, 0.12801945735995454)
118-
assert np.isclose(Rb_L3, 0.1280244880933401)
119-
assert np.isclose(Rb_L4, 0.12793335445966403)
116+
assert np.isclose(Rb_L2, 0.12800794794314643)
117+
assert np.isclose(Rb_L3, 0.12801297090220962)
118+
assert np.isclose(Rb_L4, 0.1279218446632468)
120119

121120

122121
def test_1a_1h():
@@ -209,16 +208,15 @@ def test_1a_1h():
209208
f"The sizing according to L3 has a depth of {depth_L3:.2f}m (using dynamic Rb* of {Rb_L3:.3f}) and {depth_L3s:.2f}m (using constant Rb*)")
210209
print(
211210
f"The sizing according to L4 has a depth of {depth_L4:.2f}m (using dynamic Rb* of {Rb_L4:.3f}) and {depth_L4s:.2f}m (using constant Rb*)")
212-
213-
assert np.isclose(depth_L2, 46.44356767605206)
214-
assert np.isclose(depth_L3, 46.73933500137179)
215-
assert np.isclose(depth_L4, 56.2659729399716)
211+
assert np.isclose(depth_L2, 46.4408463170366)
212+
assert np.isclose(depth_L3, 46.73652745970898)
213+
assert np.isclose(depth_L4, 56.26298710970397)
216214
assert np.isclose(depth_L2s, 46.986986159967906)
217-
assert np.isclose(depth_L3s, 47.28220733547535)
218-
assert np.isclose(depth_L4s, 56.73136082379056)
219-
assert np.isclose(Rb_L2, 0.12769092836836982)
220-
assert np.isclose(Rb_L3, 0.12769755355584275)
221-
assert np.isclose(Rb_L4, 0.12793335445966403)
215+
assert np.isclose(depth_L3s, 47.282207335475356)
216+
assert np.isclose(depth_L4s, 56.73157055683088)
217+
assert np.isclose(Rb_L2, 0.12767939520070198)
218+
assert np.isclose(Rb_L3, 0.1276860188802275)
219+
assert np.isclose(Rb_L4, 0.12792183113119798)
222220

223221

224222
if __name__ == "__main__": # pragma: no cover

GHEtool/Validation/comparison_with_other_sizing_tools/test1b/test1b.py

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -109,16 +109,15 @@ def test_1b():
109109
f"The sizing according to L3 has a depth of {depth_L3:.2f}m (using dynamic Rb* of {Rb_L3:.3f}) and {depth_L3s:.2f}m (using constant Rb*)")
110110
print(
111111
f"The sizing according to L4 has a depth of {depth_L4:.2f}m (using dynamic Rb* of {Rb_L4:.3f}) and {depth_L4s:.2f}m (using constant Rb*)")
112-
113-
assert np.isclose(depth_L2, 75.67161488446233)
114-
assert np.isclose(depth_L3, 75.62427445122744)
115-
assert np.isclose(depth_L4, 71.49641008062054)
112+
assert np.isclose(depth_L2, 75.66849470883834)
113+
assert np.isclose(depth_L3, 75.62186680865247)
114+
assert np.isclose(depth_L4, 71.49342289581354)
116115
assert np.isclose(depth_L2s, 76.71715998100636)
117116
assert np.isclose(depth_L3s, 76.67104470064083)
118-
assert np.isclose(depth_L4s, 72.52389782010322)
119-
assert np.isclose(Rb_L2, 0.12648875915036317)
120-
assert np.isclose(Rb_L3, 0.12648767833749805)
121-
assert np.isclose(Rb_L4, 0.12639600391560102)
117+
assert np.isclose(depth_L4s, 72.52389782010319)
118+
assert np.isclose(Rb_L2, 0.12647828821436058)
119+
assert np.isclose(Rb_L3, 0.12647722358651553)
120+
assert np.isclose(Rb_L4, 0.1263855489907598)
122121

123122

124123
if __name__ == "__main__": # pragma: no cover

GHEtool/Validation/comparison_with_other_sizing_tools/test2/test2.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -109,15 +109,15 @@ def test_2_6h():
109109
print(
110110
f"The sizing according to L4 has a depth of {depth_L4:.2f}m (using dynamic Rb* of {Rb_L4:.3f}) and {depth_L4s:.2f}m (using constant Rb*)")
111111

112-
assert np.isclose(depth_L2, 76.84063723898525)
113-
assert np.isclose(depth_L3, 79.10831161518712)
114-
assert np.isclose(depth_L4, 84.77053904958063)
112+
assert np.isclose(depth_L2, 76.80635452477883)
113+
assert np.isclose(depth_L3, 79.07410794395845)
114+
assert np.isclose(depth_L4, 84.73663201563583)
115115
assert np.isclose(depth_L2s, 77.43318625702659)
116116
assert np.isclose(depth_L3s, 79.6008906105556)
117117
assert np.isclose(depth_L4s, 84.97960330484824)
118-
assert np.isclose(Rb_L2, 0.11113022659380956)
119-
assert np.isclose(Rb_L3, 0.11146734480480838)
120-
assert np.isclose(Rb_L4, 0.11234852494964061)
118+
assert np.isclose(Rb_L2, 0.11102256296596089)
119+
assert np.isclose(Rb_L3, 0.11135938474158981)
120+
assert np.isclose(Rb_L4, 0.11224117157204798)
121121

122122

123123
if __name__ == "__main__": # pragma: no cover

0 commit comments

Comments
 (0)