Sizing method comparison (L2/L3)

  1"""
  2This document compares both the L2 sizing method of (Peere et al., 2021) with a more general L3 sizing.
  3The comparison is based on speed and relative accuracy in the result.
  4"""
  5
  6import time
  7
  8import numpy as np
  9import pygfunction as gt
 10
 11from GHEtool import Borefield, GroundConstantTemperature, MonthlyGeothermalLoadAbsolute
 12
 13
 14def sizing_method_comparison():
 15    number_of_iterations = 50
 16    max_value_cooling = 700
 17    max_value_heating = 800
 18
 19    # initiate the arrays
 20    results_L2 = np.zeros(number_of_iterations)
 21    results_L3 = np.zeros(number_of_iterations)
 22    difference_results = np.zeros(number_of_iterations)
 23
 24    monthly_load_cooling_array = np.empty((number_of_iterations, 12))
 25    monthly_load_heating_array = np.empty((number_of_iterations, 12))
 26    peak_load_cooling_array = np.empty((number_of_iterations, 12))
 27    peak_load_heating_array = np.empty((number_of_iterations, 12))
 28
 29    # populate arrays with random values
 30    for i in range(number_of_iterations):
 31        for j in range(12):
 32            monthly_load_cooling_array[i, j] = np.random.randint(0, max_value_cooling)
 33            monthly_load_heating_array[i, j] = np.random.randint(0, max_value_heating)
 34            peak_load_cooling_array[i, j] = np.random.randint(monthly_load_cooling_array[i, j], max_value_cooling)
 35            peak_load_heating_array[i, j] = np.random.randint(monthly_load_heating_array[i, j], max_value_heating)
 36
 37    # initiate borefield model
 38    data = GroundConstantTemperature(3, 10)
 39    borefield_gt = gt.boreholes.rectangle_field(10, 12, 6, 6, 110, 1, 0.075)
 40
 41    # Monthly loading values
 42    peak_cooling = np.array([0., 0, 34., 69., 133., 187., 213., 240., 160., 37., 0., 0.])  # Peak cooling in kW
 43    peak_heating = np.array([160., 142, 102., 55., 0., 0., 0., 0., 40.4, 85., 119., 136.])  # Peak heating in kW
 44
 45    # annual heating and cooling load
 46    annual_heating_load = 300 * 10 ** 3  # kWh
 47    annual_cooling_load = 160 * 10 ** 3  # kWh
 48
 49    # percentage of annual load per month (15.5% for January ...)
 50    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])
 51    monthly_load_cooling_percentage = np.array([0.025, 0.05, 0.05, .05, .075, .1, .2, .2, .1, .075, .05, .025])
 52
 53    # resulting load per month
 54    monthly_load_heating = annual_heating_load * monthly_load_heating_percentage   # kWh
 55    monthly_load_cooling = annual_cooling_load * monthly_load_cooling_percentage   # kWh
 56
 57    # set the load
 58    load = MonthlyGeothermalLoadAbsolute(monthly_load_heating, monthly_load_cooling, peak_heating, peak_cooling)
 59
 60    # create the borefield object
 61    borefield = Borefield(load=load)
 62    borefield.set_ground_parameters(data)
 63    borefield.set_borefield(borefield_gt)
 64    borefield.Rb = 0.2
 65
 66    # set temperature boundaries
 67    borefield.set_max_avg_fluid_temperature(16)   # maximum temperature
 68    borefield.set_min_avg_fluid_temperature(0)    # minimum temperature
 69
 70    # size according to L2 method
 71    start_L2 = time.time()
 72    for i in range(number_of_iterations):
 73        # set the load
 74        load = MonthlyGeothermalLoadAbsolute(monthly_load_heating_array[i], monthly_load_cooling_array[i],
 75                                             peak_load_heating_array[i], peak_load_cooling_array[i])
 76        borefield.load = load
 77        results_L2[i] = borefield.size(L2_sizing=True)
 78    end_L2 = time.time()
 79
 80    # size according to L3 method
 81    start_L3 = time.time()
 82    for i in range(number_of_iterations):
 83        # set the load
 84        load = MonthlyGeothermalLoadAbsolute(monthly_load_heating_array[i], monthly_load_cooling_array[i],
 85                                             peak_load_heating_array[i], peak_load_cooling_array[i])
 86        borefield.load = load
 87        results_L3[i] = borefield.size(L3_sizing=True)
 88    end_L3 = time.time()
 89
 90    print("Time for sizing according to L2:", end_L2 - start_L2, "s (or ", round((end_L2 - start_L2) / number_of_iterations * 1000, 3), "ms/sizing)")
 91    print("Time for sizing according to L3:", end_L3 - start_L3, "s (or ", round((end_L3 - start_L3) / number_of_iterations * 1000, 3), "ms/sizing)")
 92
 93    # calculate differences
 94    for i in range(number_of_iterations):
 95        difference_results[i] = results_L3[i] - results_L2[i]
 96
 97    print("The maximal difference between the sizing of L2 and L3 was:", np.round(np.max(difference_results), 3), "m or", np.round(np.max(difference_results) / results_L2[np.argmax(difference_results)] * 100, 3), "% w.r.t. the L2 sizing.")
 98    print("The mean difference between the sizing of L2 and L3 was:", np.round(np.mean(difference_results), 3), "m or", np.round(np.mean(difference_results) / np.mean(results_L2) * 100, 3), "% w.r.t. the L2 sizing.")
 99
100
101if __name__ == "__main__":   # pragma: no cover
102    sizing_method_comparison()