Skip to content
Merged
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
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ jobs:
echo "if black check fails run"
echo " black ./flopy"
echo "and then commit the changes."
black --check ./flopy
black --check --diff ./flopy

- name: Run flake8
run: |
Expand Down
130 changes: 94 additions & 36 deletions autotest/t075_test_ugrid.py
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ def test_voronoi_grid0(plot=False):
test_setup = FlopyTestSetup(verbose=True, test_dirs=model_ws)

name = "vor0"
answer_ncpl = 3804
answer_ncpl = 3803
domain = [
[1831.381546, 6335.543757],
[4337.733475, 6851.136153],
Expand All @@ -298,7 +298,7 @@ def test_voronoi_grid0(plot=False):
[1330.11116, 1809.788273],
[399.1804436, 2998.515188],
[914.7728404, 5132.494831],
[1831.381546, 6335.543757],
# [1831.381546, 6335.543757],
]
area_max = 100.0 ** 2
tri = Triangle(maximum_area=area_max, angle=30, model_ws=model_ws)
Expand All @@ -308,11 +308,6 @@ def test_voronoi_grid0(plot=False):

vor = VoronoiGrid(tri)
gridprops = vor.get_gridprops_vertexgrid()
ncpl = gridprops["ncpl"]
assert (
ncpl == answer_ncpl
), f"Number of cells should be {answer_ncpl}. Found {ncpl}"

voronoi_grid = VertexGrid(**gridprops, nlay=1)

if plot:
Expand All @@ -324,6 +319,19 @@ def test_voronoi_grid0(plot=False):
voronoi_grid.plot(ax=ax)
plt.savefig(os.path.join(model_ws, f"{name}.png"))

# ensure proper number of cells
ncpl = gridprops["ncpl"]
errmsg = f"Number of cells should be {answer_ncpl}. Found {ncpl}"
assert ncpl == answer_ncpl, errmsg

# ensure that all cells have 3 or more points
ninvalid_cells = []
for icell, ivts in enumerate(vor.iverts):
if len(ivts) < 3:
ninvalid_cells.append(icell)
errmsg = f"The following cells do not have 3 or more vertices.\n{ninvalid_cells}"
assert len(ninvalid_cells) == 0, errmsg

return


Expand All @@ -346,10 +354,6 @@ def test_voronoi_grid1(plot=False):
vor = VoronoiGrid(tri)
gridprops = vor.get_gridprops_vertexgrid()
voronoi_grid = VertexGrid(**gridprops, nlay=1)
ncpl = gridprops["ncpl"]
assert (
ncpl == answer_ncpl
), f"Number of cells should be {answer_ncpl}. Found {ncpl}"

if plot:
import matplotlib.pyplot as plt
Expand All @@ -360,6 +364,19 @@ def test_voronoi_grid1(plot=False):
voronoi_grid.plot(ax=ax)
plt.savefig(os.path.join(model_ws, f"{name}.png"))

# ensure proper number of cells
ncpl = gridprops["ncpl"]
errmsg = f"Number of cells should be {answer_ncpl}. Found {ncpl}"
assert ncpl == answer_ncpl, errmsg

# ensure that all cells have 3 or more points
ninvalid_cells = []
for icell, ivts in enumerate(vor.iverts):
if len(ivts) < 3:
ninvalid_cells.append(icell)
errmsg = f"The following cells do not have 3 or more vertices.\n{ninvalid_cells}"
assert len(ninvalid_cells) == 0, errmsg

return


Expand All @@ -381,10 +398,6 @@ def test_voronoi_grid2(plot=False):
vor = VoronoiGrid(tri)
gridprops = vor.get_gridprops_vertexgrid()
voronoi_grid = VertexGrid(**gridprops, nlay=1)
ncpl = gridprops["ncpl"]
assert (
ncpl == answer_ncpl
), f"Number of cells should be {answer_ncpl}. Found {ncpl}"

if plot:
import matplotlib.pyplot as plt
Expand All @@ -395,6 +408,19 @@ def test_voronoi_grid2(plot=False):
voronoi_grid.plot(ax=ax)
plt.savefig(os.path.join(model_ws, f"{name}.png"))

# ensure proper number of cells
ncpl = gridprops["ncpl"]
errmsg = f"Number of cells should be {answer_ncpl}. Found {ncpl}"
assert ncpl == answer_ncpl, errmsg

# ensure that all cells have 3 or more points
ninvalid_cells = []
for icell, ivts in enumerate(vor.iverts):
if len(ivts) < 3:
ninvalid_cells.append(icell)
errmsg = f"The following cells do not have 3 or more vertices.\n{ninvalid_cells}"
assert len(ninvalid_cells) == 0, errmsg

return


