Skip to content

Commit

Permalink
Modify spreadsheet test cases structure
Browse files Browse the repository at this point in the history
  • Loading branch information
LoneMeertens committed Dec 10, 2024
1 parent 5fa82db commit 43f9284
Show file tree
Hide file tree
Showing 9 changed files with 738 additions and 857 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,193 +2,111 @@
The work of (Ahmadfard and Bernier, 2019) provides a set of test cases that can be used to compare
software tools with the ultimate goal of improving the reliability of design methods for sizing
vertical ground heat exchangers. This document delivers the results on the test file using the GHEtool
L2-, L3-, and L4-sizing methods.
L2-, L3- and L4-sizing methods.
Test 1 - Synthetic balanced load – one borehole
Test 1 -Synthetic balanced load – one borehole
References:
-----------
- Ahmadfard, M., and M. Bernier. 2019. A review of vertical ground heat exchanger sizing tools including an inter-model
comparison [in eng]. Renewable sustainable energy reviews (OXFORD) 110:247–265.
"""

import os
import time
import numpy as np
import pygfunction as gt
import sys
from GHEtool import *

def test_1b_6h_ste():
# Ground properties
ground_data = GroundFluxTemperature(k_s=1.8, T_g=17.5, volumetric_heat_capacity=2073600, flux=0)

def initialize_borefield(load, delta_t, ground_data, fluid_data, pipe_data, imposed_Rb=None):
"""
Initialize and set up borefield with necessary parameters.
"""
# Initiate borefield
borefield = Borefield()

# Set ground data in borefield
borefield.set_ground_parameters(ground_data)
borefield.set_fluid_parameters(fluid_data)
borefield.set_pipe_parameters(pipe_data)
borefield.create_rectangular_borefield(1, 1, 6, 6, 110, 4, 0.075)

# Set imposed Rb if provided
if imposed_Rb is not None:
borefield.set_Rb(imposed_Rb)
borefield.calculation_setup(use_constant_Rb=True)

# Load the load profile into borefield
borefield.load = load

# Set temperature bounds
borefield.set_max_avg_fluid_temperature(35 + delta_t / 2)
borefield.set_min_avg_fluid_temperature(0 - delta_t / 2)

return borefield


def run_sizing_case(borefield, load, ground_data, fluid_data, pipe_data, peak_duration, delta_t, use_constant_Rb=None):
"""
Run sizing for L2, L3, L4, L3_ste, and L4_ste methods with imposed Rb and return results.
If imposed_Rb is None, it uses the default calculated Rb.
"""
# Set peak duration
borefield.load.peak_duration = peak_duration

# Define methods and short-term effects parameters
methods = ['L2', 'L3', 'L4', 'L3_ste', 'L4_ste']
short_term_params = {'rho_cp_grout': 3800000.0, 'rho_cp_pipe': 1540000.0}
options = {
'disp': False,
'profiles': True,
'method': 'equivalent',
'cylindrical_correction': True,
'short_term_effects': True,
'ground_data': ground_data,
'fluid_data': fluid_data,
'pipe_data': pipe_data,
'borefield': borefield,
'short_term_effects_parameters': short_term_params,
}

# Set results dictionary
results = {}
# Load fluid properties into FluidData
base_mfr = 0.440 # Baseline mass flow rate (kg/s)
fluid_data = FluidData(mfr=base_mfr, rho=1052, Cp=3795, mu=0.0052, k_f=0.48)

# Pipe properties
pipe_data = MultipleUTube(r_in=0.0137, r_out=0.0167, D_s=0.075 / 2, k_g=1.4, k_p=0.43, number_of_pipes=1)

for method in methods:
start_time = time.time()

# Re-initialize borefield if switching from L4 to L3_ste or L4_ste
if method in ['L3_ste', 'L4_ste']:
print(f"\nRe-initializing borefield for {method} method.")
borefield = initialize_borefield(load, delta_t, ground_data, fluid_data, pipe_data, imposed_Rb=borefield.Rb)
borefield.set_options_gfunction_calculation(options)
# Perform sizing with short-term effects
depth = borefield.size(100, L3_sizing=(method == 'L3_ste'), L4_sizing=(method == 'L4_ste'))
else:
# Perform sizing for regular methods (L2, L3, L4)
borefield = initialize_borefield(load, delta_t, ground_data, fluid_data, pipe_data, imposed_Rb=borefield.Rb)
depth = borefield.size(100, L2_sizing=(method == 'L2'), L3_sizing=(method == 'L3'), L4_sizing=(method == 'L4'))
# Short-term effect parameters
rho_cp_grout = 3800000.0
rho_cp_pipe = 1540000.0

# Initialize results dictionary
results = {}

# Define function to store results
def log_results(method, depth, borefield, start_time):
results[method] = {
'depth': depth,
'Rb': borefield.Rb,
'time': time.time() - start_time
}

#if method == 'L4':
#borefield._plot_temperature_profile(plot_hourly=True)

return results


def test1a_ste(use_pygfunction_media=False, Tf=0):
"""
Test the L2, L3, L4, L3_ste, and L4_ste sizing methods of the GHEtool library on a synthetic balanced load profile.
"""
"""
# Set up ground, fluid, and pipe data
ground_data = GroundFluxTemperature(k_s=1.8, T_g=17.5, volumetric_heat_capacity=2073600, flux=0)
fluid_data = FluidData(mfr=0.440, rho=1052, Cp=3795, mu=0.0052, k_f=0.48)
pipe_data = MultipleUTube(r_in=0.0137, r_out=0.0167, D_s=0.075 / 2, k_g=1.4, k_p=0.43, number_of_pipes=1)
"""
# Initialize ground, fluid, and pipe data
ground_data = GroundFluxTemperature(k_s=1.8, T_g=17.5, volumetric_heat_capacity=2073600, flux=0)

# Base mass flow rate (kg/s)
base_mfr = 0.440
# Initialize fluid data
if use_pygfunction_media:
# Use pygfunction to determine fluid data
# Create a water fluid object using pygfunction
fluid_str = 'Water' # Default fluid in pygfunction
percent = 0 # No mixture, pure water
fluid_object = gt.media.Fluid(fluid_str, percent, T=Tf)
fluid_data = FluidData()
fluid_data.import_fluid_from_pygfunction(fluid_object)
else:
# Use manual fluid data input
fluid_data = FluidData(mfr=base_mfr, rho=1052, Cp=3795, mu=0.0052, k_f=0.48)

# Create pipe data for a Multiple U-Tube configuration
pipe_data = MultipleUTube(r_in=0.0137, r_out=0.0167, D_s=0.075 / 2, k_g=1.4, k_p=0.43, number_of_pipes=1)


# Load hourly profile
load = HourlyGeothermalLoad(simulation_period=10)
csv_file_path = os.path.join(os.path.dirname(__file__), 'test1a.csv')
load.load_hourly_profile(csv_file_path, header=True, separator=",", col_extraction=1, col_injection=0)
load.load_hourly_profile(os.path.join(os.path.dirname(__file__), 'test1a.csv'), header=True, separator=",",
col_extraction=1, col_injection=0)

# Calculate delta temperature
delta_t = max(load.max_peak_extraction, load.max_peak_injection) * 1000 / (fluid_data.Cp * fluid_data.mfr)
# Calculate temperature bounds
delta_t = max(load.max_peak_extraction, load.max_peak_injection) * 1000 / (fluid_data.Cp * fluid_data.mfr)

# Test cases: for peak durations 6 hours and 1 hour
for peak_duration in [6, 1]:
print(f"\nRunning test case for peak_duration = {peak_duration}")

# Initialize borefield with required parameters
borefield = initialize_borefield(load, delta_t, ground_data, fluid_data, pipe_data)

# Run sizing for calculated Rb (default behavior)
results_default_Rb = run_sizing_case(borefield, load, ground_data, fluid_data, pipe_data, peak_duration, delta_t)

# Print results for default Rb
print("\n--- Results for calculated Rb ---")
for method, result in results_default_Rb.items():
print(f"Method: {method}")
print(f" Depth: {result['depth']:.2f} m")
print(f" Rb: {result['Rb']:.3f}")
print(f" Time: {result['time']:.2f} s")
print("\n----------------------------------")

# Run sizing for imposed Rb (static value)
Rb_static = 0.13 # Imposed Rb value
use_constant_Rb = True
# Initialize borefield with required parameters
borefield = initialize_borefield(load, delta_t, ground_data, fluid_data, pipe_data, Rb_static)
results_imposed_Rb = run_sizing_case(borefield, load, ground_data, fluid_data, pipe_data, peak_duration, delta_t, use_constant_Rb)

# Print results for imposed Rb
print("\n--- Results for imposed Rb (Rb* = 0.13) ---")
for method, result in results_imposed_Rb.items():
print(f"Method: {method}")
print(f" Depth: {result['depth']:.2f} m")
print(f" Rb: {result['Rb']:.3f}")
print(f" Time: {result['time']:.2f} s")
print("\n-------------------------------<-------------")

"""
# Add assertions for validation (replace with expected values for your case)
if peak_duration == 6:
assert np.isclose(results_default_Rb['L2']['depth'], 59.366, atol=0.1)
assert np.isclose(results_default_Rb['L3']['depth'], 59.543, atol=0.1)
assert np.isclose(results_default_Rb['L4']['depth'], 56.266, atol=0.1)
assert np.isclose(results_default_Rb['L4_ste']['depth'], 52.347, atol=0.1)
assert np.isclose(results_default_Rb['L3_ste']['depth'], 58.123, atol=0.1) # Example value
else:
# Adjust expected values based on 1-hour peak duration results
pass
"""
# Test each sizing method
for method, dynamic_rb, short_term_effects in [
('L2', True, False), ('L3', True, False), ('L4', True, False), ('L3_ste', True, True),
('L4_ste', True, True), ('L2_static', False, False), ('L3_static', False, False),
('L4_static', False, False), ('L3_static_ste', False, True), ('L4_static_ste', False, True)
]:
# Initialize borefield
borefield = Borefield()
borefield.set_ground_parameters(ground_data)
borefield.set_fluid_parameters(fluid_data)
borefield.set_pipe_parameters(pipe_data)
borefield.create_rectangular_borefield(1, 1, 6, 6, 110, 4, 0.075)
# Set peak duration
borefield.load.peak_duration = peak_duration

# Set temperature bounds
borefield.set_max_avg_fluid_temperature(35 + delta_t / 2)
borefield.set_min_avg_fluid_temperature(0 - delta_t / 2)

borefield.load = load

# Handle short-term effects
if short_term_effects:
short_term_effects_parameters = {
'rho_cp_grout': rho_cp_grout,
'rho_cp_pipe': rho_cp_pipe,
}

options = {
'disp': False,
'profiles': True,
'method': 'equivalent',
'cylindrical_correction': True,
'short_term_effects': True,
'ground_data': ground_data,
'fluid_data': fluid_data,
'pipe_data': pipe_data,
'borefield': borefield,
'short_term_effects_parameters': short_term_effects_parameters,
}
borefield.set_options_gfunction_calculation(options)

# Use constant Rb if required
if not dynamic_rb:
borefield.set_Rb(0.13)

# Perform sizing
start_time = time.time()
depth = borefield.size(100, L2_sizing=(method.startswith('L2')), L3_sizing=(method.startswith('L3')), L4_sizing=(method.startswith('L4')))
log_results(method, depth, borefield, start_time)

# Print results
for method, result in results.items():
print(f"Method {method}: Depth = {result['depth']:.2f}m, Rb* = {result['Rb']:.3f}, Time = {result['time']:.2f}s")

if __name__ == "__main__":
test1a_ste()
test_1b_6h_ste()
Loading

0 comments on commit 43f9284

Please sign in to comment.