Four different sizing cases

  1"""
  2This document contains checks to see whether or not adaptations to the code still comply with some specific cases.
  3It also shows the difference between the original L2 sizing methode (Peere et al., 2021) and a more general L3 one.
  4
  5This document contains 4 different cases referring to the paper: Peere, W., Picard, D., Cupeiro Figueroa, I., Boydens, W., and Helsen, L. Validated combined first and last year borefield sizing methodology. In Proceedings of International Building Simulation Conference 2021 (2021). Brugge (Belgium), 1-3 September 2021.
  6
  7"""
  8
  9import numpy as np
 10import pygfunction as gt
 11
 12from GHEtool import Borefield, GroundConstantTemperature, MonthlyGeothermalLoadAbsolute
 13
 14# relevant borefield data for the calculations
 15data = GroundConstantTemperature(3.5,  # conductivity of the soil (W/mK)
 16                                 10)   # Ground temperature at infinity (degrees C)
 17
 18borefield_gt = gt.boreholes.rectangle_field(10, 12, 6.5, 6.5, 100, 4, 0.075)
 19
 20
 21def load_case(number):
 22    """This function returns the values for one of the four cases."""
 23
 24    if number == 1:
 25        # case 1
 26        # limited in the first year by cooling
 27        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])
 28        monthly_load_cooling_percentage = np.array([0.025, 0.05, 0.05, .05, .075, .1, .2, .2, .1, .075, .05, .025])
 29        monthly_load_heating = monthly_load_heating_percentage * 300 * 10 ** 3  # kWh
 30        monthly_load_cooling = monthly_load_cooling_percentage * 150 * 10 ** 3  # kWh
 31        peak_cooling = np.array([0., 0., 22., 44., 83., 117., 134., 150., 100., 23., 0., 0.])
 32        peak_heating = np.zeros(12)
 33
 34    elif number == 2:
 35        # case 2
 36        # limited in the last year by cooling
 37        monthly_load_heating_percentage = np.array([0.155, 0.148, 0.125, .099, .064, 0., 0., 0., 0.061, 0.087, .117, 0.144])
 38        monthly_load_cooling_percentage = np.array([0.025, 0.05, 0.05, .05, .075, .1, .2, .2, .1, .075, .05, .025])
 39        monthly_load_heating = monthly_load_heating_percentage * 160 * 10 ** 3  # kWh
 40        monthly_load_cooling = monthly_load_cooling_percentage * 240 * 10 ** 3  # kWh
 41        peak_cooling = np.array([0., 0, 34., 69., 133., 187., 213., 240., 160., 37., 0., 0.])  # Peak cooling in kW
 42        peak_heating = np.array([160., 142, 102., 55., 0., 0., 0., 0., 40.4, 85., 119., 136.])
 43
 44    elif number == 3:
 45        # case 3
 46        # limited in the first year by heating
 47        monthly_load_heating_percentage = np.array([0.155, 0.148, 0.125, .099, .064, 0., 0., 0., 0.061, 0.087, .117, 0.144])
 48        monthly_load_cooling_percentage = np.array([0.025, 0.05, 0.05, .05, .075, .1, .2, .2, .1, .075, .05, .025])
 49        monthly_load_heating = monthly_load_heating_percentage * 160 * 10 ** 3  # kWh
 50        monthly_load_cooling = monthly_load_cooling_percentage * 240 * 10 ** 3  # kWh
 51        peak_cooling = np.zeros(12)
 52        peak_heating = np.array([300.0, 266.25, 191.25, 103.125, 0.0, 0.0, 0.0, 0.0, 75.75, 159.375, 223.125, 255.0])
 53
 54    else:
 55        # case 4
 56        # limited in the last year by heating
 57        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])
 58        monthly_load_cooling_percentage = np.array([0.025, 0.05, 0.05, .05, .075, .1, .2, .2, .1, .075, .05, .025])
 59        monthly_load_heating = monthly_load_heating_percentage * 300 * 10 ** 3  # kWh
 60        monthly_load_cooling = monthly_load_cooling_percentage * 150 * 10 ** 3  # kWh
 61        peak_cooling = np.array([0., 0., 22., 44., 83., 117., 134., 150., 100., 23., 0., 0.])
 62        peak_heating = np.array([300., 268., 191., 103., 75., 0., 0., 38., 76., 160., 224., 255.])
 63
 64    return monthly_load_heating, monthly_load_cooling, peak_heating, peak_cooling
 65
 66
 67def check_cases():
 68
 69    """
 70    This function checks whether the borefield sizing gives the correct (i.e. validated) results for the 4 cases.
 71    If not, an assertion error is raised.
 72    NOTE: these values differ slightly from the values in the mentioned paper. This is due to the fact that GHEtool uses slightly different precalculated data.
 73    """
 74
 75    correct_answers_L2 = (56.75, 117.23, 66.94, 91.32)
 76    correct_answers_L3 = (56.77, 118.74, 66.47, 91.24)
 77
 78    for i in (1, 2, 3, 4):
 79        borefield = Borefield(load=MonthlyGeothermalLoadAbsolute(*load_case(i)))
 80
 81        borefield.set_ground_parameters(data)
 82        borefield.set_borefield(borefield_gt)
 83        borefield.Rb = 0.2
 84
 85        # set temperature boundaries
 86        borefield.set_max_avg_fluid_temperature(16)  # maximum temperature
 87        borefield.set_min_avg_fluid_temperature(0)  # minimum temperature
 88
 89        borefield.size(100, L2_sizing=True)
 90        print(f'correct answer L2: {correct_answers_L2[i-1]}; calculated answer L2: {round(borefield.H,2)}; error: '
 91              f'{round(abs(1 - borefield.H / correct_answers_L2[i - 1]) * 100, 4)} %')
 92        assert np.isclose(borefield.H, correct_answers_L2[i-1], rtol=0.001)
 93
 94        borefield.size(100, L3_sizing=True)
 95        print(f'correct answer L3: {correct_answers_L3[i - 1]}; calculated answer L3: {round(borefield.H, 2)}; error: '
 96              f'{round(abs(1 - borefield.H / correct_answers_L3[i - 1]) * 100, 4)} %')
 97        assert np.isclose(borefield.H, correct_answers_L3[i-1], rtol=0.001)
 98
 99