Expand Down Expand Up @@ -426,10 +452,6 @@ def test_voronoi_grid3(plot=False):
vor = VoronoiGrid(tri)
gridprops = vor.get_gridprops_vertexgrid()
voronoi_grid = VertexGrid(**gridprops, nlay=1)
ncpl = gridprops["ncpl"]
assert (
ncpl == answer_ncpl
), f"Number of cells should be {answer_ncpl}. Found {ncpl}"

if plot:
import matplotlib.pyplot as plt
Expand All @@ -440,6 +462,19 @@ def test_voronoi_grid3(plot=False):
voronoi_grid.plot(ax=ax)
plt.savefig(os.path.join(model_ws, f"{name}.png"))

# ensure proper number of cells
ncpl = gridprops["ncpl"]
errmsg = f"Number of cells should be {answer_ncpl}. Found {ncpl}"
assert ncpl == answer_ncpl, errmsg

# ensure that all cells have 3 or more points
ninvalid_cells = []
for icell, ivts in enumerate(vor.iverts):
if len(ivts) < 3:
ninvalid_cells.append(icell)
errmsg = f"The following cells do not have 3 or more vertices.\n{ninvalid_cells}"
assert len(ninvalid_cells) == 0, errmsg

return


Expand All @@ -464,10 +499,6 @@ def test_voronoi_grid4(plot=False):
vor = VoronoiGrid(tri)
gridprops = vor.get_gridprops_vertexgrid()
voronoi_grid = VertexGrid(**gridprops, nlay=1)
ncpl = gridprops["ncpl"]
assert (
ncpl == answer_ncpl
), f"Number of cells should be {answer_ncpl}. Found {ncpl}"

if plot:
import matplotlib.pyplot as plt
Expand All @@ -478,6 +509,19 @@ def test_voronoi_grid4(plot=False):
voronoi_grid.plot(ax=ax)
plt.savefig(os.path.join(model_ws, f"{name}.png"))

# ensure proper number of cells
ncpl = gridprops["ncpl"]
errmsg = f"Number of cells should be {answer_ncpl}. Found {ncpl}"
assert ncpl == answer_ncpl, errmsg

# ensure that all cells have 3 or more points
ninvalid_cells = []
for icell, ivts in enumerate(vor.iverts):
if len(ivts) < 3:
ninvalid_cells.append(icell)
errmsg = f"The following cells do not have 3 or more vertices.\n{ninvalid_cells}"
assert len(ninvalid_cells) == 0, errmsg

return


Expand All @@ -486,10 +530,10 @@ def test_voronoi_grid5(plot=False):
test_setup = FlopyTestSetup(verbose=True, test_dirs=model_ws)

name = "vor5"
answer_ncpl = 1067
answer_ncpl = 1305
active_domain = [(0, 0), (100, 0), (100, 100), (0, 100)]
area1 = [(10, 10), (40, 10), (40, 40), (10, 40)]
area2 = [(50, 50), (90, 50), (90, 90), (50, 90)]
area2 = [(70, 70), (90, 70), (90, 90), (70, 90)]

tri = Triangle(angle=30, model_ws=model_ws)

Expand All @@ -515,25 +559,26 @@ def test_voronoi_grid5(plot=False):
# tri.add_hole((70, 20))

# add line through domain to force conforming cells
line = [(x, x) for x in np.linspace(10, 90, 100)]
line = [(x, x) for x in np.linspace(11, 89, 100)]
tri.add_polygon(line)

# then regions and other polygons should follow
tri.add_polygon(area1)
tri.add_polygon(area2)
tri.add_region((1, 1), 0, maximum_area=100) # point inside active domain
tri.add_region((11, 11), 1, maximum_area=10) # point inside area1
tri.add_region((70, 70), 2, maximum_area=3) # point inside area2
tri.add_region((70, 70), 2, maximum_area=1) # point inside area2

tri.build(verbose=False)

vor = VoronoiGrid(tri)
gridprops = vor.get_gridprops_vertexgrid()
voronoi_grid = VertexGrid(**gridprops, nlay=1)
ncpl = gridprops["ncpl"]
assert (
ncpl == answer_ncpl
), f"Number of cells should be {answer_ncpl}. Found {ncpl}"

ninvalid_cells = []
for icell, ivts in enumerate(vor.iverts):
if len(ivts) < 3:
ninvalid_cells.append(icell)

if plot:
import matplotlib.pyplot as plt
Expand All @@ -542,8 +587,21 @@ def test_voronoi_grid5(plot=False):
ax = fig.add_subplot()
ax.set_aspect("equal")
voronoi_grid.plot(ax=ax)

# plot invalid cells
ax.plot(voronoi_grid.xcellcenters[ninvalid_cells], voronoi_grid.ycellcenters[ninvalid_cells], 'ro')

plt.savefig(os.path.join(model_ws, f"{name}.png"))

