Compare the accuracy and speed of different g-function solvers¶
This example compares the simulation times and the accuracy of different solvers for the evaluation of g-functions.
The g-function of a field of 6 by4 boreholes is first calculated for a boundary condition of uniform borehole wall temperature along the boreholes, equal for all boreholes. Three different solvers are compared : ‘detailed’, ‘similarities’ 1 and ‘equivalent’ 2. Their accuracy and calculation time are compared using the ‘detailed’ solver as a reference. This shows that the ‘similarities’ solver can evaluate g-functions with high accuracy.
The g-function of a field of 12 by 10 boreholes is then calculated for a boundary condition of uniform borehole wall temperature along the boreholes, equal for all boreholes. Two different solvers are compared : ‘similarities’ and ‘equivalent’. The accuracy and calculation time of the ‘equivalent’ is compared using the ‘similarities’ solver as a reference. This shows that the ‘equivalent’ solver evaluates g-functions at a very high calculation speed while maintaining reasonable accuracy.
The script is located in: pygfunction/examples/comparison_gfunction_solvers.py
1# -*- coding: utf-8 -*-
2""" Comparison of solvers for the evaluation of g-functions using uniform and
3 equal borehole wall temperatures.
4
5 The g-function of a field of 6x4 boreholes is calculated for a boundary
6 condition of uniform borehole wall temperature along the boreholes, equal
7 for all boreholes. Three different solvers are compared : 'detailed',
8 'similarities' and 'equivalent'. Their accuracy and calculation time are
9 compared using the 'detailed' solver as a reference. This shows that the
10 'similarities' solver can evaluate g-functions with high accuracy.
11
12 The g-function of a field of 12x10 boreholes is calculated for a boundary
13 condition of uniform borehole wall temperature along the boreholes, equal
14 for all boreholes. Two different solvers are compared : 'similarities' and
15 'equivalent'. The accuracy and calculation time of the 'equivalent' is
16 compared using the 'similarities' solver as a reference. This shows that
17 the 'equivalent' solver evaluates g-functions at a very high calculation
18 speed while maintaining reasonable accuracy.
19
20"""
21import matplotlib.pyplot as plt
22import numpy as np
23from time import perf_counter
24
25import pygfunction as gt
26
27
28def main():
29 # -------------------------------------------------------------------------
30 # Simulation parameters
31 # -------------------------------------------------------------------------
32
33 # Borehole dimensions
34 D = 4.0 # Borehole buried depth (m)
35 H = 150.0 # Borehole length (m)
36 r_b = 0.075 # Borehole radius (m)
37 B = 7.5 # Borehole spacing (m)
38
39 # Thermal properties
40 alpha = 1.0e-6 # Ground thermal diffusivity (m2/s)
41
42 # g-Function calculation options
43 options = {'nSegments': 8,
44 'disp': True}
45
46 # Geometrically expanding time vector.
47 dt = 100*3600. # Time step
48 tmax = 3000. * 8760. * 3600. # Maximum time
49 Nt = 15 # Number of time steps
50 ts = H**2/(9.*alpha) # Bore field characteristic time
51 time = gt.utilities.time_geometric(dt, tmax, Nt)
52 lntts = np.log(time/ts)
53
54 # -------------------------------------------------------------------------
55 # Borehole field (First bore field)
56 # -------------------------------------------------------------------------
57
58 # Field of 6x4 (n=24) boreholes
59 N_1 = 6
60 N_2 = 4
61 field = gt.boreholes.rectangle_field(N_1, N_2, B, B, H, D, r_b)
62
63 # -------------------------------------------------------------------------
64 # Evaluate g-functions
65 # -------------------------------------------------------------------------
66 t0 = perf_counter()
67 gfunc_detailed = gt.gfunction.gFunction(
68 field, alpha, time=time, options=options, method='detailed')
69 t1 = perf_counter()
70 t_detailed = t1 - t0
71 gfunc_similarities = gt.gfunction.gFunction(
72 field, alpha, time=time, options=options, method='similarities')
73 t2 = perf_counter()
74 t_similarities = t2 - t1
75 gfunc_equivalent = gt.gfunction.gFunction(
76 field, alpha, time=time, options=options, method='equivalent')
77 t3 = perf_counter()
78 t_equivalent = t3 - t2
79
80 # -------------------------------------------------------------------------
81 # Plot results
82 # -------------------------------------------------------------------------
83 # Draw g-functions
84 ax = gfunc_detailed.visualize_g_function().axes[0]
85 ax.plot(lntts, gfunc_similarities.gFunc, 'bx')
86 ax.plot(lntts, gfunc_equivalent.gFunc, 'ro')
87 ax.legend([f'detailed (t = {t_detailed:.3f} sec)',
88 f'similarities (t = {t_similarities:.3f} sec)',
89 f'equivalent (t = {t_equivalent:.3f} sec)'])
90 ax.set_title(f'Field of {N_1} by {N_2} boreholes')
91 plt.tight_layout()
92
93 # Draw absolute error
94 # Configure figure and axes
95 fig = gt.utilities._initialize_figure()
96 ax = fig.add_subplot(111)
97 # Axis labels
98 ax.set_xlabel(r'ln$(t/t_s)$')
99 ax.set_ylabel(r'Absolute error')
100 gt.utilities._format_axes(ax)
101 # Absolute error
102 ax.plot(lntts, np.abs(gfunc_similarities.gFunc - gfunc_detailed.gFunc),
103 '-', label='similarities')
104 ax.plot(lntts, np.abs(gfunc_equivalent.gFunc - gfunc_detailed.gFunc),
105 '--', label='equivalent')
106 ax.legend()
107 ax.set_title(f"Absolute error relative to the 'detailed' solver "
108 f"(Field of {N_1} by {N_2} boreholes)")
109 # Adjust to plot window
110 fig.tight_layout()
111
112 # Draw relative error
113 # Configure figure and axes
114 fig = gt.utilities._initialize_figure()
115 ax = fig.add_subplot(111)
116 # Axis labels
117 ax.set_xlabel(r'ln$(t/t_s)$')
118 ax.set_ylabel(r'Relative error')
119 gt.utilities._format_axes(ax)
120 # Relative error
121 gFunc_ref = gfunc_detailed.gFunc # reference g-function
122 ax.plot(lntts, (gfunc_similarities.gFunc - gFunc_ref) / gFunc_ref,
123 '-', label='similarities')
124 ax.plot(lntts, (gfunc_equivalent.gFunc - gFunc_ref) / gFunc_ref,
125 '--', label='equivalent')
126 ax.legend()
127 ax.set_title(f"Relative error relative to the 'detailed' solver "
128 f"(Field of {N_1} by {N_2} boreholes)")
129 # Adjust to plot window
130 fig.tight_layout()
131
132 # -------------------------------------------------------------------------
133 # Borehole field (Second bore field)
134 # -------------------------------------------------------------------------
135
136 # Field of 6x4 (n=24) boreholes
137 N_1 = 12
138 N_2 = 10
139 field = gt.boreholes.rectangle_field(N_1, N_2, B, B, H, D, r_b)
140
141 # -------------------------------------------------------------------------
142 # Evaluate g-functions
143 # -------------------------------------------------------------------------
144 gfunc_similarities = gt.gfunction.gFunction(
145 field, alpha, time=time, options=options, method='similarities')
146 t2 = perf_counter()
147 t_similarities = t2 - t1
148 gfunc_equivalent = gt.gfunction.gFunction(
149 field, alpha, time=time, options=options, method='equivalent')
150 t3 = perf_counter()
151 t_equivalent = t3 - t2
152
153 # -------------------------------------------------------------------------
154 # Plot results
155 # -------------------------------------------------------------------------
156 # Draw g-functions
157 ax = gfunc_similarities.visualize_g_function().axes[0]
158 ax.plot(lntts, gfunc_equivalent.gFunc, 'ro')
159 ax.legend([f'similarities (t = {t_similarities:.3f} sec)',
160 f'equivalent (t = {t_equivalent:.3f} sec)'])
161 ax.set_title(f'Field of {N_1} by {N_2} boreholes')
162 plt.tight_layout()
163
164 # Draw absolute error
165 # Configure figure and axes
166 fig = gt.utilities._initialize_figure()
167 ax = fig.add_subplot(111)
168 # Axis labels
169 ax.set_xlabel(r'ln$(t/t_s)$')
170 ax.set_ylabel(r'Absolute error')
171 gt.utilities._format_axes(ax)
172 # Absolute error
173 ax.plot(lntts, np.abs(gfunc_equivalent.gFunc - gfunc_similarities.gFunc),
174 label='equivalent')
175 ax.legend()
176 ax.set_title(f"Absolute error relative to the 'similarities' solver "
177 f"(Field of {N_1} by {N_2} boreholes)")
178 # Adjust to plot window
179 fig.tight_layout()
180
181 # Draw relative error
182 # Configure figure and axes
183 fig = gt.utilities._initialize_figure()
184 ax = fig.add_subplot(111)
185 # Axis labels
186 ax.set_xlabel(r'ln$(t/t_s)$')
187 ax.set_ylabel(r'Relative error')
188 gt.utilities._format_axes(ax)
189 # Relative error
190 ax.plot(lntts, (gfunc_equivalent.gFunc - gfunc_similarities.gFunc) / gfunc_similarities.gFunc,
191 label='equivalent')
192 ax.legend()
193 ax.set_title(f"Relative error relative to the 'similarities' solver "
194 f"(Field of {N_1} by {N_2} boreholes)")
195 # Adjust to plot window
196 fig.tight_layout()
197
198 return
199
200
201# Main function
202if __name__ == '__main__':
203 main()
References
- 1
Cimmino, M. (2018). Fast calculation of the g-functions of geothermal borehole fields using similarities in the evaluation of the finite line source solution. Journal of Building Performance Simulation, 11 (6), 655-668.
- 2
Prieto, C., & Cimmino, M. (2021). Thermal interactions in large irregular fields of geothermal boreholes: the method of equivalent borehole. Journal of Building Performance Simulation, 14 (4), 446-460.