Skip to content

Commit

Permalink
Merge pull request #82 from j-c-cook/issue81_duplicateboreholes
Browse files Browse the repository at this point in the history
functions to check for duplicates and to remove duplicates, update ex…
  • Loading branch information
MassimoCimmino authored Apr 10, 2021
2 parents 584754b + c83295e commit a98cc24
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 0 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## Current version

### New features

* [Issue 81](https://github.com/MassimoCimmino/pygfunction/issues/81) - Added functions to find a remove duplicate boreholes.

## Version 1.1.2 (2021-01-21)

### New features
Expand Down
4 changes: 4 additions & 0 deletions doc/source/example_custom_bore_field.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ This example demonstrates the use of the :doc:`borehole <boreholes>` module
to define the positions of the boreholes within a bore field from a list of
borehole positions.

Two borehole positions (1 and 2) are intentionally added as duplicates and
are removed by calling the :func:`pygfunction.boreholes.remove_duplicates`
function.

The following script generates a bore field with 5 boreholes. The field is
then plotted on a figure.

Expand Down
90 changes: 90 additions & 0 deletions pygfunction/boreholes.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,96 @@ def position(self):
return pos


def find_duplicates(boreField, disp=False):
"""
The distance method :func:`Borehole.distance` is utilized to find all
duplicate boreholes in a boreField.
This function considers a duplicate to be any pair of points that fall
within each others radius. The lower index (i) is always stored in the
0 position of the tuple, while the higher index (j) is stored in the 1
position.
Parameters
----------
boreField : list
A list of :class:`Borehole` objects
disp : bool, optional
Set to true to print progression messages.
Default is False.
Returns
-------
duplicate_pairs : list
A list of tuples where the tuples are pairs of duplicates
"""

duplicate_pairs = [] # define an empty list to be appended to
for i in range(len(boreField)):
borehole_1 = boreField[i]
for j in range(i, len(boreField)): # only loop unique interactions
borehole_2 = boreField[j]
if i == j: # skip the borehole itself
continue
else:
dist = borehole_1.distance(borehole_2)
if abs(dist - borehole_1.r_b) < borehole_1.r_b:
duplicate_pairs.append((i, j))
if disp:
# pad with '-' align in center
output = f"{ '*gt.boreholes.find_duplicates()*' :-^50}"
# keep a space between the function name
print(output.replace('*', ' '))
print('The duplicate pairs of boreholes found: {}'\
.format(duplicate_pairs))
return duplicate_pairs


def remove_duplicates(boreField, disp=False):
"""
Removes all of the duplicates found from the duplicate pairs returned in
:func:`check_duplicates`.
For each pair of duplicates, the first borehole (with the lower index) is
kept and the other (with the higher index) is removed.
Parameters
----------
boreField : list
A list of :class:`Borehole` objects
disp : bool, optional
Set to true to print progression messages.
Default is False.
Returns
-------
new_boreField : list
A boreField without duplicates
"""
# get a list of tuple
duplicate_pairs = find_duplicates(boreField, disp=disp)

new_boreField = []

# values not to be included
duplicate_bores = []
for i in range(len(duplicate_pairs)):
duplicate_bores.append(duplicate_pairs[i][1])

for i in range(len(boreField)):
if i in duplicate_bores:
continue
else:
new_boreField.append(boreField[i])
if disp:
# pad with '-' align in center
print(f"{'*gt.boreholes.remove_duplicates()*' :-^50}".\
replace('*', ' ')) # keep a space between the function name
n_duplicates = len(boreField) - len(new_boreField)
print('The number of duplicates removed: {}'.format(n_duplicates))

return new_boreField


def rectangle_field(N_1, N_2, B_1, B_2, H, D, r_b):
"""
Build a list of boreholes in a rectangular bore field configuration.
Expand Down
12 changes: 12 additions & 0 deletions pygfunction/examples/custom_bore_field.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,13 @@ def main():
r_b = 0.075 # Borehole radius (m)

# Borehole positions
# Note: Two duplicate boreholes have been added to this list of positions.
# Position 1 has a borehole that is directly on top of another bore
# Position 2 has a borehole with radius inside of another bore
# The duplicates will be removed with the remove_duplicates function
pos = [(0.0, 0.0),
(0.0, 0.0), # Duplicate (for example purposes)
(0.03, 0.0), # Duplicate (for example purposes)
(5.0, 0.),
(3.5, 4.0),
(1.0, 7.0),
Expand All @@ -31,6 +37,12 @@ def main():
# Build list of boreholes
field = [gt.boreholes.Borehole(H, D, r_b, x, y) for (x, y) in pos]

# -------------------------------------------------------------------------
# Find and remove duplicates from borehole field
# -------------------------------------------------------------------------

field = gt.boreholes.remove_duplicates(field, disp=True)

# -------------------------------------------------------------------------
# Draw bore field
# -------------------------------------------------------------------------
Expand Down

0 comments on commit a98cc24

Please sign in to comment.