# ensure proper number of cells
ncpl = gridprops["ncpl"]
errmsg = f"Number of cells should be {answer_ncpl}. Found {ncpl}"
assert ncpl == answer_ncpl, errmsg

# ensure that all cells have 3 or more points
errmsg = f"The following cells do not have 3 or more vertices.\n{ninvalid_cells}"
assert len(ninvalid_cells) == 0, errmsg

return


Expand All @@ -556,9 +614,9 @@ def test_voronoi_grid5(plot=False):
# test_create_unstructured_grid_from_verts()
# test_triangle_unstructured_grid()
# test_voronoi_vertex_grid()
test_voronoi_grid0(plot=True)
test_voronoi_grid1(plot=True)
test_voronoi_grid2(plot=True)
test_voronoi_grid3(plot=True)
test_voronoi_grid4(plot=True)
#test_voronoi_grid0(plot=True)
#test_voronoi_grid1(plot=True)
#test_voronoi_grid2(plot=True)
#test_voronoi_grid3(plot=True)
#test_voronoi_grid4(plot=True)
test_voronoi_grid5(plot=True)
67 changes: 27 additions & 40 deletions examples/Notebooks/flopy3_voronoi.ipynb

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions flopy/discretization/grid.py
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,10 @@ def lenuni(self):
def idomain(self):
return copy.deepcopy(self._idomain)

@idomain.setter
def idomain(self, idomain):
self._idomain = idomain

@property
def ncpl(self):
raise NotImplementedError("must define ncpl in child class")
Expand Down
4 changes: 3 additions & 1 deletion flopy/discretization/unstructuredgrid.py
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,9 @@ def nvert(self):
@property
def iverts(self):
if self._iverts is not None:
return [list(filter((None).__ne__, i)) for i in self._iverts]
return [
[ivt for ivt in t if ivt is not None] for t in self._iverts
]

@property
def verts(self):
Expand Down
8 changes: 6 additions & 2 deletions flopy/discretization/vertexgrid.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,12 +133,16 @@ def iverts(self):
@property
def cell1d(self):
if self._cell1d is not None:
return [list(filter((None).__ne__, t)) for t in self._cell1d]
return [
[ivt for ivt in t if ivt is not None] for t in self._cell2d
]

@property
def cell2d(self):
if self._cell2d is not None:
return [list(filter((None).__ne__, t)) for t in self._cell2d]
return [
[ivt for ivt in t if ivt is not None] for t in self._cell2d
]

@property
def verts(self):
Expand Down
27 changes: 20 additions & 7 deletions flopy/utils/voronoi.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,16 +82,27 @@ def tri2vor(tri, **kwargs):
tri_verts = tri.verts
tri_iverts = tri.iverts
tri_edge = tri.edge
npoints = tri_verts.shape[0]
ntriangles = len(tri_iverts)
nedges = tri_edge.shape[0]

# check to make sure there are no duplicate points
tri_verts_unique = np.unique(tri_verts, axis=0)
if tri_verts.shape != tri_verts_unique.shape:
npoints_unique = tri_verts_unique.shape[0]
errmsg = (
f"There are duplicate points in the triangular mesh. "
f"These can be caused by overlapping regions, holes, and "
f"refinement features. The triangular mesh has {npoints} "
f"points but only {npoints_unique} are unique."
)
raise Exception(errmsg)

# construct the voronoi grid
vor = Voronoi(tri_verts, **kwargs)
ridge_points = vor.ridge_points
ridge_vertices = vor.ridge_vertices

npoints = tri_verts.shape[0]
ntriangles = len(tri_iverts)
nedges = tri_edge.shape[0]

# test the voronoi vertices, and mark those outside of the domain
nvertices = vor.vertices.shape[0]
xc = vor.vertices[:, 0].reshape((nvertices, 1))
Expand All @@ -115,6 +126,9 @@ def tri2vor(tri, **kwargs):
# renumber valid vertices consecutively
idx_vertindex[idx_filtered] = np.arange(nvalid_vertices)

# Create new lists for the voronoi grid vertices and the
# voronoi grid incidence list. There should be one voronoi
# cell for each vertex point in the triangular grid
vor_verts = [(x, y) for x, y in vor.vertices[idx_filtered]]
vor_iverts = [[] for i in range(npoints)]

Expand Down Expand Up @@ -181,9 +195,8 @@ def tri2vor(tri, **kwargs):
if True:
vor_verts = np.array(vor_verts)
for icell in range(len(vor_iverts)):
vor_iverts[icell] = get_sorted_vertices(
vor_iverts[icell], vor_verts
)
iverts_cell = vor_iverts[icell]
vor_iverts[icell] = get_sorted_vertices(iverts_cell, vor_verts)

return vor_verts, vor_iverts

Expand Down