Borefield
This file contains all the code for the borefield calculations.
- class GHEtool.Borefield.Borefield(peak_heating: Optional[Union[_SupportsArray[dtype[Any]], _NestedSequence[_SupportsArray[dtype[Any]]], bool, int, float, complex, str, bytes, _NestedSequence[Union[bool, int, float, complex, str, bytes]]]] = None, peak_cooling: Optional[Union[_SupportsArray[dtype[Any]], _NestedSequence[_SupportsArray[dtype[Any]]], bool, int, float, complex, str, bytes, _NestedSequence[Union[bool, int, float, complex, str, bytes]]]] = None, baseload_heating: Optional[Union[_SupportsArray[dtype[Any]], _NestedSequence[_SupportsArray[dtype[Any]]], bool, int, float, complex, str, bytes, _NestedSequence[Union[bool, int, float, complex, str, bytes]]]] = None, baseload_cooling: Optional[Union[_SupportsArray[dtype[Any]], _NestedSequence[_SupportsArray[dtype[Any]]], bool, int, float, complex, str, bytes, _NestedSequence[Union[bool, int, float, complex, str, bytes]]]] = None, borefield: Optional[list[pygfunction.boreholes.Borehole]] = None, custom_gfunction: Optional[CustomGFunction] = None, load: Optional[_LoadData] = None)
Bases:
BaseClass
Main borefield class
- Parameters
- peak_heatinglist, numpy array
Monthly peak heating values [kW]
- peak_coolinglist, numpy array
Monthly peak cooling values [kW]
- baseload_heatinglist, numpy array
Monthly baseload heating values [kWh]
- baseload_coolinglist, numpy array
Monthly baseload heating values [kWh]
- borefieldpygfunction borehole/borefield object
Set the borefield for which the calculations will be carried out
- custom_gfunctionCustomGFunction
Custom gfunction dataset
Examples
monthly peak values [kW]
>>> peak_cooling = np.array([0., 0, 34., 69., 133., 187., 213., 240., 160., 37., 0., 0.]) >>> peak_heating = np.array([160., 142, 102., 55., 0., 0., 0., 0., 40.4, 85., 119., 136.])
annual heating and cooling load [kWh]
>>> annual_heating_load = 300 * 10 ** 3 >>> annual_cooling_load = 160 * 10 ** 3
percentage of annual load per month (15.5% for January …)
>>> 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]) >>> monthly_load_cooling_percentage = np.array([0.025, 0.05, 0.05, .05, .075, .1, .2, .2, .1, .075, .05, .025])
resulting load per month [kWh]
>>> monthly_load_heating = annual_heating_load * monthly_load_heating_percentage >>> monthly_load_cooling = annual_cooling_load * monthly_load_cooling_percentage
create the borefield object
>>> borefield = Borefield()
set the load
>>> load = MonthlyGeothermalLoadAbsolute(monthly_load_heating, monthly_load_cooling, peak_heating, peak_cooling) >>> borefield.load = load
- property H: float
This function returns the borehole depth.
- Returns
- float
Borehole depth [meters]
- property Rb: float
This function returns the equivalent borehole thermal resistance.
- Returns
- Rbfloat
Equivalent borehole thermal resistance [mK/W]
- property Re: float
Reynolds number.
- Returns
- float
Reynolds number
- static activate_logger() None
This function activates the logging.
- Returns
- None
- property borefield
Returns the hidden _borefield variable.
- Returns
- Hidden _borefield object
- calculate_next_depth_deep_sizing(current_depth: float) float
This method is a slower but more robust way of calculating the next depth in the sizing iteration when the borefield is sized for the maximum fluid temperature when there is a non-constant ground temperature. The method is based (as can be seen in its corresponding validation document) on the assumption that the difference between the maximum temperature in peak cooling and the average undisturbed ground temperature is irreversily proportional to the depth. In this way, given this difference in temperature and the current depth, a new depth can be calculated.
- Parameters
- current_depthfloat
The current depth of the borefield [m]
- Returns
- float
New depth of the borefield [m]
- calculate_quadrant() int
This function returns the borefield quadrant (as defined by Peere et al., 2021 1) based on the calculated temperature profile. If there is no limiting quadrant, None is returned.
Quadrant 1 is limited in the first year by the maximum temperature
Quadrant 2 is limited in the last year by the maximum temperature
Quadrant 3 is limited in the first year by the minimum temperature
Quadrant 4 is limited in the last year by the maximum temperature
- Returns
- quadrantint
The quadrant which limits the borefield
References
- 1
Peere, W., Picard, D., Cupeiro Figueroa, I., Boydens, W., and Helsen, L. (2021) Validated combined first and last year borefield sizing methodology. In Proceedings of International Building Simulation Conference 2021. Brugge (Belgium), 1-3 September 2021. https://doi.org/10.26868/25222708.2021.30180
- calculate_temperatures(depth: Optional[float] = None, hourly: bool = False) None
Calculate all the temperatures without plotting the figure. When depth is given, it calculates it for a given depth.
- Parameters
- depthfloat
Depth for which the temperature profile should be calculated for [m]
- hourlybool
True when the temperatures should be calculated based on hourly data
- Returns
- None
- calculation_setup(calculation_setup: Optional[CalculationSetup] = None, use_constant_Rb: Optional[bool] = None, **kwargs) None
This function sets the options for the sizing function.
The L2 sizing is the one explained in (Peere et al., 2021) 2 and is the quickest method (it uses 3 pulses)
The L3 sizing is a more general approach which is slower but more accurate (it uses 24 pulses/year)
The L4 sizing is the most exact one, since it uses hourly data (8760 pulses/year)
- Parameters
- calculation_setupCalculationSetup
An instance of the CalculationSetup class. When this argument differs from None, all the other parameters are set based on this calculation_setup
- use_constant_Rbbool
True if a constant borehole equivalent resistance (Rb*) value should be used
- kwargs
Dictionary with all the other options that can be set within GHEtool. For a complete list, see the documentation in the CalculationSetup class.
- Returns
- None
References
- 2(1,2,3,4)
Peere, W., Picard, D., Cupeiro Figueroa, I., Boydens, W., and Helsen, L. (2021) Validated combined first and last year borefield sizing methodology. In Proceedings of International Building Simulation Conference 2021. Brugge (Belgium), 1-3 September 2021. https://doi.org/10.26868/25222708.2021.30180
- 3
Peere, W. (2020) Methode voor economische optimalisatie van geothermische verwarmings- en koelsystemen. Master thesis, Department of Mechanical Engineering, KU Leuven, Belgium.
- create_L_shaped_borefield(N_1: int, N_2: int, B_1: float, B_2: float, H: float, D: float = 1, r_b: float = 0.075)
This function creates a L shaped borefield. It calls the pygfunction module in the background. The documentation of this function is based on pygfunction.
- Parameters
- N_1int
Number of boreholes in the x direction
- N_2int
Number of boreholes in the y direction
- B_1int
Distance between adjacent boreholes in the x direction [m]
- B_2int
Distance between adjacent boreholes in the y direction [m]
- Hfloat
Borehole depth [m]
- Dfloat
Borehole buried depth [m]
- r_bfloat
Borehole radius [m]
- Returns
- pygfunction borefield object
- create_U_shaped_borefield(N_1: int, N_2: int, B_1: float, B_2: float, H: float, D: float = 1, r_b: float = 0.075)
This function creates a U shaped borefield. It calls the pygfunction module in the background. The documentation of this function is based on pygfunction.
- Parameters
- N_1int
Number of boreholes in the x direction
- N_2int
Number of boreholes in the y direction
- B_1int
Distance between adjacent boreholes in the x direction [m]
- B_2int
Distance between adjacent boreholes in the y direction [m]
- Hfloat
Borehole depth [m]
- Dfloat
Borehole buried depth [m]
- r_bfloat
Borehole radius [m]
- Returns
- pygfunction borefield object
- create_box_shaped_borefield(N_1: int, N_2: int, B_1: float, B_2: float, H: float, D: float = 1, r_b: float = 0.075)
This function creates a box shaped borefield. It calls the pygfunction module in the background. The documentation of this function is based on pygfunction.
- Parameters
- N_1int
Number of boreholes in the x direction
- N_2int
Number of boreholes in the y direction
- B_1int
Distance between adjacent boreholes in the x direction [m]
- B_2int
Distance between adjacent boreholes in the y direction [m]
- Hfloat
Borehole depth [m]
- Dfloat
Borehole buried depth [m]
- r_bfloat
Borehole radius [m]
- Returns
- pygfunction borefield object
- create_circular_borefield(N: int, R: float, H: float, D: float = 1, r_b: float = 0.075)
This function creates a circular borefield. It calls the pygfunction module in the background. The documentation of this function is based on pygfunction.
- Parameters
- Nint
Number of boreholes in the borefield
- Rfloat
Distance of boreholes from the center of the field
- Hfloat
Borehole depth [m]
- Dfloat
Borehole buried depth [m]
- r_bfloat
Borehole radius [m]
- Returns
- pygfunction borefield object
- create_custom_dataset(time_array: Optional[Union[_SupportsArray[dtype[Any]], _NestedSequence[_SupportsArray[dtype[Any]]], bool, int, float, complex, str, bytes, _NestedSequence[Union[bool, int, float, complex, str, bytes]]]] = None, depth_array: Optional[Union[_SupportsArray[dtype[Any]], _NestedSequence[_SupportsArray[dtype[Any]]], bool, int, float, complex, str, bytes, _NestedSequence[Union[bool, int, float, complex, str, bytes]]]] = None, options: dict = {}) None
This function makes a datafile for a given custom borefield and sets it for the borefield object. It automatically sets this datafile in the current borefield object, so it can be used as a source for the interpolation of g-values.
- Parameters
- time_arraylist, np.array
Time values (in seconds) used for the calculation of the datafile
- depth_arraylist, np.array
List or arrays of depths for which the datafile should be created
- optionsdict
Options for the g-function calculation (check pygfunction.gfunction.gFunction() for more information)
- Returns
- None
- Raises
- ValueError
When no borefield or ground data is set
- create_rectangular_borefield(N_1: int, N_2: int, B_1: float, B_2: float, H: float, D: float = 1, r_b: float = 0.075)
This function creates a rectangular borefield. It calls the pygfunction module in the background. The documentation of this function is based on pygfunction.
- Parameters
- N_1int
Number of boreholes in the x direction
- N_2int
Number of boreholes in the y direction
- B_1int
Distance between adjacent boreholes in the x direction [m]
- B_2int
Distance between adjacent boreholes in the y direction [m]
- Hfloat
Borehole depth [m]
- Dfloat
Borehole buried depth [m]
- r_bfloat
Borehole radius [m]
- Returns
- pygfunction borefield object
- static deactivate_logger() None
This function deactivates the logging.
- Returns
- None
- gfunction(time_value: Union[_SupportsArray[dtype[Any]], _NestedSequence[_SupportsArray[dtype[Any]]], bool, int, float, complex, str, bytes, _NestedSequence[Union[bool, int, float, complex, str, bytes]]], H: Optional[float] = None) ndarray
This function returns the gfunction value. It can do so by either calculating the gfunctions just-in-time or by interpolating from a loaded custom data file.
- Parameters
- time_valuelist, float, np.ndarray
Time value(s) in seconds at which the gfunctions should be calculated
- Hfloat
Depth [m] at which the gfunctions should be calculated. If no depth is given, the current depth is taken.
- Returns
- gvaluenp.ndarray
1D array with the g-values for all the requested time_value(s)
- property ground_data: _GroundData
This function returns the ground data.
- Returns
- ground dataGroundData
- property investment_cost: float
This function calculates the investment cost based on a cost profile linear to the total borehole length.
- Returns
- float
Investment cost
- property load: GHEtool.VariableClasses.LoadData._LoadData._LoadData | GHEtool.VariableClasses.LoadData.GeothermalLoad.HourlyGeothermalLoad.HourlyGeothermalLoad | GHEtool.VariableClasses.LoadData.GeothermalLoad.MonthlyGeothermalLoadAbsolute.MonthlyGeothermalLoadAbsolute
This returns the LoadData object.
- Returns
- Load data: LoadData
- load_custom_gfunction(location: str) None
This function loads the custom gfunction.
- Parameters
- locationstr
Path to the location of the custom gfunction file
- Returns
- None
- property number_of_boreholes: int
This returns the number of boreholes in the borefield attribute.
- Returns
- int
Number of boreholes
- optimise_load_profile_energy(building_load: HourlyGeothermalLoad, depth: Optional[float] = None, SCOP: float = 1000000, SEER: float = 1000000, temperature_threshold: float = 0.05) None
This function optimises the load based on the given borefield and the given hourly load. (When the load is not geothermal, the SCOP and SEER are used to convert it to a geothermal load.) It does so based on a load-duration curve. The temperatures of the borefield are calculated on a monthly basis, even though we have hourly data, for an hourly calculation of the temperatures would take a very long time.
- Parameters
- building_load_LoadData
Load data used for the optimisation
- depthfloat
Depth of the boreholes in the borefield [m]
- SCOPfloat
SCOP of the geothermal system (needed to convert hourly building load to geothermal load)
- SEERfloat
SEER of the geothermal system (needed to convert hourly building load to geothermal load)
- temperature_thresholdfloat
The maximum allowed temperature difference between the maximum and minimum fluid temperatures and their respective limits. The lower this threshold, the longer the convergence will take.
- Returns
- None
- Raises
- ValueError
ValueError if no hourly load is given or the threshold is negative
- optimise_load_profile_power(building_load: HourlyGeothermalLoad, depth: Optional[float] = None, SCOP: float = 1000000, SEER: float = 1000000, temperature_threshold: float = 0.05, use_hourly_resolution: bool = True) None
This function optimises the load based on the given borefield and the given hourly load. (When the load is not geothermal, the SCOP and SEER are used to convert it to a geothermal load.) It does so based on a load-duration curve. The temperatures of the borefield are calculated on a monthly basis, even though we have hourly data, for an hourly calculation of the temperatures would take a very long time.
- Parameters
- building_load_LoadData
Load data used for the optimisation
- depthfloat
Depth of the boreholes in the borefield [m]
- SCOPfloat
SCOP of the geothermal system (needed to convert hourly building load to geothermal load)
- SEERfloat
SEER of the geothermal system (needed to convert hourly building load to geothermal load)
- temperature_thresholdfloat
The maximum allowed temperature difference between the maximum and minimum fluid temperatures and their respective limits. The lower this threshold, the longer the convergence will take.
- use_hourly_resolutionbool
If use_hourly_resolution is used, the hourly data will be used for this optimisation. This can take some more time than using the monthly resolution, but it will give more accurate results.
- Returns
- None
- Raises
- ValueError
ValueError if no hourly load is given or the threshold is negative
- print_temperature_profile(legend: bool = True, plot_hourly: bool = False) None
This function plots the temperature profile for the calculated depth. It uses the available temperature profile data.
- Parameters
- legendbool
True if the legend should be printed
- plot_hourlybool
True if the temperature profile printed should be based on the hourly load profile.
- Returns
- fig, ax
Figure object
- print_temperature_profile_fixed_depth(depth: float, legend: bool = True, plot_hourly: bool = False)
This function plots the temperature profile for a fixed depth. It uses the already calculated temperature profile data, if available.
- Parameters
- depthfloat
Depth at which the temperature profile should be shown
- legendbool
True if the legend should be printed
- plot_hourlybool
True if the temperature profile printed should be based on the hourly load profile.
- Returns
- fig, ax
Figure object
- set_Rb(Rb: float) None
This function sets the constant equivalent borehole thermal resistance.
- Parameters
- Rbfloat
Equivalent borehole thermal resistance (mK/W)
- Returns
- None
- set_borefield(borefield: Optional[list[pygfunction.boreholes.Borehole]] = None) None
This function set the borefield object. When None is given, the borefield will be deleted.
- Parameters
- borefieldList[pygfunction.boreholes.Borehole]
Borefield created with the pygfunction package
- Returns
- None
- set_fluid_parameters(data: FluidData) None
This function sets the fluid parameters.
- Parameters
- dataFluidData
All the relevant fluid data
- Returns
- None
- set_ground_parameters(data: _GroundData) None
This function sets the relevant ground parameters.
- Parameters
- dataGroundData
All the relevant ground data
- Returns
- None
- set_investment_cost(investment_cost: Optional[list] = None) None
This function sets the investment cost. This is linear with respect to the total field length. If None, the default is set.
- Parameters
- investment_costlist
1D array of polynomial coefficients (including coefficients equal to zero) from highest degree to the constant term
- Returns
- None
- set_load(load: _LoadData) None
This function sets the _load attribute.
- Parameters
- load_LoadData
Load data object
- Returns
- None
- set_max_avg_fluid_temperature(temp: float) None
This functions sets the maximal average fluid temperature to temp.
- Parameters
- tempfloat
Maximal average fluid temperature [deg C]
- Returns
- None
- Raises
- ValueError
When the maximal average fluid temperature is lower than the minimal average fluid temperature
- set_min_avg_fluid_temperature(temp: float) None
This functions sets the minimal average fluid temperature to temp.
- Parameters
- tempfloat
Minimal average fluid temperature [deg C]
- Returns
- None
- Raises
- ValueError
When the maximal average temperature is lower than the minimal average temperature
- set_options_gfunction_calculation(options: dict) None
This function sets the options for the gfunction calculation of pygfunction. This dictionary is directly passed through to the gFunction class of pygfunction. For more information, please visit the documentation of pygfunction.
- Parameters
- optionsdict
Dictionary with options for the gFunction class of pygfunction
- Returns
- None
- set_pipe_parameters(data: _PipeData) None
This function sets the pipe parameters.
- Parameters
- dataPipeData
All the relevant pipe parameters
- Returns
- None
- property simulation_period: int
This returns the simulation period from the LoadData object.
- Returns
- Simulation period [years]int
- size(H_init: Optional[float] = None, use_constant_Rb: Optional[bool] = None, L2_sizing: Optional[bool] = None, L3_sizing: Optional[bool] = None, L4_sizing: Optional[bool] = None, quadrant_sizing: Optional[int] = None, **kwargs) float
This function sets the options for the sizing function.
The L2 sizing is the one explained in (Peere et al., 2021) 2 and is the quickest method (it uses 3 pulses)
The L3 sizing is a more general approach which is slower but more accurate (it uses 24 pulses/year)
The L4 sizing is the most exact one, since it uses hourly data (8760 pulses/year)
Please note that the changes sizing setup changes here are not saved! Use self.setupSizing for this.
- Parameters
- H_initfloat
Initial depth for the iteration. If None, the default H_init is chosen.
- use_constant_Rbbool
True if a constant borehole equivalent resistance (Rb*) value should be used
- L2_sizingbool
True if a sizing with the L2 method is needed
- L3_sizingbool
True if a sizing with the L3 method is needed
- L4_sizingbool
True if a sizing with the L4 method is needed
- quadrant_sizingint
Differs from 0 when a sizing in a certain quadrant is desired. Quadrants are developed by (Peere et al., 2021) 2, 3
- kwargsdict
Dictionary with all the other options that can be set within GHEtool. For a complete list, see the documentation in the CalculationSetup class.
- Returns
- borehole depthfloat
- Raises
- ValueError
ValueError when no ground data is provided
- size_L2(H_init: Optional[float] = None, quadrant_sizing: int = 0) float
This function sizes the of the given configuration according to the methodology explained in (Peere et al., 2021) 2, which is a L2 method. When quadrant sizing is other than 0, it sizes the field based on the asked quadrant. It returns the borefield depth.
- Parameters
- H_initfloat
Initial depth from where to start the iteration [m]
- quadrant_sizingint
If a quadrant is given the sizing is performed for this quadrant else for the relevant
- Returns
- Hfloat
Required depth of the borefield [m]
- Raises
- ValueError
ValueError when no ground data is provided or quadrant is not in range.
- size_L3(H_init: Optional[float] = None, quadrant_sizing: int = 0) float
This function sizes the borefield based on a monthly (L3) method.
- Parameters
- H_initfloat
Initial depth from where to start the iteration [m]
- quadrant_sizingint
If a quadrant is given the sizing is performed for this quadrant else for the relevant
- Returns
- Hfloat
Required depth of the borefield [m]
- Raises
- ValueError
ValueError when no ground data is provided or quadrant is not in range.
- UnsolvableDueToTemperatureGradient
Error when the field cannot be sized.
- size_L4(H_init: Optional[float] = None, quadrant_sizing: int = 0) float
This function sizes the borefield based on an hourly (L4) sizing methodology.
- Parameters
- H_initfloat
Initial depth from where to start the iteration [m]
- quadrant_sizingint
If a quadrant is given the sizing is performed for this quadrant else for the relevant
- Returns
- Hfloat
Required depth of the borefield [m]
- Raises
- ValueError
ValueError when no ground data is provided or quadrant is not in range.
- UnsolvableDueToTemperatureGradient
When the field cannot be sized due to the temperature gradient.