Skip to content

Issue77 advanced search examples #109

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 14 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
2 changes: 1 addition & 1 deletion ghedt/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 1 addition & 2 deletions ghedt/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
9 changes: 9 additions & 0 deletions ghedt/coordinates.py
Original file line number Diff line number Diff line change
@@ -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 = []
Expand Down
41 changes: 36 additions & 5 deletions ghedt/design.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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):
Expand Down Expand Up @@ -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: '
Expand Down
6 changes: 3 additions & 3 deletions ghedt/domains.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion ghedt/examples/Design/find_bi_rectangle.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
213 changes: 213 additions & 0 deletions ghedt/examples/Design/find_bi_rectangular_cutout.py
Original file line number Diff line number Diff line change
@@ -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()
2 changes: 1 addition & 1 deletion ghedt/examples/Design/find_bi_zoned_rectangle.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
2 changes: 1 addition & 1 deletion ghedt/examples/Design/find_near_square.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
# -------------
Expand Down
2 changes: 1 addition & 1 deletion ghedt/examples/Design/find_rectangle.py
Original file line number Diff line number Diff line change
Expand Up @@ -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...'
Expand Down
Loading