1"""
2This document compares the sizing with a constant Rb*-value with sizing where the Rb*-value is being recalculated.
3For the test, the L2 sizing method is used.
4The comparison is based on speed and relative accuracy in the result.
5It is shown that the speed difference is significant, but so is the difference in the result. With a constant Rb* value, it is important that the initial depth is rather accurate.
6"""
7
8import time
9
10import numpy as np
11import pygfunction as gt
12
13from GHEtool import Borefield, FluidData, GroundConstantTemperature, DoubleUTube, MonthlyGeothermalLoadAbsolute
14
15
16def sizing_with_Rb():
17 number_of_iterations = 50
18 max_value_cooling = 700
19 max_value_heating = 800
20
21 # initiate the arrays
22 results_Rb_static = np.empty(number_of_iterations)
23 results_Rb_dynamic = np.empty(number_of_iterations)
24 difference_results = np.empty(number_of_iterations)
25
26 monthly_load_cooling_array = np.empty((number_of_iterations, 12))
27 monthly_load_heating_array = np.empty((number_of_iterations, 12))
28 peak_load_cooling_array = np.empty((number_of_iterations, 12))
29 peak_load_heating_array = np.empty((number_of_iterations, 12))
30
31 # populate arrays with random values
32 for i in range(number_of_iterations):
33 for j in range(12):
34 monthly_load_cooling_array[i, j] = np.random.randint(0, max_value_cooling)
35 monthly_load_heating_array[i, j] = np.random.randint(0, max_value_heating)
36 peak_load_cooling_array[i, j] = np.random.randint(monthly_load_cooling_array[i, j], max_value_cooling)
37 peak_load_heating_array[i, j] = np.random.randint(monthly_load_heating_array[i, j], max_value_heating)
38
39 # initiate borefield model
40 data = GroundConstantTemperature(3, 10) # ground data with an inaccurate guess of 100m for the depth of the borefield
41 fluid_data = FluidData(0.2, 0.568, 998, 4180, 1e-3)
42 pipe_data = DoubleUTube(1, 0.015, 0.02, 0.4, 0.05)
43
44 borefield_gt = gt.boreholes.rectangle_field(10, 12, 6, 6, 100, 1, 0.075)
45
46 # Monthly loading values
47 peak_cooling = np.array([0., 0, 34., 69., 133., 187., 213., 240., 160., 37., 0., 0.]) # Peak cooling in kW
48 peak_heating = np.array([160., 142, 102., 55., 0., 0., 0., 0., 40.4, 85., 119., 136.]) # Peak heating in kW
49
50 # annual heating and cooling load
51 annual_heating_load = 300 * 10 ** 3 # kWh
52 annual_cooling_load = 160 * 10 ** 3 # kWh
53
54 # percentage of annual load per month (15.5% for January ...)
55 monthly_load_heating_percentage = np.array([0.155, 0.148, 0.125, .099, .064, 0., 0., 0., 0.061, 0.087, 0.117, 0.144])
56 monthly_load_cooling_percentage = np.array([0.025, 0.05, 0.05, .05, .075, .1, .2, .2, .1, .075, .05, .025])
57
58 # resulting load per month
59 monthly_load_heating = annual_heating_load * monthly_load_heating_percentage # kWh
60 monthly_load_cooling = annual_cooling_load * monthly_load_cooling_percentage # kWh
61
62 # set the load
63 load = MonthlyGeothermalLoadAbsolute(monthly_load_heating, monthly_load_cooling, peak_heating, peak_cooling)
64
65 # create the borefield object
66 borefield = Borefield(load=load)
67
68 borefield.set_ground_parameters(data)
69 borefield.set_fluid_parameters(fluid_data)
70 borefield.set_pipe_parameters(pipe_data)
71 borefield.Rb = 0.2
72 borefield.set_borefield(borefield_gt)
73
74 # create custom gfunction to speed up the calculation
75 borefield.create_custom_dataset()
76
77 # set temperature boundaries
78 borefield.set_max_avg_fluid_temperature(16) # maximum temperature
79 borefield.set_min_avg_fluid_temperature(0) # minimum temperature
80
81 # size with constant Rb* value
82 borefield.calculation_setup(use_constant_Rb=True)
83
84 # calculate the Rb* value
85 borefield.Rb = borefield.borehole.calculate_Rb(100, 1, 0.075, data.k_s)
86
87 start_Rb_constant = time.time()
88 for i in range(number_of_iterations):
89 # set the load
90 load = MonthlyGeothermalLoadAbsolute(monthly_load_heating_array[i], monthly_load_cooling_array[i],
91 peak_load_heating_array[i], peak_load_cooling_array[i])
92 borefield.load = load
93 results_Rb_static[i] = borefield.size()
94 end_Rb_constant = time.time()
95
96 # size with a dynamic Rb* value
97 borefield.calculation_setup(use_constant_Rb=False)
98
99 start_Rb_dynamic = time.time()
100 for i in range(number_of_iterations):
101 # set the load
102 load = MonthlyGeothermalLoadAbsolute(monthly_load_heating_array[i], monthly_load_cooling_array[i],
103 peak_load_heating_array[i], peak_load_cooling_array[i])
104 borefield.load = load
105 results_Rb_dynamic[i] = borefield.size()
106 end_Rb_dynamic = time.time()
107 print(results_Rb_dynamic[1])
108
109 print("These are the results when an inaccurate constant Rb* value is used.")
110 print("Time for sizing with a constant Rb* value:", end_Rb_constant - start_Rb_constant, "s")
111 print("Time for sizing with a dynamic Rb* value:", end_Rb_dynamic - start_Rb_dynamic, "s")
112
113 # calculate differences
114 for i in range(number_of_iterations):
115 difference_results[i] = results_Rb_dynamic[i] - results_Rb_static[i]
116
117 print("The maximal difference between the sizing with a constant and a dynamic Rb* value:", np.round(np.max(difference_results), 3), "m or", np.round(np.max(difference_results) / results_Rb_static[np.argmax(difference_results)] * 100, 3), "% w.r.t. the constant Rb* approach.")
118 print("The mean difference between the sizing with a constant and a dynamic Rb* value:", np.round(np.mean(difference_results), 3), "m or", np.round(np.mean(difference_results) / np.mean(results_Rb_static) * 100, 3), "% w.r.t. the constant Rb* approach.")
119 print("------------------------------------------------------------------------------")
120
121 # Do the same thing but with another constant Rb* value based on a borehole depth of 185m.
122
123 borefield_gt = gt.boreholes.rectangle_field(10, 12, 6, 6, 185, 1, 0.075) # borefield with an accurate guess of 185m for the depth of the borefield
124 borefield.set_borefield(borefield_gt)
125
126 # size with a constant Rb* value
127 borefield.calculation_setup(use_constant_Rb=True)
128
129 # calculate the Rb* value
130 borefield.Rb = borefield.borehole.calculate_Rb(100, 1, 0.075, data.k_s)
131
132 start_Rb_constant = time.time()
133 for i in range(number_of_iterations):
134 # set the load
135 load = MonthlyGeothermalLoadAbsolute(monthly_load_heating_array[i], monthly_load_cooling_array[i],
136 peak_load_heating_array[i], peak_load_cooling_array[i])
137 borefield.load = load
138 results_Rb_static[i] = borefield.size()
139 end_Rb_constant = time.time()
140
141 # size with a dynamic Rb* value
142 borefield.calculation_setup(use_constant_Rb=False)
143
144 start_Rb_dynamic = time.time()
145 for i in range(number_of_iterations):
146 # set the load
147 load = MonthlyGeothermalLoadAbsolute(monthly_load_heating_array[i], monthly_load_cooling_array[i],
148 peak_load_heating_array[i], peak_load_cooling_array[i])
149 borefield.load = load
150 results_Rb_dynamic[i] = borefield.size()
151 end_Rb_dynamic = time.time()
152
153 print("These are the results when an accurate constant Rb* value is used.")
154 print("Time for sizing with a constant Rb* value:", end_Rb_constant - start_Rb_constant, "s")
155 print("Time for sizing with a dynamic Rb* value:", end_Rb_dynamic - start_Rb_dynamic, "s")
156
157 # calculate differences
158 for i in range(number_of_iterations):
159 difference_results[i] = results_Rb_dynamic[i] - results_Rb_static[i]
160
161 print("The maximal difference between the sizing with a constant and a dynamic Rb* value:",
162 np.round(np.max(difference_results), 3), "m or",
163 np.round(np.max(difference_results) / results_Rb_static[np.argmax(difference_results)] * 100, 3),
164 "% w.r.t. the constant Rb* approach.")
165 print("The mean difference between the sizing with a constant and a dynamic Rb* value:",
166 np.round(np.mean(difference_results), 3), "m or",
167 np.round(np.mean(difference_results) / np.mean(results_Rb_static) * 100, 3),
168 "% w.r.t. the constant Rb* approach.")
169
170
171if __name__ == "__main__": # pragma: no cover
172 sizing_with_Rb()