diff --git a/CHANGELOG.md b/CHANGELOG.md index 001886f..8f8e657 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,7 +14,13 @@ non-exhaustive list of the possible categories issues could fall in: - Fixes - for any bug fixes - Documentation - for changes to the package that are purely for purposes of documentation -## Version 0.2 +## Current version + +### New features + +* [Issue 77](https://github.com/j-c-cook/ghedt/issues/77) - The geometrical constraints and design objects are enhanced to support design of bi-rectangular fields containing no-drilling zones. + +## Version 0.2/0.3 ### Enhances diff --git a/ghedt/README.md b/ghedt/README.md index 3be9db1..482f259 100644 --- a/ghedt/README.md +++ b/ghedt/README.md @@ -12,7 +12,7 @@ and a folder that contains examples. ├── coordinates.py ├── design.py ├── domains.py -├── feature_recognition.py +├── geometry.py ├── gfunction.py ├── ground_heat_exchangers.py ├── media.py diff --git a/ghedt/__init__.py b/ghedt/__init__.py index 93092ef..a54d81c 100644 --- a/ghedt/__init__.py +++ b/ghedt/__init__.py @@ -5,6 +5,5 @@ from . import utilities from . import domains from . import search_routines -from . import feature_recognition -from . import media +from . import geometry from . import design diff --git a/ghedt/coordinates.py b/ghedt/coordinates.py index 06c0b81..0aef1e0 100644 --- a/ghedt/coordinates.py +++ b/ghedt/coordinates.py @@ -1,6 +1,15 @@ # Jack C. Cook # Tuesday, October 26, 2021 +def scale_coordinates(coordinates, scale): + new_coordinates = [] + for i in range(len(coordinates)): + x, y = coordinates[i] + x *= scale + y *= scale + new_coordinates.append((x, y)) + return new_coordinates + def transpose_coordinates(coordinates): coordinates_transposed = [] diff --git a/ghedt/design.py b/ghedt/design.py index 91db8d6..64ea708 100644 --- a/ghedt/design.py +++ b/ghedt/design.py @@ -15,7 +15,7 @@ def __init__(self, V_flow: float, borehole: gt.boreholes.Borehole, fluid: gt.media.Fluid, pipe: plat.media.Pipe, grout: plat.media.Grout, soil: plat.media.Soil, sim_params: plat.media.SimulationParameters, - geometric_constraints: dt.media.GeometricConstraints, + geometric_constraints: dt.geometry.Constraints, hourly_extraction_ground_loads: list, method: str = 'hybrid', routine: str = 'near-square', flow: str = 'borehole'): self.V_flow = V_flow # volumetric flow rate, m3/s @@ -47,7 +47,7 @@ def __init__(self, V_flow: float, borehole: gt.boreholes.Borehole, # Check the routine parameter self.routine = routine available_routines = ['near-square', 'rectangle', 'bi-rectangle', - 'bi-zoned'] + 'bi-zoned', 'bi-rectangle-cutout'] self.geometric_constraints.check_inputs(self.routine) gc = self.geometric_constraints if routine in available_routines: @@ -76,10 +76,35 @@ def __init__(self, V_flow: float, borehole: gt.boreholes.Borehole, self.coordinates_domain_nested = \ dt.domains.bi_rectangle_zoned_nested( gc.length, gc.width, gc.B_min, gc.B_max_x, gc.B_max_y) + elif routine == 'bi-rectangle-cutout': + _length = self.geometric_constraints.length + _width = self.geometric_constraints.width + _B_min = self.geometric_constraints.B_min + _B_max_x = self.geometric_constraints.B_max_x + _B_max_y = self.geometric_constraints.B_max_y + coordinates_domain_nested = dt.domains.bi_rectangle_nested( + _length, _width, _B_min, _B_max_x, _B_max_y + ) + + coordinates_domain_nested_cutout = [] + for i in range(len(coordinates_domain_nested)): + new_coordinates_domain = [] + for j in range(len(coordinates_domain_nested[i])): + coordinates = coordinates_domain_nested[i][j] + new_coordinates = dt.geometry.remove_cutout( + coordinates, + boundary=self.geometric_constraints.no_go + ) + new_coordinates_domain.append(new_coordinates) + coordinates_domain_nested_cutout.append( + new_coordinates_domain) + + self.coordinates_domain_nested = \ + coordinates_domain_nested_cutout else: - raise ValueError('The requested routine is not available. ' - 'The currently available routines are: ' - '`near-square`.') + raise ValueError(f'The requested routine is not available. ' + f'The currently available routines are: ' + f'{self.available_routines}.') self.flow = flow def find_design(self, disp=False): @@ -115,6 +140,12 @@ def find_design(self, disp=False): self.bhe_object, self.fluid, self.pipe, self.grout, self.soil, self.sim_params, self.hourly_extraction_ground_loads, method=self.method, flow=self.flow, disp=disp) + elif self.routine == 'bi-rectangle-cutout': + bisection_search = dt.search_routines.Bisection2D( + self.coordinates_domain_nested, self.V_flow, self.borehole, + self.bhe_object, self.fluid, self.pipe, self.grout, self.soil, + self.sim_params, self.hourly_extraction_ground_loads, + method=self.method, flow=self.flow, disp=disp) else: raise ValueError('The requested routine is not available. ' 'The currently available routines are: ' diff --git a/ghedt/domains.py b/ghedt/domains.py index 6ec163b..ee3fa8b 100644 --- a/ghedt/domains.py +++ b/ghedt/domains.py @@ -354,7 +354,7 @@ def polygonal_land_constraint(property_boundary, B_min, B_max_x, B_max_y, building_description = [] outer_rectangle = \ - dt.feature_recognition.determine_largest_rectangle(property_boundary) + dt.geometry.determine_largest_rectangle(property_boundary) x, y = list(zip(*outer_rectangle)) length = max(x) @@ -370,12 +370,12 @@ def polygonal_land_constraint(property_boundary, B_min, B_max_x, B_max_y, for j in range(len(coordinates_domain_nested[i])): coordinates = coordinates_domain_nested[i][j] # Remove boreholes outside of property - new_coordinates = dt.feature_recognition.remove_cutout( + new_coordinates = dt.geometry.remove_cutout( coordinates, boundary=property_boundary, remove_inside=False) # Remove boreholes inside of building if len(new_coordinates) == 0: continue - new_coordinates = dt.feature_recognition.remove_cutout( + new_coordinates = dt.geometry.remove_cutout( new_coordinates, boundary=building_description, remove_inside=True, keep_contour=False) new_coordinates_domain.append(new_coordinates) diff --git a/ghedt/examples/Design/find_bi_rectangle.py b/ghedt/examples/Design/find_bi_rectangle.py index d1d92ec..108d0b1 100644 --- a/ghedt/examples/Design/find_bi_rectangle.py +++ b/ghedt/examples/Design/find_bi_rectangle.py @@ -137,7 +137,7 @@ def main(): - B_min - B_max """ - geometric_constraints = dt.media.GeometricConstraints( + geometric_constraints = dt.geometry.Constraints( length=length, width=width, B_min=B_min, B_max_x=B_max_x, B_max_y=B_max_y) diff --git a/ghedt/examples/Design/find_bi_rectangular_cutout.py b/ghedt/examples/Design/find_bi_rectangular_cutout.py new file mode 100644 index 0000000..d1b137a --- /dev/null +++ b/ghedt/examples/Design/find_bi_rectangular_cutout.py @@ -0,0 +1,213 @@ +import ghedt as dt +import ghedt.peak_load_analysis_tool as plat +import pygfunction as gt +import pandas as pd +from time import time as clock + + +def main(): + # Borehole dimensions + # ------------------- + H = 96. # Borehole length (m) + D = 2. # Borehole buried depth (m) + r_b = 0.075 # Borehole radius (m) + + # Pipe dimensions + # --------------- + r_out = 26.67 / 1000. / 2. # Pipe outer radius (m) + r_in = 21.6 / 1000. / 2. # Pipe inner radius (m) + s = 32.3 / 1000. # Inner-tube to inner-tube Shank spacing (m) + epsilon = 1.0e-6 # Pipe roughness (m) + + # Pipe positions + # -------------- + # Single U-tube [(x_in, y_in), (x_out, y_out)] + pos = plat.media.Pipe.place_pipes(s, r_out, 1) + # Single U-tube BHE object + bhe_object = plat.borehole_heat_exchangers.SingleUTube + + # Thermal conductivities + # ---------------------- + k_p = 0.4 # Pipe thermal conductivity (W/m.K) + k_s = 2.0 # Ground thermal conductivity (W/m.K) + k_g = 1.0 # Grout thermal conductivity (W/m.K) + + # Volumetric heat capacities + # -------------------------- + rhoCp_p = 1542. * 1000. # Pipe volumetric heat capacity (J/K.m3) + rhoCp_s = 2343.493 * 1000. # Soil volumetric heat capacity (J/K.m3) + rhoCp_g = 3901. * 1000. # Grout volumetric heat capacity (J/K.m3) + + # Thermal properties + # ------------------ + # Pipe + pipe = plat.media.Pipe(pos, r_in, r_out, s, epsilon, k_p, rhoCp_p) + # Soil + ugt = 18.3 # Undisturbed ground temperature (degrees Celsius) + soil = plat.media.Soil(k_s, rhoCp_s, ugt) + # Grout + grout = plat.media.Grout(k_g, rhoCp_g) + + # Inputs related to fluid + # ----------------------- + # Fluid properties + mixer = 'MEG' # Ethylene glycol mixed with water + percent = 0. # Percentage of ethylene glycol added in + fluid = gt.media.Fluid(mixer=mixer, percent=percent) + + # Fluid properties + V_flow_borehole = 0.2 # System volumetric flow rate (L/s) + + # Define a borehole + borehole = gt.boreholes.Borehole(H, D, r_b, x=0., y=0.) + + # Simulation start month and end month + # -------------------------------- + # Simulation start month and end month + start_month = 1 + n_years = 20 + end_month = n_years * 12 + # Maximum and minimum allowable fluid temperatures + max_EFT_allowable = 35 # degrees Celsius + min_EFT_allowable = 5 # degrees Celsius + # Maximum and minimum allowable heights + max_Height = 135. # in meters + min_Height = 60 # in meters + sim_params = plat.media.SimulationParameters( + start_month, end_month, max_EFT_allowable, min_EFT_allowable, + max_Height, min_Height) + + # Process loads from file + # ----------------------- + # read in the csv file and convert the loads to a list of length 8760 + hourly_extraction: dict = \ + pd.read_csv('../Atlanta_Office_Building_Loads.csv').to_dict('list') + # Take only the first column in the dictionary + hourly_extraction_ground_loads: list = \ + hourly_extraction[list(hourly_extraction.keys())[0]] + + # -------------------------------------------------------------------------- + + # Design constraints are the land and range of B-spacing + length = 85. # m + width = 80 # m + B_min = 4.45 # m + B_max_x = 10. # m + B_max_y = 12. + + perimeter = [[0., 0.], [length, 0.], [width, length], [0., width]] + l_x_building = 50 + l_y_building = 33.3 + origin_x, origin_y = (15, 36.5) + + no_go = [[origin_x, origin_y], + [origin_x + l_x_building, origin_y], + [origin_x + l_x_building, origin_y + l_y_building], + [origin_x, origin_y + l_y_building]] + + geometric_constraints = dt.geometry.Constraints( + length=length, + width=width, + B_min=B_min, + B_max_x=B_max_x, + B_max_y=B_max_y, + outer_constraints=perimeter, + no_go=no_go + ) + routine = 'bi-rectangle-cutout' + geometric_constraints.check_inputs(routine) + + design = dt.design.Design( + V_flow_borehole, + borehole, + bhe_object, + fluid, + pipe, + grout, + soil, + sim_params, + geometric_constraints, + hourly_extraction_ground_loads, + routine=routine, + flow='borehole' + ) + + coordinates_domain = design.coordinates_domain_nested[0] + + output_folder = 'Bi-Rectangle_Domain' + dt.domains.visualize_domain(coordinates_domain, output_folder) + + tic = clock() + bisection_search = design.find_design(disp=True) + toc = clock() + print('Time to perform bisection search: {} seconds'.format(toc - tic)) + + nbh = len(bisection_search.selected_coordinates) + print('Number of boreholes: {}'.format(nbh)) + + print('Borehole spacing: {}'.format(bisection_search.ghe.GFunction.B)) + + # Perform sizing in between the min and max bounds + tic = clock() + ghe = bisection_search.ghe + ghe.compute_g_functions() + + ghe.size(method='hybrid') + toc = clock() + print('Time to compute g-functions and size: {} seconds'.format(toc - tic)) + + print('Sized height of boreholes: {0:.2f} m'.format(ghe.bhe.b.H)) + + print('Total drilling depth: {0:.1f} m'.format(ghe.bhe.b.H * nbh)) + + # Plot go and no-go zone with corrected borefield + # ----------------------------------------------- + coordinates = bisection_search.selected_coordinates + + perimeter = [[0., 0.], [85., 0.], [85., 80.], [0., 80.]] + l_x_building = 50 + l_y_building = 33.3 + origin_x, origin_y = (15, 36.5) + no_go = [[origin_x, origin_y], [origin_x+l_x_building, origin_y], + [origin_x+l_x_building, origin_y+l_y_building], + [origin_x, origin_y+l_y_building]] + + fig, ax = dt.gfunction.GFunction.visualize_area_and_constraints( + perimeter, coordinates, no_go=no_go) + + fig.savefig('bi-rectangle_case-cutout.png', + bbox_inches='tight', pad_inches=0.1) + + # Export plots for animation + folder = 'Calculated_Temperature_Fields/' + dt.utilities.create_if_not(folder) + + outer_domain = [design.coordinates_domain_nested[0][0]] + for i in range(len(design.coordinates_domain_nested)): + outer_domain.append(design.coordinates_domain_nested[i][-1]) + + calculated_temperatures_nested = \ + bisection_search.calculated_temperatures_nested[0] + + count = 0 + for key in calculated_temperatures_nested: + _coordinates = outer_domain[key] + fig, ax = dt.gfunction.GFunction.visualize_area_and_constraints( + perimeter, _coordinates, no_go=no_go) + name = str(count).zfill(2) + fig.savefig(folder + name + '.png', bbox_inches='tight', pad_inches=0.1) + count += 1 + + calculated_temperatures = bisection_search.calculated_temperatures + inner_domain = bisection_search.coordinates_domain + for key in calculated_temperatures: + _coordinates = inner_domain[key] + fig, ax = dt.gfunction.GFunction.visualize_area_and_constraints( + perimeter, _coordinates, no_go=no_go) + name = str(count).zfill(2) + fig.savefig(folder + name + '.png', bbox_inches='tight', pad_inches=0.1) + count += 1 + + +if __name__ == '__main__': + main() diff --git a/ghedt/examples/Design/find_bi_zoned_rectangle.py b/ghedt/examples/Design/find_bi_zoned_rectangle.py index a9656b5..cd023a7 100644 --- a/ghedt/examples/Design/find_bi_zoned_rectangle.py +++ b/ghedt/examples/Design/find_bi_zoned_rectangle.py @@ -136,7 +136,7 @@ def main(): - B_min - B_max """ - geometric_constraints = dt.media.GeometricConstraints( + geometric_constraints = dt.geometry.Constraints( length=length, width=width, B_min=B_min, B_max_x=B_max_x, B_max_y=B_max_y) diff --git a/ghedt/examples/Design/find_near_square.py b/ghedt/examples/Design/find_near_square.py index c8c41d6..5908271 100644 --- a/ghedt/examples/Design/find_near_square.py +++ b/ghedt/examples/Design/find_near_square.py @@ -130,7 +130,7 @@ def main(): # B is already defined above number_of_boreholes = 32 length = dt.utilities.length_of_side(number_of_boreholes, B) - geometric_constraints = dt.media.GeometricConstraints(B=B, length=length) + geometric_constraints = dt.geometry.Constraints(B=B, length=length) # Single U-tube # ------------- diff --git a/ghedt/examples/Design/find_rectangle.py b/ghedt/examples/Design/find_rectangle.py index e591e28..0a7573c 100644 --- a/ghedt/examples/Design/find_rectangle.py +++ b/ghedt/examples/Design/find_rectangle.py @@ -137,7 +137,7 @@ def main(): - B_min - B_max """ - geometric_constraints = dt.media.GeometricConstraints( + geometric_constraints = dt.geometry.Constraints( length=length, width=width, B_min=B_min, B_max_x=B_max) title = 'Find rectangle...' diff --git a/ghedt/feature_recognition.py b/ghedt/geometry.py similarity index 54% rename from ghedt/feature_recognition.py rename to ghedt/geometry.py index 97f3dc7..71e9ffe 100644 --- a/ghedt/feature_recognition.py +++ b/ghedt/geometry.py @@ -1,19 +1,58 @@ # Jack C. Cook -# Wednesday, January 15, 2020 -import copy +# Friday, December 10, 2021 +import copy import numpy as np import cv2 - - -def scale_coordinates(coordinates, scale): - new_coordinates = [] - for i in range(len(coordinates)): - x, y = coordinates[i] - x *= scale - y *= scale - new_coordinates.append((x, y)) - return new_coordinates +import ghedt as dt + + +class Constraints: + def __init__(self, length: float = None, width: float = None, + B: float = None, B_min: float = None, + B_max_x: float = None, B_max_y: float = None, + outer_constraints: list = None, no_go: list = None): + # Spacing parameters in meters + self.B = B + self.B_max_x = B_max_x + self.B_max_y = B_max_y + self.B_min = B_min + # Length and width constraints + self.length = length + self.width = width + # Outer constraints described as a polygon + self.outer_constraints = outer_constraints + # TODO: Handling for a list or a list of lists to occur later + # Note: the entirety of the no-go zone should fall inside the + # outer_constraints + self.no_go = no_go + + def check_inputs(self, method): + # The required instances for the near-square design is self.B + if method == 'near-square': + assert self.B is not None + assert self.length is not None + elif method == 'rectangle': + assert self.width is not None + assert self.length is not None + assert self.B_min is not None + assert self.B_max_x is not None + elif method == 'bi-rectangle' or 'bi-zoned': + assert self.width is not None + assert self.length is not None + assert self.B_min is not None + assert self.B_max_x is not None + assert self.B_max_y is not None + elif method == 'bi-rectangle-cutout': + assert self.length is not None + assert self.width is not None + assert self.B_min is not None + assert self.B_max_x is not None + assert self.B_max_y is not None + assert self.outer_constraints is not None + assert self.no_go is not None + + return def remove_cutout(coordinates, boundary=None, remove_inside=True, @@ -24,8 +63,8 @@ def remove_cutout(coordinates, boundary=None, remove_inside=True, # cv2.pointPolygonTest only takes integers, so we scale by 10000 and then # scale back to keep precision scale = 10000. - coordinates = scale_coordinates(coordinates, scale) - boundary = scale_coordinates(boundary, scale) + coordinates = dt.coordinates.scale_coordinates(coordinates, scale) + boundary = dt.coordinates.scale_coordinates(boundary, scale) _boundary = np.array(boundary, dtype=np.uint64) @@ -74,7 +113,7 @@ def remove_cutout(coordinates, boundary=None, remove_inside=True, else: new_coordinates.append(coordinates[i]) - new_coordinates = scale_coordinates(new_coordinates, 1/scale) + new_coordinates = dt.coordinates.scale_coordinates(new_coordinates, 1/scale) return new_coordinates diff --git a/ghedt/media.py b/ghedt/media.py deleted file mode 100644 index 1824c07..0000000 --- a/ghedt/media.py +++ /dev/null @@ -1,42 +0,0 @@ -# Jack C. Cook -# Friday, December 10, 2021 - - -class GeometricConstraints: - def __init__(self, length: float = None, width: float = None, - B: float = None, B_min: float = None, - B_max_x: float = None, B_max_y: float = None, - outer_constraints: list = None, no_go: list = None): - # Spacing parameters in meters - self.B = B - self.B_max_x = B_max_x - self.B_max_y = B_max_y - self.B_min = B_min - # Length and width constraints - self.length = length - self.width = width - # Outer constraints described as a polygon - self.outer_constraints = outer_constraints - # TODO: Handling for a list or a list of lists to occur later - # Note: the entirety of the no-go zone should fall inside the - # outer_constraints - self.no_go = no_go - - def check_inputs(self, method): - # The required instances for the near-square design is self.B - if method == 'near-square': - assert self.B is not None - assert self.length is not None - elif method == 'rectangle': - assert self.width is not None - assert self.length is not None - assert self.B_min is not None - assert self.B_max_x is not None - elif method == 'bi-rectangle' or 'bi-zoned': - assert self.width is not None - assert self.length is not None - assert self.B_min is not None - assert self.B_max_x is not None - assert self.B_max_y is not None - - return diff --git a/requirements.txt b/requirements.txt index 744b8eb..ac4afcc 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,8 +1,7 @@ -pygfunction>=2.1 -numpy>=1.19.2 -scipy>=1.6.2 -matplotlib>=3.3.4 -coolprop>=6.4.1 +pygfunction>=2.2.1 +numpy>=1.21.5 +scipy>=1.7.3 +matplotlib>=3.5.1 pandas>=1.3.2 openpyxl>=3.0.8 opencv-python==4.5.4.58 \ No newline at end of file diff --git a/setup.py b/setup.py index bc7dcd0..1837623 100644 --- a/setup.py +++ b/setup.py @@ -9,25 +9,23 @@ long_description = f.read() setup(name='ghedt', - install_requires=['pygfunction>=2.1', - 'matplotlib>=3.3.4', - 'numpy>=1.19.2', - 'Pillow>=8.1.0', - 'scipy>=1.6.2', - 'pandas>=1.3.2', - 'natsort>=7.1.1', - 'openpyxl>=3.0.8', - 'coolprop>=6.4.1', - 'opencv-python==4.5.4.58'], + install_requires=['pygfunction>=2.2.1', + 'numpy>=1.21.5', + 'scipy>=1.7.3', + 'matplotlib>=3.5.1', + 'opencv-python==4.5.4.58' + 'pandas >= 1.3.2', + 'openpyxl >= 3.0.8' + ], url='https://github.com/j-c-cook/ghedt', - download_url='https://github.com/j-c-cook/ghedt/archive/v0.2.tar.gz', + download_url='https://github.com/j-c-cook/ghedt/archive/v0.3.tar.gz', long_description=long_description, long_description_content_type='text/markdown', - version='0.2', + version='0.3', packages=find_packages(), include_package_data=True, author='Jack C. Cook', - author_email='jack.cook@okstate.edu', + author_email='jack-c-cook@protonmail.com', description='A ground heat exchanger design tool with the advanced and ' 'unmatched capability of automatic borehole field selection ' 'based on drilling geometric land constraints.') diff --git a/tests/test_design.py b/tests/test_design.py index a463794..cd41a04 100644 --- a/tests/test_design.py +++ b/tests/test_design.py @@ -3,13 +3,12 @@ import copy import unittest import os +import csv import ghedt as dt import ghedt.peak_load_analysis_tool as plat import pygfunction as gt -import pandas as pd - TESTDATA_FILENAME = os.path.join(os.path.dirname(__file__), 'Atlanta_Office_Building_Loads.csv') @@ -128,11 +127,13 @@ def setUp(self) -> None: # Process loads from file # ----------------------- # read in the csv file and convert the loads to a list of length 8760 - hourly_extraction: dict = \ - pd.read_csv(TESTDATA_FILENAME).to_dict('list') - # Take only the first column in the dictionary - self.hourly_extraction_ground_loads: list = \ - hourly_extraction[list(hourly_extraction.keys())[0]] + hourly_extraction: list = [] + with open(TESTDATA_FILENAME) as csvfile: + reader = csv.reader(csvfile, delimiter=',') + for i, row in enumerate(reader): + if i != 0 or i > 8760: + hourly_extraction.append(float(row[0])) + self.hourly_extraction_ground_loads = hourly_extraction # Geometric constraints for the `near-square` routine # Required geometric constraints for the uniform rectangle design: B @@ -140,7 +141,7 @@ def setUp(self) -> None: number_of_boreholes = 32 length = dt.utilities.length_of_side(number_of_boreholes, B) self.geometric_constraints = \ - dt.media.GeometricConstraints(B=B, length=length) + dt.geometry.Constraints(B=B, length=length) def test_design_selection(self): # Single U-tube diff --git a/tests/test_ghe.py b/tests/test_ghe.py index 481f9b1..3d6bd14 100644 --- a/tests/test_ghe.py +++ b/tests/test_ghe.py @@ -3,13 +3,12 @@ import unittest import os +import csv import ghedt as dt import ghedt.peak_load_analysis_tool as plat import pygfunction as gt -import pandas as pd - TESTDATA_FILENAME = os.path.join(os.path.dirname(__file__), 'Atlanta_Office_Building_Loads.csv') @@ -136,11 +135,13 @@ def setUp(self) -> None: # Process loads from file # ----------------------- # read in the csv file and convert the loads to a list of length 8760 - hourly_extraction: dict = \ - pd.read_csv(TESTDATA_FILENAME).to_dict('list') - # Take only the first column in the dictionary - self.hourly_extraction_ground_loads: list = \ - hourly_extraction[list(hourly_extraction.keys())[0]] + hourly_extraction: list = [] + with open(TESTDATA_FILENAME) as csvfile: + reader = csv.reader(csvfile, delimiter=',') + for i, row in enumerate(reader): + if i != 0 or i > 8760: + hourly_extraction.append(float(row[0])) + self.hourly_extraction_ground_loads = hourly_extraction def test_single_u_tube(self):