Calculation of g-Functions computed with non-uniform segment lengthsΒΆ
This example demonstrates the use of the utilities
module to determine discretized segment ratios along a borehole.
The following script computes g-Functions for a field of 6x4 boreholes utilizing the MIFT and UBWT boundary conditions with a 48 segments per borehole and equal segment lengths. The MIFT and UBWT g-functions are computed with only 8 segments per borehole and non-uniform segment lengths. RMSE values are compared. It is shown that g-functions can be calculated accurately using a small number of segments.
The script is located in: pygfunction/examples/discretize_boreholes.py
1# -*- coding: utf-8 -*-
2""" Example of g-function calculation using non-uniform segment lengths along
3 the boreholes.
4
5 The g-functions of a field of 6x4 boreholes are calculated for two
6 boundary conditions : (1) a uniform borehole wall temperature along the
7 boreholes equal for all boreholes, and (2) an equal inlet fluid
8 temperature into the boreholes. g-Functions using 8 segments in a
9 non-uniform discretization are compared to reference g-functions
10 calculated using 48 segments of equal lengths. It is shown that g-functions
11 can be calculated accurately using a small number of segments.
12"""
13
14import pygfunction as gt
15from numpy import pi
16import matplotlib.pyplot as plt
17import numpy as np
18
19
20def main():
21 # -------------------------------------------------------------------------
22 # Simulation parameters
23 # -------------------------------------------------------------------------
24
25 # Borehole dimensions
26 D = 4.0 # Borehole buried depth (m)
27 H = 150.0 # Borehole length (m)
28 r_b = 0.075 # Borehole radius (m)
29 B = 7.5 # Borehole spacing (m)
30
31 # Pipe dimensions
32 r_out = 0.0211 # Pipe outer radius (m)
33 r_in = 0.0147 # Pipe inner radius (m)
34 D_s = 0.052 # Shank spacing (m)
35 epsilon = 1.0e-6 # Pipe roughness (m)
36
37 # Pipe positions
38 # Single U-tube [(x_in, y_in), (x_out, y_out)]
39 pos_pipes = [(-D_s, 0.), (D_s, 0.)]
40
41 # Ground properties
42 alpha = 1.0e-6 # Ground thermal diffusivity (m2/s)
43 k_s = 2.0 # Ground thermal conductivity (W/m.K)
44
45 # Grout properties
46 k_g = 1.0 # Grout thermal conductivity (W/m.K)
47
48 # Pipe properties
49 k_p = 0.4 # Pipe thermal conductivity (W/m.K)
50
51 # Fluid properties
52 m_flow_borehole = 0.25 # Total fluid mass flow rate per borehole (kg/s)
53 # The fluid is propylene-glycol (20 %) at 20 degC
54 fluid = gt.media.Fluid('MPG', 20.)
55 cp_f = fluid.cp # Fluid specific isobaric heat capacity (J/kg.K)
56 rho_f = fluid.rho # Fluid density (kg/m3)
57 mu_f = fluid.mu # Fluid dynamic viscosity (kg/m.s)
58 k_f = fluid.k # Fluid thermal conductivity (W/m.K)
59
60 # g-Function calculation options
61
62 # Number of segments used in the reference calculation with uniform
63 # discretization
64 nSegments_uniform = 48
65 options_uniform = {'nSegments': nSegments_uniform,
66 'segment_ratios': None,
67 'disp': True}
68 # Number of segments used in the calculation with non-uniform
69 # discretization
70 nSegments_unequal = 8
71 segment_ratios = gt.utilities.segment_ratios(
72 nSegments_unequal, end_length_ratio=0.02)
73 options_unequal = {'nSegments': nSegments_unequal,
74 'segment_ratios': segment_ratios,
75 'disp':True}
76
77 # Geometrically expanding time vector.
78 dt = 100*3600. # Time step
79 tmax = 3000. * 8760. * 3600. # Maximum time
80 Nt = 25 # Number of time steps
81 ts = H**2/(9.*alpha) # Bore field characteristic time
82 time = gt.utilities.time_geometric(dt, tmax, Nt)
83
84 # -------------------------------------------------------------------------
85 # Borehole field
86 # -------------------------------------------------------------------------
87
88 # Field of 6x4 (n=24) boreholes
89 N_1 = 6
90 N_2 = 4
91 boreField = gt.boreholes.rectangle_field(N_1, N_2, B, B, H, D, r_b)
92 gt.boreholes.visualize_field(boreField)
93 nBoreholes = len(boreField)
94
95 # -------------------------------------------------------------------------
96 # Initialize pipe model
97 # -------------------------------------------------------------------------
98
99 # Pipe thermal resistance
100 R_p = gt.pipes.conduction_thermal_resistance_circular_pipe(
101 r_in, r_out, k_p)
102 # Fluid to inner pipe wall thermal resistance (Single U-tube)
103 m_flow_pipe = m_flow_borehole
104 h_f = gt.pipes.convective_heat_transfer_coefficient_circular_pipe(
105 m_flow_pipe, r_in, mu_f, rho_f, k_f, cp_f, epsilon)
106 R_f = 1.0/(h_f*2*pi*r_in)
107
108 # Single U-tube, same for all boreholes in the bore field
109 UTubes = []
110 for borehole in boreField:
111 SingleUTube = gt.pipes.SingleUTube(
112 pos_pipes, r_in, r_out, borehole, k_s, k_g, R_f + R_p)
113 UTubes.append(SingleUTube)
114 m_flow_network = m_flow_borehole*nBoreholes
115
116 # Network of boreholes connected in parallel
117 network = gt.networks.Network(
118 boreField, UTubes, m_flow_network=m_flow_network, cp_f=cp_f)
119
120 # -------------------------------------------------------------------------
121 # Evaluate the g-functions for the borefield
122 # -------------------------------------------------------------------------
123
124 # Compute g-function for the converged MIFT case with equal number of
125 # segments per borehole, and equal segment lengths along the boreholes
126 gfunc_MIFT_uniform = gt.gfunction.gFunction(
127 network, alpha, time=time, boundary_condition='MIFT',
128 options=options_uniform)
129
130 # Calculate the g-function for uniform borehole wall temperature
131 gfunc_UBWT_uniform = gt.gfunction.gFunction(
132 boreField, alpha, time=time, boundary_condition='UBWT',
133 options=options_uniform)
134
135 # Compute g-function for the MIFT case with equal number of segments per
136 # borehole, and non-uniform segment lengths along the boreholes
137 gfunc_MIFT_unequal = gt.gfunction.gFunction(
138 network, alpha, time=time, boundary_condition='MIFT',
139 options=options_unequal)
140
141 # Calculate the g-function for uniform borehole wall temperature
142 gfunc_UBWT_unequal = gt.gfunction.gFunction(
143 boreField, alpha, time=time, boundary_condition='UBWT',
144 options=options_unequal)
145
146 # Compute the rmse between the reference cases and the discretized
147 # (predicted) cases
148 RMSE_MIFT = RMSE(gfunc_MIFT_uniform.gFunc, gfunc_MIFT_unequal.gFunc)
149 print(f'RMSE (MIFT) = {RMSE_MIFT:.5f}')
150 RMSE_UBWT = RMSE(gfunc_UBWT_uniform.gFunc, gfunc_UBWT_unequal.gFunc)
151 print(f'RMSE (UBWT) = {RMSE_UBWT:.5f}')
152
153 # -------------------------------------------------------------------------
154 # Plot g-functions
155 # -------------------------------------------------------------------------
156
157 ax = gfunc_MIFT_uniform.visualize_g_function().axes[0]
158 ax.plot(np.log(time / ts), gfunc_UBWT_uniform.gFunc)
159 ax.plot(np.log(time / ts), gfunc_MIFT_unequal.gFunc, 'o')
160 ax.plot(np.log(time / ts), gfunc_UBWT_unequal.gFunc, 'o')
161 ax.legend(
162 ['Equal inlet temperature (uniform segments)',
163 'Uniform borehole wall temperature (uniform segments)',
164 'Equal inlet temperature (non-uniform segments)',
165 'Uniform borehole wall temperature (non-uniform segments)'])
166 plt.tight_layout()
167
168 return
169
170
171def RMSE(reference, predicted):
172 rmse = np.linalg.norm(predicted - reference) / len(reference)
173 return rmse
174
175
176# Main function
177if __name__ == '__main__':
178 main()