diff --git a/examples/bore_field_thermal_resistance.py b/examples/bore_field_thermal_resistance.py index 36834cb..71c58fc 100644 --- a/examples/bore_field_thermal_resistance.py +++ b/examples/bore_field_thermal_resistance.py @@ -8,8 +8,9 @@ """ try: import matplotlib.pyplot as plt + enable_plotting = True except ModuleNotFoundError: - pass + enable_plotting = False import numpy as np from scipy.constants import pi @@ -117,7 +118,7 @@ def main(make_plots=True): # Plot bore field thermal resistances # ------------------------------------------------------------------------- - if make_plots: + if enable_plotting and make_plots: # Configure figure and axes fig = gt.utilities._initialize_figure() diff --git a/examples/comparison_gfunction_solvers.py b/examples/comparison_gfunction_solvers.py index 9d86e98..9e3c0aa 100644 --- a/examples/comparison_gfunction_solvers.py +++ b/examples/comparison_gfunction_solvers.py @@ -20,8 +20,9 @@ """ try: import matplotlib.pyplot as plt + enable_plotting = True except ModuleNotFoundError: - pass + enable_plotting = False import numpy as np from time import perf_counter @@ -81,7 +82,7 @@ def main(make_plots=True): t3 = perf_counter() t_equivalent = t3 - t2 - if make_plots: + if enable_plotting and make_plots: # ------------------------------------------------------------------------- # Plot results @@ -156,7 +157,7 @@ def main(make_plots=True): t3 = perf_counter() t_equivalent = t3 - t2 - if make_plots: + if enable_plotting and make_plots: # ------------------------------------------------------------------------- # Plot results diff --git a/examples/comparison_load_aggregation.py b/examples/comparison_load_aggregation.py index 22bff3f..63efe3b 100644 --- a/examples/comparison_load_aggregation.py +++ b/examples/comparison_load_aggregation.py @@ -16,8 +16,9 @@ try: import matplotlib.pyplot as plt + enable_plotting = True except ModuleNotFoundError: - pass + enable_plotting = False import numpy as np from scipy.constants import pi @@ -53,7 +54,7 @@ def main(make_plots=True): time = dt * np.arange(1, Nt+1) # Evaluate heat extraction rate - Q_b = synthetic_load(time/3600.) + Q_b = gt.utilities.synthetic_load(time/3600.) # Load aggregation schemes ClaessonJaved = gt.load_aggregation.ClaessonJaved(dt, tmax) @@ -122,7 +123,7 @@ def main(make_plots=True): # Convolution in Fourier domain T_b_exact = T_g - fftconvolve(dQ, g/(2.0*pi*k_s*H), mode='full')[0:Nt] - if make_plots: + if enable_plotting and make_plots: # ------------------------------------------------------------------------- # plot results @@ -173,35 +174,6 @@ def main(make_plots=True): print(f'Maximum absolute error : {maxError_n:.3f} degC') print(f'Calculation time : {t_calc_n:.3f} sec') - return - - -def synthetic_load(x): - """ - Synthetic load profile of Bernier et al. (2004). - - Returns load y (in watts) at time x (in hours). - """ - A = 2000.0 - B = 2190.0 - C = 80.0 - D = 2.0 - E = 0.01 - F = 0.0 - G = 0.95 - - func = (168.0-C)/168.0 - for i in [1, 2, 3]: - func += 1.0/(i*pi)*(np.cos(C*pi*i/84.0) - 1.0) \ - *(np.sin(pi*i/84.0*(x - B))) - func = func*A*np.sin(pi/12.0*(x - B)) \ - *np.sin(pi/4380.0*(x - B)) - - y = func + (-1.0)**np.floor(D/8760.0*(x - B))*abs(func) \ - + E*(-1.0)**np.floor(D/8760.0*(x - B)) \ - /np.sign(np.cos(D*pi/4380.0*(x - F)) + G) - return -y - # Main function if __name__ == '__main__': diff --git a/examples/custom_bore_field.py b/examples/custom_bore_field.py index 96108c8..531dd96 100644 --- a/examples/custom_bore_field.py +++ b/examples/custom_bore_field.py @@ -5,7 +5,7 @@ import pygfunction as gt -def main(): +def main(make_plots=True): # ------------------------------------------------------------------------- # Parameters # ------------------------------------------------------------------------- @@ -45,9 +45,8 @@ def main(): # Draw bore field # ------------------------------------------------------------------------- - gt.boreholes.visualize_field(field) - - return + if make_plots: + gt.boreholes.visualize_field(field) # Main function diff --git a/examples/custom_bore_field_from_file.py b/examples/custom_bore_field_from_file.py index 55448be..5331e9e 100644 --- a/examples/custom_bore_field_from_file.py +++ b/examples/custom_bore_field_from_file.py @@ -8,13 +8,13 @@ import pygfunction as gt -def main(): +def main(make_plots=True): # ------------------------------------------------------------------------- # Parameters # ------------------------------------------------------------------------- # Filepath to bore field text file - filename = Path(__file__).parent / "data", "custom_field_32_boreholes.txt" + filename = Path(__file__).parent / "data" / "custom_field_32_boreholes.txt" # ------------------------------------------------------------------------- # Borehole field @@ -23,13 +23,12 @@ def main(): # Build list of boreholes field = gt.boreholes.field_from_file(filename) - # ------------------------------------------------------------------------- - # Draw bore field - # ------------------------------------------------------------------------- - - gt.boreholes.visualize_field(field) + if make_plots: + # ------------------------------------------------------------------------- + # Draw bore field + # ------------------------------------------------------------------------- - return + gt.boreholes.visualize_field(field) # Main function diff --git a/examples/custom_borehole.py b/examples/custom_borehole.py index 0de0f97..2a057e3 100644 --- a/examples/custom_borehole.py +++ b/examples/custom_borehole.py @@ -9,7 +9,7 @@ import pygfunction as gt -def main(): +def main(make_plots=True): # ------------------------------------------------------------------------- # Simulation parameters # ------------------------------------------------------------------------- @@ -100,9 +100,10 @@ def main(): print(f'Single U-tube Borehole thermal resistance: ' f'{R_b:.4f} m.K/W') - # Visualize the borehole geometry and save the figure - fig_single = SingleUTube.visualize_pipes() - fig_single.savefig('single-u-tube-borehole.png') + if make_plots: + # Visualize the borehole geometry and save the figure + fig_single = SingleUTube.visualize_pipes() + fig_single.savefig('single-u-tube-borehole.png') # ------------------------------------------------------------------------- # Define a double U-tube borehole @@ -152,9 +153,10 @@ def main(): print(f'Double U-tube (parallel) Borehole thermal resistance: ' f'{R_b_parallel:.4f} m.K/W') - # Visualize the borehole geometry and save the figure - fig_double = DoubleUTube_series.visualize_pipes() - fig_double.savefig('double-u-tube-borehole.png') + if make_plots: + # Visualize the borehole geometry and save the figure + fig_double = DoubleUTube_series.visualize_pipes() + fig_double.savefig('double-u-tube-borehole.png') # ------------------------------------------------------------------------- # Define a coaxial borehole @@ -197,9 +199,10 @@ def main(): m_flow_borehole, fluid.cp) print(f'Coaxial tube Borehole thermal resistance: {R_b:.4f} m.K/W') - # Visualize the borehole geometry and save the figure - fig_coaxial = Coaxial.visualize_pipes() - fig_coaxial.savefig('coaxial-borehole.png') + if make_plots: + # Visualize the borehole geometry and save the figure + fig_coaxial = Coaxial.visualize_pipes() + fig_coaxial.savefig('coaxial-borehole.png') if __name__ == '__main__': diff --git a/examples/discretize_boreholes.py b/examples/discretize_boreholes.py index cd1768b..bb75bd6 100644 --- a/examples/discretize_boreholes.py +++ b/examples/discretize_boreholes.py @@ -11,13 +11,18 @@ can be calculated accurately using a small number of segments. """ +try: + import matplotlib.pyplot as plt + enable_plotting = True +except ModuleNotFoundError: + enable_plotting = False + import pygfunction as gt from numpy import pi -import matplotlib.pyplot as plt import numpy as np -def main(): +def main(make_plots=True): # ------------------------------------------------------------------------- # Simulation parameters # ------------------------------------------------------------------------- @@ -89,7 +94,10 @@ def main(): N_1 = 6 N_2 = 4 boreField = gt.boreholes.rectangle_field(N_1, N_2, B, B, H, D, r_b) - gt.boreholes.visualize_field(boreField) + + if make_plots: + gt.boreholes.visualize_field(boreField) + nBoreholes = len(boreField) # ------------------------------------------------------------------------- @@ -150,22 +158,23 @@ def main(): RMSE_UBWT = RMSE(gfunc_UBWT_uniform.gFunc, gfunc_UBWT_unequal.gFunc) print(f'RMSE (UBWT) = {RMSE_UBWT:.5f}') - # ------------------------------------------------------------------------- - # Plot g-functions - # ------------------------------------------------------------------------- + if enable_plotting and make_plots: + + # ------------------------------------------------------------------------- + # Plot g-functions + # ------------------------------------------------------------------------- + + ax = gfunc_MIFT_uniform.visualize_g_function().axes[0] + ax.plot(np.log(time / ts), gfunc_UBWT_uniform.gFunc) + ax.plot(np.log(time / ts), gfunc_MIFT_unequal.gFunc, 'o') + ax.plot(np.log(time / ts), gfunc_UBWT_unequal.gFunc, 'o') + ax.legend( + ['Equal inlet temperature (uniform segments)', + 'Uniform borehole wall temperature (uniform segments)', + 'Equal inlet temperature (non-uniform segments)', + 'Uniform borehole wall temperature (non-uniform segments)']) + plt.tight_layout() - ax = gfunc_MIFT_uniform.visualize_g_function().axes[0] - ax.plot(np.log(time / ts), gfunc_UBWT_uniform.gFunc) - ax.plot(np.log(time / ts), gfunc_MIFT_unequal.gFunc, 'o') - ax.plot(np.log(time / ts), gfunc_UBWT_unequal.gFunc, 'o') - ax.legend( - ['Equal inlet temperature (uniform segments)', - 'Uniform borehole wall temperature (uniform segments)', - 'Equal inlet temperature (non-uniform segments)', - 'Uniform borehole wall temperature (non-uniform segments)']) - plt.tight_layout() - - return def RMSE(reference, predicted): diff --git a/examples/equal_inlet_temperature.py b/examples/equal_inlet_temperature.py index ae8f377..1dbc3ca 100644 --- a/examples/equal_inlet_temperature.py +++ b/examples/equal_inlet_temperature.py @@ -7,14 +7,19 @@ boreholes, and (c) equal inlet fluid temperature into all boreholes. """ -import matplotlib.pyplot as plt +try: + import matplotlib.pyplot as plt + enable_plotting = True +except ModuleNotFoundError: + enable_plotting = False + import numpy as np from scipy.constants import pi import pygfunction as gt -def main(): +def main(make_plots=True): # ------------------------------------------------------------------------- # Simulation parameters # ------------------------------------------------------------------------- @@ -116,19 +121,18 @@ def main(): gfunc_equal_Tf_in = gt.gfunction.gFunction( network, alpha, time=time, boundary_condition='MIFT', options=options) - # ------------------------------------------------------------------------- - # Plot g-functions - # ------------------------------------------------------------------------- - - ax = gfunc_uniform_Q.visualize_g_function().axes[0] - ax.plot(np.log(time/ts), gfunc_uniform_T.gFunc, 'k--') - ax.plot(np.log(time/ts), gfunc_equal_Tf_in.gFunc, 'r-.') - ax.legend(['Uniform heat extraction rate', - 'Uniform borehole wall temperature', - 'Equal inlet temperature']) - plt.tight_layout() - - return + if enable_plotting and make_plots: + # ------------------------------------------------------------------------- + # Plot g-functions + # ------------------------------------------------------------------------- + + ax = gfunc_uniform_Q.visualize_g_function().axes[0] + ax.plot(np.log(time/ts), gfunc_uniform_T.gFunc, 'k--') + ax.plot(np.log(time/ts), gfunc_equal_Tf_in.gFunc, 'r-.') + ax.legend(['Uniform heat extraction rate', + 'Uniform borehole wall temperature', + 'Equal inlet temperature']) + plt.tight_layout() # Main function diff --git a/examples/fluid_temperature.py b/examples/fluid_temperature.py index 77bdc30..fb694b4 100644 --- a/examples/fluid_temperature.py +++ b/examples/fluid_temperature.py @@ -11,14 +11,19 @@ compared. """ -import matplotlib.pyplot as plt +try: + import matplotlib.pyplot as plt + enable_plotting = True +except ModuleNotFoundError: + enable_plotting = False + import numpy as np from scipy.constants import pi import pygfunction as gt -def main(): +def main(make_plots=True): # ------------------------------------------------------------------------- # Simulation parameters # ------------------------------------------------------------------------- @@ -74,7 +79,7 @@ def main(): time = dt * np.arange(1, Nt+1) # Evaluate heat extraction rate - Q = synthetic_load(time/3600.) + Q = gt.utilities.synthetic_load(time/3600.) # Load aggregation scheme LoadAgg = gt.load_aggregation.ClaessonJaved(dt, tmax) @@ -163,135 +168,109 @@ def main(): T_f_out_double_ser[i] = DoubleUTube_ser.get_outlet_temperature( T_f_in_double_ser[i], T_b[i], m_flow, cp_f) - # ------------------------------------------------------------------------- - # Plot hourly heat extraction rates and temperatures - # ------------------------------------------------------------------------- - - # Configure figure and axes - fig = gt.utilities._initialize_figure() - - ax1 = fig.add_subplot(211) - # Axis labels - ax1.set_xlabel(r'Time [hours]') - ax1.set_ylabel(r'Total heat extraction rate [W]') - gt.utilities._format_axes(ax1) - - # Plot heat extraction rates - hours = np.arange(1, Nt+1) * dt / 3600. - ax1.plot(hours, Q) - - ax2 = fig.add_subplot(212) - # Axis labels - ax2.set_xlabel(r'Time [hours]') - ax2.set_ylabel(r'Temperature [degC]') - gt.utilities._format_axes(ax2) - - # Plot temperatures - ax2.plot(hours, T_b, 'k-', lw=1.5, label='Borehole wall') - ax2.plot(hours, T_f_out_single, '--', - label='Outlet, single U-tube') - ax2.plot(hours, T_f_out_double_par, '-.', - label='Outlet, double U-tube (parallel)') - ax2.plot(hours, T_f_out_double_ser, ':', - label='Outlet, double U-tube (series)') - ax2.legend() - - # Adjust to plot window - plt.tight_layout() - - # ------------------------------------------------------------------------- - # Plot fluid temperature profiles - # ------------------------------------------------------------------------- - - # Evaluate temperatures at nz evenly spaced depths along the borehole - # at the (it+1)-th time step - nz = 20 - it = 8724 - z = np.linspace(0., H, num=nz) - T_f_single = SingleUTube.get_temperature(z, - T_f_in_single[it], - T_b[it], - m_flow, - cp_f) - T_f_double_par = DoubleUTube_par.get_temperature(z, - T_f_in_double_par[it], - T_b[it], - m_flow, - cp_f) - T_f_double_ser = DoubleUTube_ser.get_temperature(z, - T_f_in_double_ser[it], - T_b[it], - m_flow, - cp_f) - - # Configure figure and axes - fig = gt.utilities._initialize_figure() - - ax3 = fig.add_subplot(131) - # Axis labels - ax3.set_xlabel(r'Temperature [degC]') - ax3.set_ylabel(r'Depth from borehole head [m]') - gt.utilities._format_axes(ax3) - - # Plot temperatures - ax3.plot(np.array([T_b[it], T_b[it]]), np.array([0., H]), 'k--') - ax3.plot(T_f_single, z, 'b-') - ax3.legend(['Borehole wall', 'Fluid']) - - ax4 = fig.add_subplot(132) - # Axis labels - ax4.set_xlabel(r'Temperature [degC]') - ax4.set_ylabel(r'Depth from borehole head [m]') - gt.utilities._format_axes(ax4) - - # Plot temperatures - ax4.plot(T_f_double_par, z, 'b-') - ax4.plot(np.array([T_b[it], T_b[it]]), np.array([0., H]), 'k--') - - ax5 = fig.add_subplot(133) - # Axis labels - ax5.set_xlabel(r'Temperature [degC]') - ax5.set_ylabel(r'Depth from borehole head [m]') - gt.utilities._format_axes(ax5) - - # Plot temperatures - ax5.plot(T_f_double_ser, z, 'b-') - ax5.plot(np.array([T_b[it], T_b[it]]), np.array([0., H]), 'k--') - - # Reverse y-axes - ax3.set_ylim(ax3.get_ylim()[::-1]) - ax4.set_ylim(ax4.get_ylim()[::-1]) - ax5.set_ylim(ax5.get_ylim()[::-1]) - # Adjust to plot window - plt.tight_layout() - - return - - -def synthetic_load(x): - """ - Synthetic load profile of Bernier et al. (2004). - - Returns load y (in watts) at time x (in hours). - """ - A = 2000.0 - B = 2190.0 - C = 80.0 - D = 2.0 - E = 0.01 - F = 0.0 - G = 0.95 - - func = (168.0-C)/168.0 - for i in [1, 2, 3]: - func += 1.0/(i*pi)*(np.cos(C*pi*i/84.0)-1.0) \ - *(np.sin(pi*i/84.0*(x-B))) - func = func*A*np.sin(pi/12.0*(x-B)) \ - *np.sin(pi/4380.0*(x-B)) - - y = func + (-1.0)**np.floor(D/8760.0*(x-B))*abs(func) \ - + E*(-1.0)**np.floor(D/8760.0*(x-B))/np.sign(np.cos(D*pi/4380.0*(x-F))+G) - return -y + if enable_plotting and make_plots: + + # ------------------------------------------------------------------------- + # Plot hourly heat extraction rates and temperatures + # ------------------------------------------------------------------------- + + # Configure figure and axes + fig = gt.utilities._initialize_figure() + + ax1 = fig.add_subplot(211) + # Axis labels + ax1.set_xlabel(r'Time [hours]') + ax1.set_ylabel(r'Total heat extraction rate [W]') + gt.utilities._format_axes(ax1) + + # Plot heat extraction rates + hours = np.arange(1, Nt+1) * dt / 3600. + ax1.plot(hours, Q) + + ax2 = fig.add_subplot(212) + # Axis labels + ax2.set_xlabel(r'Time [hours]') + ax2.set_ylabel(r'Temperature [degC]') + gt.utilities._format_axes(ax2) + + # Plot temperatures + ax2.plot(hours, T_b, 'k-', lw=1.5, label='Borehole wall') + ax2.plot(hours, T_f_out_single, '--', + label='Outlet, single U-tube') + ax2.plot(hours, T_f_out_double_par, '-.', + label='Outlet, double U-tube (parallel)') + ax2.plot(hours, T_f_out_double_ser, ':', + label='Outlet, double U-tube (series)') + ax2.legend() + + # Adjust to plot window + plt.tight_layout() + + # ------------------------------------------------------------------------- + # Plot fluid temperature profiles + # ------------------------------------------------------------------------- + + # Evaluate temperatures at nz evenly spaced depths along the borehole + # at the (it+1)-th time step + nz = 20 + it = 8724 + z = np.linspace(0., H, num=nz) + T_f_single = SingleUTube.get_temperature(z, + T_f_in_single[it], + T_b[it], + m_flow, + cp_f) + T_f_double_par = DoubleUTube_par.get_temperature(z, + T_f_in_double_par[it], + T_b[it], + m_flow, + cp_f) + T_f_double_ser = DoubleUTube_ser.get_temperature(z, + T_f_in_double_ser[it], + T_b[it], + m_flow, + cp_f) + + # Configure figure and axes + fig = gt.utilities._initialize_figure() + + ax3 = fig.add_subplot(131) + # Axis labels + ax3.set_xlabel(r'Temperature [degC]') + ax3.set_ylabel(r'Depth from borehole head [m]') + gt.utilities._format_axes(ax3) + + # Plot temperatures + ax3.plot(np.array([T_b[it], T_b[it]]), np.array([0., H]), 'k--') + ax3.plot(T_f_single, z, 'b-') + ax3.legend(['Borehole wall', 'Fluid']) + + ax4 = fig.add_subplot(132) + # Axis labels + ax4.set_xlabel(r'Temperature [degC]') + ax4.set_ylabel(r'Depth from borehole head [m]') + gt.utilities._format_axes(ax4) + + # Plot temperatures + ax4.plot(T_f_double_par, z, 'b-') + ax4.plot(np.array([T_b[it], T_b[it]]), np.array([0., H]), 'k--') + + ax5 = fig.add_subplot(133) + # Axis labels + ax5.set_xlabel(r'Temperature [degC]') + ax5.set_ylabel(r'Depth from borehole head [m]') + gt.utilities._format_axes(ax5) + + # Plot temperatures + ax5.plot(T_f_double_ser, z, 'b-') + ax5.plot(np.array([T_b[it], T_b[it]]), np.array([0., H]), 'k--') + + # Reverse y-axes + ax3.set_ylim(ax3.get_ylim()[::-1]) + ax4.set_ylim(ax4.get_ylim()[::-1]) + ax5.set_ylim(ax5.get_ylim()[::-1]) + # Adjust to plot window + plt.tight_layout() # Main function diff --git a/examples/fluid_temperature_multiple_boreholes.py b/examples/fluid_temperature_multiple_boreholes.py index 93b8c74..a57c0a0 100644 --- a/examples/fluid_temperature_multiple_boreholes.py +++ b/examples/fluid_temperature_multiple_boreholes.py @@ -9,14 +9,19 @@ evaluated. """ -import matplotlib.pyplot as plt +try: + import matplotlib.pyplot as plt + enable_plotting = True +except ModuleNotFoundError: + enable_plotting = False + import numpy as np from scipy.constants import pi import pygfunction as gt -def main(): +def main(make_plots=True): # ------------------------------------------------------------------------- # Simulation parameters # ------------------------------------------------------------------------- @@ -123,7 +128,7 @@ def main(): # ------------------------------------------------------------------------- # Evaluate heat extraction rate - Q_tot = nBoreholes*synthetic_load(time/3600.) + Q_tot = nBoreholes*gt.utilities.synthetic_load(time/3600.) T_b = np.zeros(Nt) T_f_in = np.zeros(Nt) @@ -148,98 +153,71 @@ def main(): T_f_out[i] = network.get_network_outlet_temperature( T_f_in[i], T_b[i], m_flow_network, cp_f, nSegments=1) - # ------------------------------------------------------------------------- - # Plot hourly heat extraction rates and temperatures - # ------------------------------------------------------------------------- - - # Configure figure and axes - fig = gt.utilities._initialize_figure() - - ax1 = fig.add_subplot(211) - # Axis labels - ax1.set_xlabel(r'Time [hours]') - ax1.set_ylabel(r'Total heat extraction rate [W]') - gt.utilities._format_axes(ax1) - - # Plot heat extraction rates - hours = np.arange(1, Nt+1) * dt / 3600. - ax1.plot(hours, Q_tot) - - ax2 = fig.add_subplot(212) - # Axis labels - ax2.set_xlabel(r'Time [hours]') - ax2.set_ylabel(r'Temperature [degC]') - gt.utilities._format_axes(ax2) - - # Plot temperatures - ax2.plot(hours, T_b, label='Borehole wall') - ax2.plot(hours, T_f_out, '-.', - label='Outlet, double U-tube (parallel)') - ax2.legend() - - # Adjust to plot window - plt.tight_layout() - - # ------------------------------------------------------------------------- - # Plot fluid temperature profiles - # ------------------------------------------------------------------------- - - # Evaluate temperatures at nz evenly spaced depths along the borehole - # at the (it+1)-th time step - nz = 20 - it = 8724 - z = np.linspace(0., H, num=nz) - T_f = UTubes[0].get_temperature( - z, T_f_in[it], T_b[it], m_flow_borehole, cp_f) - - - # Configure figure and axes - fig = gt.utilities._initialize_figure() - - ax3 = fig.add_subplot(111) - # Axis labels - ax3.set_xlabel(r'Temperature [degC]') - ax3.set_ylabel(r'Depth from borehole head [m]') - gt.utilities._format_axes(ax3) - - # Plot temperatures - pltFlu = ax3.plot(T_f, z, 'b-', label='Fluid') - pltWal = ax3.plot(np.array([T_b[it], T_b[it]]), np.array([0., H]), - 'k--', label='Borehole wall') - ax3.legend(handles=[pltFlu[0]]+pltWal) - - # Reverse y-axes - ax3.set_ylim(ax3.get_ylim()[::-1]) - # Adjust to plot window - plt.tight_layout() - - return - - -def synthetic_load(x): - """ - Synthetic load profile of Bernier et al. (2004). - - Returns load y (in watts) at time x (in hours). - """ - A = 2000.0 - B = 2190.0 - C = 80.0 - D = 2.0 - E = 0.01 - F = 0.0 - G = 0.95 - - func = (168.0-C)/168.0 - for i in [1, 2, 3]: - func += 1.0/(i*pi)*(np.cos(C*pi*i/84.0)-1.0) \ - *(np.sin(pi*i/84.0*(x-B))) - func = func*A*np.sin(pi/12.0*(x-B)) \ - *np.sin(pi/4380.0*(x-B)) - - y = func + (-1.0)**np.floor(D/8760.0*(x-B))*abs(func) \ - + E*(-1.0)**np.floor(D/8760.0*(x-B))/np.sign(np.cos(D*pi/4380.0*(x-F))+G) - return -y + if enable_plotting and make_plots: + # ------------------------------------------------------------------------- + # Plot hourly heat extraction rates and temperatures + # ------------------------------------------------------------------------- + + # Configure figure and axes + fig = gt.utilities._initialize_figure() + + ax1 = fig.add_subplot(211) + # Axis labels + ax1.set_xlabel(r'Time [hours]') + ax1.set_ylabel(r'Total heat extraction rate [W]') + gt.utilities._format_axes(ax1) + + # Plot heat extraction rates + hours = np.arange(1, Nt+1) * dt / 3600. + ax1.plot(hours, Q_tot) + + ax2 = fig.add_subplot(212) + # Axis labels + ax2.set_xlabel(r'Time [hours]') + ax2.set_ylabel(r'Temperature [degC]') + gt.utilities._format_axes(ax2) + + # Plot temperatures + ax2.plot(hours, T_b, label='Borehole wall') + ax2.plot(hours, T_f_out, '-.', + label='Outlet, double U-tube (parallel)') + ax2.legend() + + # Adjust to plot window + plt.tight_layout() + + # ------------------------------------------------------------------------- + # Plot fluid temperature profiles + # ------------------------------------------------------------------------- + + # Evaluate temperatures at nz evenly spaced depths along the borehole + # at the (it+1)-th time step + nz = 20 + it = 8724 + z = np.linspace(0., H, num=nz) + T_f = UTubes[0].get_temperature( + z, T_f_in[it], T_b[it], m_flow_borehole, cp_f) + + + # Configure figure and axes + fig = gt.utilities._initialize_figure() + + ax3 = fig.add_subplot(111) + # Axis labels + ax3.set_xlabel(r'Temperature [degC]') + ax3.set_ylabel(r'Depth from borehole head [m]') + gt.utilities._format_axes(ax3) + + # Plot temperatures + pltFlu = ax3.plot(T_f, z, 'b-', label='Fluid') + pltWal = ax3.plot(np.array([T_b[it], T_b[it]]), np.array([0., H]), + 'k--', label='Borehole wall') + ax3.legend(handles=[pltFlu[0]]+pltWal) + + # Reverse y-axes + ax3.set_ylim(ax3.get_ylim()[::-1]) + # Adjust to plot window + plt.tight_layout() # Main function diff --git a/examples/inclined_boreholes.py b/examples/inclined_boreholes.py index 386821c..1f092ee 100644 --- a/examples/inclined_boreholes.py +++ b/examples/inclined_boreholes.py @@ -18,7 +18,7 @@ import numpy as np -def main(): +def main(make_plots=True): # ------------------------------------------------------------------------- # Simulation parameters # ------------------------------------------------------------------------- @@ -72,8 +72,9 @@ def main(): H, D, r_b, i * B, 0., tilt=tilt, orientation=orientation) boreField1.append(borehole) - # Visualize the borehole field - fig1 = gt.boreholes.visualize_field(boreField1) + if make_plots: + # Visualize the borehole field + gt.boreholes.visualize_field(boreField1) """ Bore field #2 @@ -88,8 +89,9 @@ def main(): # Field of 6 boreholes in a circle boreField2 = gt.boreholes.circle_field(N, R, H, D, r_b, tilt=tilt) - # Visualize the borehole field - fig2 = gt.boreholes.visualize_field(boreField2) + if make_plots: + # Visualize the borehole field + gt.boreholes.visualize_field(boreField2) # ------------------------------------------------------------------------- # Evaluate g-functions for all fields @@ -97,15 +99,20 @@ def main(): # Bore field #1 gfunc1 = gt.gfunction.gFunction( boreField1, alpha, time=time, options=options, method='similarities') - fig3 = gfunc1.visualize_g_function() - fig3.suptitle('"Optimal" field of 8 boreholes') - fig3.tight_layout() + + if make_plots: + fig3 = gfunc1.visualize_g_function() + fig3.suptitle('"Optimal" field of 8 boreholes') + fig3.tight_layout() + # Bore field #2 gfunc2 = gt.gfunction.gFunction( boreField2, alpha, time=time, options=options, method='similarities') - fig4 = gfunc2.visualize_g_function() - fig4.suptitle(f'Field of {N} boreholes in a circle') - fig4.tight_layout() + + if make_plots: + fig4 = gfunc2.visualize_g_function() + fig4.suptitle(f'Field of {N} boreholes in a circle') + fig4.tight_layout() # Main function diff --git a/examples/load_aggregation.py b/examples/load_aggregation.py index 1da0cb6..689b3fb 100644 --- a/examples/load_aggregation.py +++ b/examples/load_aggregation.py @@ -7,7 +7,12 @@ are simulated using the aggregation method of Claesson and Javed (2012). """ -import matplotlib.pyplot as plt +try: + import matplotlib.pyplot as plt + enable_plotting = True +except ModuleNotFoundError: + enable_plotting = False + import numpy as np from scipy.constants import pi from scipy.interpolate import interp1d @@ -16,7 +21,7 @@ import pygfunction as gt -def main(): +def main(make_plots=True): # ------------------------------------------------------------------------- # Simulation parameters # ------------------------------------------------------------------------- @@ -42,7 +47,7 @@ def main(): time = dt * np.arange(1, Nt+1) # Evaluate heat extraction rate - Q_b = synthetic_load(time/3600.) + Q_b = gt.utilities.synthetic_load(time/3600.) # Load aggregation scheme LoadAgg = gt.load_aggregation.ClaessonJaved(dt, tmax) @@ -73,7 +78,7 @@ def main(): # Apply current load LoadAgg.set_current_load(Q_b_i/H) - # Evaluate borehole wall temeprature + # Evaluate borehole wall temperature deltaT_b = LoadAgg.temporal_superposition() T_b[i] = T_g - deltaT_b @@ -91,69 +96,42 @@ def main(): # Convolution in Fourier domain T_b_exact = T_g - fftconvolve(dQ, g/(2.0*pi*k_s*H), mode='full')[0:Nt] - # ------------------------------------------------------------------------- - # plot results - # ------------------------------------------------------------------------- + if enable_plotting and make_plots: + # ------------------------------------------------------------------------- + # plot results + # ------------------------------------------------------------------------- + + # Configure figure and axes + fig = gt.utilities._initialize_figure() + + ax1 = fig.add_subplot(311) + # Axis labels + ax1.set_xlabel(r'$t$ [hours]') + ax1.set_ylabel(r'$Q_b$ [W]') + gt.utilities._format_axes(ax1) + + hours = np.arange(1, Nt+1) * dt / 3600. + ax1.plot(hours, Q_b) + + ax2 = fig.add_subplot(312) + # Axis labels + ax2.set_xlabel(r'$t$ [hours]') + ax2.set_ylabel(r'$T_b$ [degC]') + gt.utilities._format_axes(ax2) + + ax2.plot(hours, T_b) + ax2.plot(hours, T_b_exact, 'k.') + + ax3 = fig.add_subplot(313) + # Axis labels + ax3.set_xlabel(r'$t$ [hours]') + ax3.set_ylabel(r'Error [degC]') + gt.utilities._format_axes(ax3) + + ax3.plot(hours, T_b - T_b_exact) - # Configure figure and axes - fig = gt.utilities._initialize_figure() - - ax1 = fig.add_subplot(311) - # Axis labels - ax1.set_xlabel(r'$t$ [hours]') - ax1.set_ylabel(r'$Q_b$ [W]') - gt.utilities._format_axes(ax1) - - hours = np.arange(1, Nt+1) * dt / 3600. - ax1.plot(hours, Q_b) - - ax2 = fig.add_subplot(312) - # Axis labels - ax2.set_xlabel(r'$t$ [hours]') - ax2.set_ylabel(r'$T_b$ [degC]') - gt.utilities._format_axes(ax2) - - ax2.plot(hours, T_b) - ax2.plot(hours, T_b_exact, 'k.') - - ax3 = fig.add_subplot(313) - # Axis labels - ax3.set_xlabel(r'$t$ [hours]') - ax3.set_ylabel(r'Error [degC]') - gt.utilities._format_axes(ax3) - - ax3.plot(hours, T_b - T_b_exact) - - # Adjust to plot window - plt.tight_layout() - - return - - -def synthetic_load(x): - """ - Synthetic load profile of Bernier et al. (2004). - - Returns load y (in watts) at time x (in hours). - """ - A = 2000.0 - B = 2190.0 - C = 80.0 - D = 2.0 - E = 0.01 - F = 0.0 - G = 0.95 - - func = (168.0-C)/168.0 - for i in [1,2,3]: - func += 1.0/(i*pi)*(np.cos(C*pi*i/84.0)-1.0) \ - *(np.sin(pi*i/84.0*(x-B))) - func = func*A*np.sin(pi/12.0*(x-B)) \ - *np.sin(pi/4380.0*(x-B)) - - y = func + (-1.0)**np.floor(D/8760.0*(x-B))*abs(func) \ - + E*(-1.0)**np.floor(D/8760.0*(x-B))/np.sign(np.cos(D*pi/4380.0*(x-F))+G) - return -y + # Adjust to plot window + plt.tight_layout() # Main function diff --git a/examples/mixed_inlet_conditions.py b/examples/mixed_inlet_conditions.py index 3c637df..9f2c0d4 100644 --- a/examples/mixed_inlet_conditions.py +++ b/examples/mixed_inlet_conditions.py @@ -8,14 +8,19 @@ temperature, rather than the average borehole wall temperature. """ -import matplotlib.pyplot as plt +try: + import matplotlib.pyplot as plt + enable_plotting = True +except ModuleNotFoundError: + enable_plotting = False + import numpy as np from scipy.constants import pi import pygfunction as gt -def main(): +def main(make_plots=True): # ------------------------------------------------------------------------- # Simulation parameters # ------------------------------------------------------------------------- @@ -126,23 +131,22 @@ def main(): network, alpha, time=time, boundary_condition='MIFT', options=options, method=method) - # ------------------------------------------------------------------------- - # Plot g-functions - # ------------------------------------------------------------------------- - - ax = gfunc_Tb.visualize_g_function().axes[0] - ax.plot(np.log(time/ts), gfunc_equal_Tf_mixed.gFunc, 'r-.') - ax.legend(['Uniform temperature', 'Mixed inlet temperature']) - plt.tight_layout() - - # For the mixed inlet fluid temperature condition, draw the temperatures - # and heat extraction rates - gfunc_equal_Tf_mixed.visualize_temperatures() - gfunc_equal_Tf_mixed.visualize_temperature_profiles() - gfunc_equal_Tf_mixed.visualize_heat_extraction_rates() - gfunc_equal_Tf_mixed.visualize_heat_extraction_rate_profiles() - - return + if enable_plotting and make_plots: + # ------------------------------------------------------------------------- + # Plot g-functions + # ------------------------------------------------------------------------- + + ax = gfunc_Tb.visualize_g_function().axes[0] + ax.plot(np.log(time/ts), gfunc_equal_Tf_mixed.gFunc, 'r-.') + ax.legend(['Uniform temperature', 'Mixed inlet temperature']) + plt.tight_layout() + + # For the mixed inlet fluid temperature condition, draw the temperatures + # and heat extraction rates + gfunc_equal_Tf_mixed.visualize_temperatures() + gfunc_equal_Tf_mixed.visualize_temperature_profiles() + gfunc_equal_Tf_mixed.visualize_heat_extraction_rates() + gfunc_equal_Tf_mixed.visualize_heat_extraction_rate_profiles() # Main function diff --git a/examples/multiple_independent_Utubes.py b/examples/multiple_independent_Utubes.py index 1008994..7ce7070 100644 --- a/examples/multiple_independent_Utubes.py +++ b/examples/multiple_independent_Utubes.py @@ -11,15 +11,20 @@ """ from pathlib import Path -import matplotlib.lines as mlines -import matplotlib.pyplot as plt +try: + import matplotlib.lines as mlines + import matplotlib.pyplot as plt + enable_plotting = True +except ModuleNotFoundError: + enable_plotting = False + import numpy as np from scipy.constants import pi import pygfunction as gt -def main(): +def main(make_plots=True): # ------------------------------------------------------------------------- # Simulation parameters # ------------------------------------------------------------------------- @@ -82,54 +87,55 @@ def main(): z = np.linspace(0., H, num=nz) T_f = MultipleUTube.get_temperature(z, T_f_in, T_b, m_flow_borehole, cp_f) - # ------------------------------------------------------------------------- - # Plot fluid temperature profiles - # ------------------------------------------------------------------------- - - # Configure figure and axes - fig = gt.utilities._initialize_figure() - - ax1 = fig.add_subplot(111) - # Axis labels - ax1.set_xlabel(r'Temperature [degC]') - ax1.set_ylabel(r'Depth from borehole head [m]') - gt.utilities._format_axes(ax1) - - # Plot temperatures - ax1.plot(T_f, z, 'k.') - ax1.plot(np.array([T_b, T_b]), np.array([0., H]), 'k--') - # Labels - calculated = mlines.Line2D([], [], - color='black', - ls='None', - marker='.', - label='Fluid') - borehole_temp = mlines.Line2D([], [], - color='black', - ls='--', + if enable_plotting and make_plots: + + # ------------------------------------------------------------------------- + # Plot fluid temperature profiles + # ------------------------------------------------------------------------- + + # Configure figure and axes + fig = gt.utilities._initialize_figure() + + ax1 = fig.add_subplot(111) + # Axis labels + ax1.set_xlabel(r'Temperature [degC]') + ax1.set_ylabel(r'Depth from borehole head [m]') + gt.utilities._format_axes(ax1) + + # Plot temperatures + ax1.plot(T_f, z, 'k.') + ax1.plot(np.array([T_b, T_b]), np.array([0., H]), 'k--') + # Labels + calculated = mlines.Line2D([], [], + color='black', + ls='None', + marker='.', + label='Fluid') + borehole_temp = mlines.Line2D([], [], + color='black', + ls='--', + marker='None', + label='Borehole wall') + plt.tight_layout() + + # ------------------------------------------------------------------------- + # Load data from Cimmino (2016) + # ------------------------------------------------------------------------- + data = np.loadtxt(filePath, skiprows=1) + ax1.plot(data[:,2:], data[:,0], 'b-',) + reference = mlines.Line2D([], [], + color='blue', + ls='-', + lw=1.5, marker='None', - label='Borehole wall') - plt.tight_layout() + label='Cimmino (2016)') + ax1.legend(handles=[borehole_temp, calculated, reference], + loc='upper left') + + # Reverse y-axis + ax1.set_ylim(ax1.get_ylim()[::-1]) + # Adjust to plot window - # ------------------------------------------------------------------------- - # Load data from Cimmino (2016) - # ------------------------------------------------------------------------- - data = np.loadtxt(filePath, skiprows=1) - ax1.plot(data[:,2:], data[:,0], 'b-',) - reference = mlines.Line2D([], [], - color='blue', - ls='-', - lw=1.5, - marker='None', - label='Cimmino (2016)') - ax1.legend(handles=[borehole_temp, calculated, reference], - loc='upper left') - - # Reverse y-axis - ax1.set_ylim(ax1.get_ylim()[::-1]) - # Adjust to plot window - - return def _pipePositions(Ds, nPipes): diff --git a/examples/multipole_temperature.py b/examples/multipole_temperature.py index b32a492..844a14a 100644 --- a/examples/multipole_temperature.py +++ b/examples/multipole_temperature.py @@ -12,14 +12,19 @@ """ from pathlib import Path -import matplotlib.pyplot as plt +try: + import matplotlib.pyplot as plt + enable_plotting = True +except ModuleNotFoundError: + enable_plotting = False + import numpy as np from scipy.constants import pi import pygfunction as gt -def main(): +def main(make_plots=True): # ------------------------------------------------------------------------- # Simulation parameters # ------------------------------------------------------------------------- @@ -95,27 +100,29 @@ def main(): # Load validation data data = np.loadtxt(filePath, skiprows=1) - # Configure figure and axes - fig = gt.utilities._initialize_figure() + if enable_plotting and make_plots: + + # Configure figure and axes + fig = gt.utilities._initialize_figure() - ax1 = fig.add_subplot(111) - # Axis labels - ax1.set_xlabel(r'x (m)') - ax1.set_ylabel(r'$T(x,0)$') - # Axis limits - ax1.set_xlim([-0.1, 0.1]) - ax1.set_ylim([-0.2, 1.2]) - # Show grid - ax1.grid() - gt.utilities._format_axes(ax1) + ax1 = fig.add_subplot(111) + # Axis labels + ax1.set_xlabel(r'x (m)') + ax1.set_ylabel(r'$T(x,0)$') + # Axis limits + ax1.set_xlim([-0.1, 0.1]) + ax1.set_ylim([-0.2, 1.2]) + # Show grid + ax1.grid() + gt.utilities._format_axes(ax1) - ax1.plot(x, T, label='pygfunction') - ax1.plot(data[:,0], data[:,1], 'ko', - label='Claesson and Hellstrom (2011)') - ax1.legend(loc='upper left') + ax1.plot(x, T, label='pygfunction') + ax1.plot(data[:,0], data[:,1], 'ko', + label='Claesson and Hellstrom (2011)') + ax1.legend(loc='upper left') - # Adjust to plot window - plt.tight_layout() + # Adjust to plot window + plt.tight_layout() # ------------------------------------------------------------------------- # Temperatures in -0.1 < x < 0.1, -0.1 < y < 0.1 @@ -133,36 +140,35 @@ def main(): x_T=X.flatten(), y_T=Y.flatten()) - # Configure figure and axes - fig = gt.utilities._initialize_figure() - - ax1 = fig.add_subplot(111) - # Axis labels - ax1.set_xlabel('x (m)') - ax1.set_ylabel('y (m)') - # Axis limits - plt.axis([-0.1, 0.1, -0.1, 0.1]) - plt.gca().set_aspect('equal', adjustable='box') - gt.utilities._format_axes(ax1) - - # Borehole wall outline - borewall = plt.Circle((0., 0.), radius=r_b, - fill=False, linestyle='--', linewidth=2.) - ax1.add_patch(borewall) - # Pipe outlines - for pos, r_out_n in zip(pos_pipes, rp_out): - pipe = plt.Circle(pos, radius=r_out_n, - fill=False, linestyle='-', linewidth=4.) - ax1.add_patch(pipe) - # Temperature contours - CS = ax1.contour(X, Y, T.reshape((N_xy, N_xy)), - np.linspace(-0.2, 1.0, num=7)) - plt.clabel(CS, inline=1, fontsize=10) - - # Adjust to plot window - plt.tight_layout() - - return + if enable_plotting and make_plots: + # Configure figure and axes + fig = gt.utilities._initialize_figure() + + ax1 = fig.add_subplot(111) + # Axis labels + ax1.set_xlabel('x (m)') + ax1.set_ylabel('y (m)') + # Axis limits + plt.axis([-0.1, 0.1, -0.1, 0.1]) + plt.gca().set_aspect('equal', adjustable='box') + gt.utilities._format_axes(ax1) + + # Borehole wall outline + borewall = plt.Circle((0., 0.), radius=r_b, + fill=False, linestyle='--', linewidth=2.) + ax1.add_patch(borewall) + # Pipe outlines + for pos, r_out_n in zip(pos_pipes, rp_out): + pipe = plt.Circle(pos, radius=r_out_n, + fill=False, linestyle='-', linewidth=4.) + ax1.add_patch(pipe) + # Temperature contours + CS = ax1.contour(X, Y, T.reshape((N_xy, N_xy)), + np.linspace(-0.2, 1.0, num=7)) + plt.clabel(CS, inline=1, fontsize=10) + + # Adjust to plot window + plt.tight_layout() # Main function diff --git a/examples/regular_bore_field.py b/examples/regular_bore_field.py index 5213024..42f97fc 100644 --- a/examples/regular_bore_field.py +++ b/examples/regular_bore_field.py @@ -2,12 +2,16 @@ """ Example of definition of a bore field using pre-defined configurations. """ -import matplotlib.pyplot as plt +try: + import matplotlib.pyplot as plt + enable_plotting = True +except ModuleNotFoundError: + enable_plotting = False import pygfunction as gt -def main(): +def main(make_plots=True): # ------------------------------------------------------------------------- # Parameters # ------------------------------------------------------------------------- @@ -51,16 +55,15 @@ def main(): # Circular field of 8 boreholes circleField = gt.boreholes.circle_field(N_b, R, H, D, r_b) - # ------------------------------------------------------------------------- - # Draw bore fields - # ------------------------------------------------------------------------- - for field in [ - rectangularField, staggeredRectangularField, denseRectangularField, - boxField, UField, LField, circleField]: - gt.boreholes.visualize_field(field) - plt.show() - - return + if enable_plotting and make_plots: + # ------------------------------------------------------------------------- + # Draw bore fields + # ------------------------------------------------------------------------- + for field in [ + rectangularField, staggeredRectangularField, denseRectangularField, + boxField, UField, LField, circleField]: + gt.boreholes.visualize_field(field) + plt.show() # Main function diff --git a/examples/unequal_segments.py b/examples/unequal_segments.py index 7ee3fb1..6c6db49 100644 --- a/examples/unequal_segments.py +++ b/examples/unequal_segments.py @@ -5,13 +5,18 @@ The g-functions of a field of 6x4 boreholes is calculated with unequal number of segments. """ -import matplotlib.pyplot as plt +try: + import matplotlib.pyplot as plt + enable_plotting = True +except ModuleNotFoundError: + enable_plotting = False + import numpy as np import pygfunction as gt -def main(): +def main(make_plots=True): # ------------------------------------------------------------------------- # Simulation parameters # ------------------------------------------------------------------------- @@ -40,7 +45,9 @@ def main(): N_1 = 6 N_2 = 4 boreField = gt.boreholes.rectangle_field(N_1, N_2, B, B, H, D, r_b) - gt.boreholes.visualize_field(boreField) + + if enable_plotting and make_plots: + gt.boreholes.visualize_field(boreField) # ------------------------------------------------------------------------- # Evaluate g-functions with different segment options @@ -95,37 +102,36 @@ def main(): g_func_predefined = gt.gfunction.gFunction( boreField, alpha, time=time, options=options, method=method) - # ------------------------------------------------------------------------- - # Plot g-functions - # ------------------------------------------------------------------------- - - ax = gfunc_equal.visualize_g_function().axes[0] - ax.plot(np.log(time/ts), gfunc_unequal.gFunc, 'r-.') - ax.plot(np.log(time/ts), g_func_predefined.gFunc, 'k-.') - ax.legend(['Equal number of segments', - 'Unequal number of segments', - 'Unequal segment lengths']) - plt.tight_layout() - - # Heat extraction rate profiles - fig = gfunc_unequal.visualize_heat_extraction_rates( - iBoreholes=[18, 12, 14]) - fig.suptitle('Heat extraction rates (unequal number of segments)') - fig.tight_layout() - fig = g_func_predefined.visualize_heat_extraction_rates( - iBoreholes=[18, 12, 14]) - fig.suptitle('Heat extraction rates (unequal segment lengths)') - fig.tight_layout() - fig = gfunc_unequal.visualize_heat_extraction_rate_profiles( - iBoreholes=[18, 12, 14]) - fig.suptitle('Heat extraction rate profiles (unequal number of segments)') - fig.tight_layout() - fig = g_func_predefined.visualize_heat_extraction_rate_profiles( - iBoreholes=[18, 12, 14]) - fig.suptitle('Heat extraction rate profiles (unequal segment lengths)') - fig.tight_layout() - - return + if enable_plotting and make_plots: + # ------------------------------------------------------------------------- + # Plot g-functions + # ------------------------------------------------------------------------- + + ax = gfunc_equal.visualize_g_function().axes[0] + ax.plot(np.log(time/ts), gfunc_unequal.gFunc, 'r-.') + ax.plot(np.log(time/ts), g_func_predefined.gFunc, 'k-.') + ax.legend(['Equal number of segments', + 'Unequal number of segments', + 'Unequal segment lengths']) + plt.tight_layout() + + # Heat extraction rate profiles + fig = gfunc_unequal.visualize_heat_extraction_rates( + iBoreholes=[18, 12, 14]) + fig.suptitle('Heat extraction rates (unequal number of segments)') + fig.tight_layout() + fig = g_func_predefined.visualize_heat_extraction_rates( + iBoreholes=[18, 12, 14]) + fig.suptitle('Heat extraction rates (unequal segment lengths)') + fig.tight_layout() + fig = gfunc_unequal.visualize_heat_extraction_rate_profiles( + iBoreholes=[18, 12, 14]) + fig.suptitle('Heat extraction rate profiles (unequal number of segments)') + fig.tight_layout() + fig = g_func_predefined.visualize_heat_extraction_rate_profiles( + iBoreholes=[18, 12, 14]) + fig.suptitle('Heat extraction rate profiles (unequal segment lengths)') + fig.tight_layout() # Main function diff --git a/examples/uniform_heat_extraction_rate.py b/examples/uniform_heat_extraction_rate.py index ae7c0dd..0e34b74 100644 --- a/examples/uniform_heat_extraction_rate.py +++ b/examples/uniform_heat_extraction_rate.py @@ -8,13 +8,18 @@ """ from pathlib import Path -import matplotlib.pyplot as plt +try: + import matplotlib.pyplot as plt + enable_plotting = True +except ModuleNotFoundError: + enable_plotting = False + import numpy as np import pygfunction as gt -def main(): +def main(make_plots=True): # ------------------------------------------------------------------------- # Simulation parameters # ------------------------------------------------------------------------- @@ -91,20 +96,20 @@ def main(): gfunc = gt.gfunction.gFunction( field, alpha, time=time, boundary_condition='UHTR', options=options[i], method=method) - # Draw g-function - ax = gfunc.visualize_g_function().axes[0] - # Draw reference g-function - ax.plot(data[:,0], data[:,i+1], 'bx') - ax.legend(['pygfunction', 'Cimmino and Bernier (2014)']) - ax.set_title('Field of {} boreholes'.format(len(field))) - plt.tight_layout() - - # For the second borefield, draw the evolution of heat extraction rates - if i == 1: - gfunc.visualize_temperatures(iBoreholes=[18, 12, 14]) - gfunc.visualize_temperature_profiles(iBoreholes=[14]) - - return + + if enable_plotting and make_plots: + # Draw g-function + ax = gfunc.visualize_g_function().axes[0] + # Draw reference g-function + ax.plot(data[:,0], data[:,i+1], 'bx') + ax.legend(['pygfunction', 'Cimmino and Bernier (2014)']) + ax.set_title('Field of {} boreholes'.format(len(field))) + plt.tight_layout() + + # For the second borefield, draw the evolution of heat extraction rates + if i == 1: + gfunc.visualize_temperatures(iBoreholes=[18, 12, 14]) + gfunc.visualize_temperature_profiles(iBoreholes=[14]) # Main function diff --git a/examples/uniform_temperature.py b/examples/uniform_temperature.py index 041591f..ffa90d8 100644 --- a/examples/uniform_temperature.py +++ b/examples/uniform_temperature.py @@ -9,14 +9,19 @@ """ from pathlib import Path -import matplotlib.pyplot as plt +try: + import matplotlib.pyplot as plt + enable_plotting = True +except ModuleNotFoundError: + enable_plotting = False + import numpy as np from time import perf_counter import pygfunction as gt -def main(): +def main(make_plots=True): # ------------------------------------------------------------------------- # Simulation parameters # ------------------------------------------------------------------------- @@ -88,42 +93,42 @@ def main(): field, alpha, time=time, options=options, method='equivalent') t2 = perf_counter() t_equivalent = t2 - t1 - # Draw g-function - ax = gfunc_similarities.visualize_g_function().axes[0] - ax.plot(lntts, gfunc_equivalent.gFunc) - # Draw reference g-function - ax.plot(data[:,0], data[:,i+1], 'o') - ax.legend([f'similarities (t = {t_similarities:.3f} sec)', - f'equivalent (t = {t_equivalent:.3f} sec)', - 'Cimmino and Bernier (2014)']) - ax.set_title(f'Field of {nBoreholes} boreholes') - plt.tight_layout() - - # For the second borefield, draw the evolution of heat extraction rates - if i == 1: - fig = gfunc_similarities.visualize_heat_extraction_rates( - iBoreholes=[18, 12, 14]) - fig.suptitle(f"Field of {nBoreholes} boreholes: 'similarities' " - f"solver") - fig.tight_layout() - - fig = gfunc_equivalent.visualize_heat_extraction_rates() - fig.suptitle(f"Field of {nBoreholes} boreholes: 'equivalent' " - f"solver") - fig.tight_layout() - - fig = gfunc_similarities.visualize_heat_extraction_rate_profiles( - iBoreholes=[18, 12, 14]) - fig.suptitle(f"Field of {nBoreholes} boreholes: 'similarities' " - f"solver") - fig.tight_layout() - - fig = gfunc_equivalent.visualize_heat_extraction_rate_profiles() - fig.suptitle(f"Field of {nBoreholes} boreholes: 'equivalent' " - f"solver") - fig.tight_layout() - - return + + if enable_plotting and make_plots: + # Draw g-function + ax = gfunc_similarities.visualize_g_function().axes[0] + ax.plot(lntts, gfunc_equivalent.gFunc) + # Draw reference g-function + ax.plot(data[:,0], data[:,i+1], 'o') + ax.legend([f'similarities (t = {t_similarities:.3f} sec)', + f'equivalent (t = {t_equivalent:.3f} sec)', + 'Cimmino and Bernier (2014)']) + ax.set_title(f'Field of {nBoreholes} boreholes') + plt.tight_layout() + + # For the second borefield, draw the evolution of heat extraction rates + if i == 1: + fig = gfunc_similarities.visualize_heat_extraction_rates( + iBoreholes=[18, 12, 14]) + fig.suptitle(f"Field of {nBoreholes} boreholes: 'similarities' " + f"solver") + fig.tight_layout() + + fig = gfunc_equivalent.visualize_heat_extraction_rates() + fig.suptitle(f"Field of {nBoreholes} boreholes: 'equivalent' " + f"solver") + fig.tight_layout() + + fig = gfunc_similarities.visualize_heat_extraction_rate_profiles( + iBoreholes=[18, 12, 14]) + fig.suptitle(f"Field of {nBoreholes} boreholes: 'similarities' " + f"solver") + fig.tight_layout() + + fig = gfunc_equivalent.visualize_heat_extraction_rate_profiles() + fig.suptitle(f"Field of {nBoreholes} boreholes: 'equivalent' " + f"solver") + fig.tight_layout() # Main function diff --git a/pygfunction/boreholes.py b/pygfunction/boreholes.py index 2b03bae..4f7aa1d 100644 --- a/pygfunction/boreholes.py +++ b/pygfunction/boreholes.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- -import matplotlib.pyplot as plt import numpy as np from scipy.constants import pi from scipy.spatial.distance import pdist @@ -1346,6 +1345,11 @@ def visualize_field( """ + try: + import matplotlib.pyplot as plt + except ModuleNotFoundError: + raise ModuleNotFoundError("matplotlib is not installed. pip install matplotlib to proceed") + # Configure figure and axes fig = _initialize_figure() if viewTop and view3D: diff --git a/pygfunction/gfunction.py b/pygfunction/gfunction.py index 2a43154..060ec5d 100644 --- a/pygfunction/gfunction.py +++ b/pygfunction/gfunction.py @@ -2,7 +2,6 @@ from time import perf_counter import warnings -import matplotlib.pyplot as plt import numpy as np from scipy.cluster.hierarchy import cut_tree, dendrogram, linkage from scipy.constants import pi @@ -293,6 +292,12 @@ def visualize_g_function(self): Figure object (matplotlib). """ + + try: + import matplotlib.pyplot as plt + except ModuleNotFoundError: + raise ModuleNotFoundError("matplotlib is not installed. pip install matplotlib to proceed") + # Configure figure and axes fig = _initialize_figure() ax = fig.add_subplot(111) @@ -332,6 +337,12 @@ def visualize_heat_extraction_rates(self, iBoreholes=None, showTilt=True): Figure object (matplotlib). """ + + try: + import matplotlib.pyplot as plt + except ModuleNotFoundError: + raise ModuleNotFoundError("matplotlib is not installed. pip install matplotlib to proceed") + # If iBoreholes is None, then plot all boreholes if iBoreholes is None: iBoreholes = range(len(self.solver.boreholes)) @@ -419,6 +430,12 @@ def visualize_heat_extraction_rate_profiles( Figure object (matplotlib). """ + + try: + import matplotlib.pyplot as plt + except ModuleNotFoundError: + raise ModuleNotFoundError("matplotlib is not installed. pip install matplotlib to proceed") + # If iBoreholes is None, then plot all boreholes if iBoreholes is None: iBoreholes = range(len(self.solver.boreholes)) @@ -496,6 +513,12 @@ def visualize_temperatures(self, iBoreholes=None, showTilt=True): Figure object (matplotlib). """ + + try: + import matplotlib.pyplot as plt + except ModuleNotFoundError: + raise ModuleNotFoundError("matplotlib is not installed. pip install matplotlib to proceed") + # If iBoreholes is None, then plot all boreholes if iBoreholes is None: iBoreholes = range(len(self.solver.boreholes)) @@ -581,6 +604,12 @@ def visualize_temperature_profiles( Figure object (matplotlib). """ + + try: + import matplotlib.pyplot as plt + except ModuleNotFoundError: + raise ModuleNotFoundError("matplotlib is not installed. pip install matplotlib to proceed") + # If iBoreholes is None, then plot all boreholes if iBoreholes is None: iBoreholes = range(len(self.boreholes)) @@ -4242,4 +4271,4 @@ def _check_solver_specific_inputs(self): [np.allclose(self.network.p[0]._Rd, pipe._Rd) for pipe in self.network.p]), \ "All boreholes must have the same piping configuration." - return + diff --git a/pygfunction/networks.py b/pygfunction/networks.py index f4ba8c7..9ddcda9 100644 --- a/pygfunction/networks.py +++ b/pygfunction/networks.py @@ -1518,4 +1518,3 @@ def _verify_bore_connectivity(bore_connectivity, nBoreholes): if n > nBoreholes: raise ValueError( 'The borehole connectivity list is invalid.') - return diff --git a/pygfunction/pipes.py b/pygfunction/pipes.py index f74f12f..628cf21 100644 --- a/pygfunction/pipes.py +++ b/pygfunction/pipes.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- -import matplotlib.pyplot as plt import numpy as np from scipy.constants import pi from scipy.special import binom @@ -741,6 +740,12 @@ def visualize_pipes(self): Figure object (matplotlib). """ + + try: + import matplotlib.pyplot as plt + except ModuleNotFoundError: + raise ModuleNotFoundError("matplotlib is not installed. pip install matplotlib to proceed") + # Configure figure and axes fig = _initialize_figure() ax = fig.add_subplot(111) @@ -2384,6 +2389,12 @@ def visualize_pipes(self): Figure object (matplotlib). """ + + try: + import matplotlib.pyplot as plt + except ModuleNotFoundError: + raise ModuleNotFoundError("matplotlib is not installed. pip install matplotlib to proceed") + # Configure figure and axes fig = _initialize_figure() ax = fig.add_subplot(111) diff --git a/pygfunction/utilities.py b/pygfunction/utilities.py index d1674fd..75ca25a 100644 --- a/pygfunction/utilities.py +++ b/pygfunction/utilities.py @@ -1,11 +1,37 @@ # -*- coding: utf-8 -*- -import matplotlib.pyplot as plt import numpy as np import numpy.polynomial.polynomial as poly +from scipy.constants import pi from scipy.special import erf import warnings +def synthetic_load(x): + """ + Synthetic load profile of Bernier et al. (2004). + + Returns load y (in watts) at time x (in hours). + """ + A = 2000.0 + B = 2190.0 + C = 80.0 + D = 2.0 + E = 0.01 + F = 0.0 + G = 0.95 + + func = (168.0-C)/168.0 + for i in [1, 2, 3]: + func += 1.0/(i*pi)*(np.cos(C*pi*i/84.0)-1.0) \ + *(np.sin(pi*i/84.0*(x-B))) + func = func*A*np.sin(pi/12.0*(x-B)) \ + *np.sin(pi/4380.0*(x-B)) + + y = func + (-1.0)**np.floor(D/8760.0*(x-B))*abs(func) \ + + E*(-1.0)**np.floor(D/8760.0*(x-B))/np.sign(np.cos(D*pi/4380.0*(x-F))+G) + return -y + + def cardinal_point(direction): accepted_inputs = ['E', 'ENE', 'NE', 'NNE', 'N', 'NNW', 'NW', 'WNW', @@ -366,6 +392,12 @@ def _initialize_figure(): Figure object (matplotlib). """ + + try: + import matplotlib.pyplot as plt + except ModuleNotFoundError: + raise ModuleNotFoundError("matplotlib is not installed. pip install matplotlib to proceed") + plt.rc('font', size=9) plt.rc('xtick', labelsize=9) plt.rc('ytick', labelsize=9) diff --git a/tests/examples_test.py b/tests/examples_test.py index ad62148..ba476fd 100644 --- a/tests/examples_test.py +++ b/tests/examples_test.py @@ -1,19 +1,79 @@ import os +import unittest from examples.bore_field_thermal_resistance import main as bftr_main from examples.comparison_gfunction_solvers import main as cgs_main from examples.comparison_load_aggregation import main as cla_main +from examples.custom_bore_field import main as cbf_main +from examples.custom_bore_field_from_file import main as cbff_main +from examples.custom_borehole import main as cb_main +from examples.equal_inlet_temperature import main as eit_main +from examples.fluid_temperature import main as ft_main +from examples.fluid_temperature_multiple_boreholes import main as ftmb_main +from examples.inclined_boreholes import main as ib_main +from examples.load_aggregation import main as la_main +from examples.mixed_inlet_conditions import main as mic_main +from examples.multiple_independent_Utubes import main as miu_main +from examples.multipole_temperature import main as mt_main +from examples.regular_bore_field import main as rbf_main +from examples.unequal_segments import main as us_main +from examples.uniform_heat_extraction_rate import main as uher_main +from examples.uniform_temperature import main as ut_main -import unittest class TestExamples(unittest.TestCase): - def test_bftr_main(self): + def test_bore_field_thermal_resistance_example(self): bftr_main(make_plots=False) - def test_cgs_main(self): + def test_comparison_gfunction_solvers_example(self): cgs_main(make_plots=False) - @unittest.skipIf("CI" not in os.environ, "Long running test that only runs on CI. Skipping.") - def test_cla_Main(self): + @unittest.skipIf("CI" not in os.environ, "long running test - only runs on CI") + def test_comparison_load_aggregation_example(self): cla_main(make_plots=False) + + def test_custom_bore_field_example(self): + cbf_main(make_plots=False) + + def test_custom_bore_field_from_file_example(self): + cbff_main(make_plots=False) + + def test_custom_borehole_example(self): + cb_main(make_plots=False) + + def test_equal_inlet_temperature_example(self): + eit_main(make_plots=False) + + def test_fluid_temperature_example(self): + ft_main(make_plots=False) + + def test_fluid_temperature_multiple_boreholes_example(self): + ftmb_main(make_plots=False) + + def test_inclined_boreholes_example(self): + ib_main(make_plots=False) + + def test_load_aggregation_example(self): + la_main(make_plots=False) + + def test_mixed_inlet_conditions_example(self): + mic_main(make_plots=False) + + def test_multiple_independent_Utubes_example(self): + miu_main(make_plots=False) + + def test_multipole_temperature_example(self): + mt_main(make_plots=False) + + def test_regular_bore_field_example(self): + rbf_main(make_plots=False) + + def test_unequal_segments_example(self): + us_main(make_plots=False) + + def test_uniform_heat_extraction_rate_example(self): + uher_main(make_plots=False) + + def test_uniform_temperature_example(self): + ut_main(make_plots=False)