100def check_custom_datafile():
101    """
102    This function checks whether the borefield sizing gives the correct (i.e. validated) results for the 4 cases given the custom datafile.
103    If not, an assertion error is raised.
104    """
105
106    # create custom datafile
107
108    correct_answers = (56.75, 117.23, 66.94, 91.32)
109
110    custom_field = gt.boreholes.rectangle_field(N_1=12, N_2=10, B_1=6.5, B_2=6.5, H=110., D=4, r_b=0.075)
111
112    for i in (1, 2, 3, 4):
113        borefield = Borefield(load=MonthlyGeothermalLoadAbsolute(*load_case(i)))
114
115        borefield.set_ground_parameters(data)
116        borefield.set_borefield(custom_field)
117        borefield.Rb = 0.2
118
119        # set temperature boundaries
120        borefield.set_max_avg_fluid_temperature(16)  # maximum temperature
121        borefield.set_min_avg_fluid_temperature(0)  # minimum temperature
122
123        borefield.size(100, L3_sizing=True)
124        print(f'correct answer: {correct_answers[i-1]}; calculated '
125              f'answer: {round(borefield.H,2)}; error: '
126              f'{round(abs(1-borefield.H/correct_answers[i - 1])*100,4)} %')
127
128
129if __name__ == "__main__":   # pragma: no cover
130    check_cases()  # check different cases
131    check_custom_datafile()  # check if the custom datafile is correct