Skip to content

Commit

Permalink
Merge pull request PMEAL#2774 from PMEAL/enhancing_generators
Browse files Browse the repository at this point in the history
# Enhanced Voronoi generators to accept a `relaxation` argument #enh
# Fixed labeling bug in `FaceCenteredCubic` for face-to-face throats #bug
# Add `pore_labels` and `throat_labels` argments to `plot_tutorial` so apply custom labels #enh
  • Loading branch information
jgostick authored Jun 22, 2023
2 parents d4d73ab + 1b669b2 commit 8119bd9
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 16 deletions.
14 changes: 13 additions & 1 deletion openpnm/network/_delaunay_voronoi_dual.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ class DelaunayVoronoiDual(Network):
If ``True`` then the base points will be reflected across
all the faces of the domain prior to performing the tessellation. This
feature is best combined with ``trim=True``.
relaxation : int
The number of time to iteratively relax the base points by moving them to
the centroid of their respective Voronoi hulls. The default it 0.
%(Network.parameters)s
Expand All @@ -51,12 +54,21 @@ class DelaunayVoronoiDual(Network):
"""

def __init__(self, shape, points, trim=True, reflect=True, **kwargs):
def __init__(
self,
shape,
points,
trim=True,
reflect=True,
relaxation=0,
**kwargs
):
super().__init__(**kwargs)
net, vor, tri = voronoi_delaunay_dual(shape=shape,
points=points,
trim=trim,
reflect=reflect,
relaxation=relaxation,
node_prefix='pore',
edge_prefix='throat')
self.update(net)
Expand Down
19 changes: 9 additions & 10 deletions openpnm/network/_fcc.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,20 +50,19 @@ def __init__(self, shape, mode='sc', spacing=1, **kwargs):
net = fcc(shape=shape, spacing=spacing,
node_prefix='pore', edge_prefix='throat')
self.update(net)
# Deal with labels
Ts = self.find_neighbor_throats(pores=self.pores('corner'),
mode='xnor')
self['throat.corner_to_corner'] = False
self['throat.corner_to_corner'][Ts] = True
Ts = self.find_neighbor_throats(pores=self.pores('face'))
self['throat.corner_to_face'] = False
self['throat.corner_to_face'][Ts] = True
# Add labels
Ts1 = np.all(self['pore.corner'][self.conns], axis=1)
self['throat.corner_to_corner'] = Ts1
Ts2 = np.all(self['pore.face'][self.conns], axis=1)
self['throat.face_to_face'] = Ts2
self['throat.corner_to_face'] = ~(Ts1 + Ts2)

# Finally scale network to specified spacing
topotools.label_faces(self)
Ps = self.pores(['left', 'right', 'top', 'bottom', 'front', 'back'])
Ps = self.pores(['xmin', 'xmax', 'ymin', 'ymax', 'zmin', 'zmax'])
Ps = self.to_mask(pores=Ps)
self['pore.surface'] = Ps

# Finally scale network to specified spacing
self['pore.coords'] *= np.array(spacing)

def add_boundary_pores(self, labels, spacing):
Expand Down
14 changes: 13 additions & 1 deletion openpnm/network/_voronoi.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ class Voronoi(Network):
all the faces of the domain prior to performing the tessellation. This
feature is best combined with ``trim=True`` to make nice flat faces
on all sides of the domain.
relaxation : int
The number of time to iteratively relax the base points by moving them to
the centroid of their respective Voronoi hulls. The default it 0.
%(Network.parameters)s
Expand All @@ -58,12 +61,21 @@ class Voronoi(Network):
"""

def __init__(self, shape, points, trim=True, reflect=True, **kwargs):
def __init__(
self,
shape,
points,
trim=True,
reflect=True,
relaxation=0,
**kwargs
):
super().__init__(**kwargs)
net, vor = voronoi(points=points,
shape=shape,
trim=trim,
reflect=reflect,
relaxation=relaxation,
node_prefix='pore',
edge_prefix='throat')
self.update(net)
Expand Down
23 changes: 20 additions & 3 deletions openpnm/visualization/_plottools.py
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,9 @@ def plot_coordinates(network,
well as throat connections from ``plot_connections``.
size_by : str or array_like
An ndarray of pore values (e.g. alg['pore.concentration']). These
values are normalized by scaled by ``markersize``.
values are normalized by scaled by ``markersize``. Note that this controls
the marker *area*, so if you want the markers to be proportional to diameter
you should do `size_by=net['pore.diameter']**2`.
color_by : str or array_like
An ndarray of pore values (e.g. alg['pore.concentration']).
cmap : str or cmap object
Expand Down Expand Up @@ -469,6 +471,8 @@ def plot_networkx(network,


def plot_tutorial(network,
pore_labels=None,
throat_labels=None,
font_size=12,
line_width=2,
node_color='b',
Expand All @@ -482,6 +486,12 @@ def plot_tutorial(network,
network : Network
The network to plot, should be 2D, since the z-coordinate will be
ignored.
pore_labels : array_like
A list of values to use for labeling the pores. If not provided then pore
index is used.
throat_labels : array_like
A list of values to use for labeling the throat. If not provided then throat
index is used.
font_size : int
Size of font to use for labels.
line_width : int
Expand All @@ -504,8 +514,15 @@ def plot_tutorial(network,

G = network_to_networkx(network=network)
pos = {i: network['pore.coords'][i, 0:2] for i in network.Ps}
labels = {i: i for i in network.Ps}
edge_labels = {tuple(network['throat.conns'][i, :]): i for i in network.Ts}
if pore_labels is None:
labels = {i: i for i in network.Ps}
else:
labels = {i: pore_labels[i] for i in network.Ps}
if throat_labels is None:
edge_labels = {tuple(network['throat.conns'][i, :]): i for i in network.Ts}
else:
edge_labels = {tuple(network['throat.conns'][i, :]): throat_labels[i]
for i in network.Ts}

gplot = nx.draw_networkx_nodes(G, pos,
node_size=node_size,
Expand Down
3 changes: 2 additions & 1 deletion tests/unit/network/BravaisTest.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ def test_generation_fcc(self):
assert fcc.num_pores('pore.corner') == 27
assert fcc.num_pores('pore.face') == 36
assert fcc.num_throats('throat.corner_to_corner') == 54
assert fcc.num_throats('throat.corner_to_face') == 240
assert fcc.num_throats('throat.face_to_face') == 96
assert fcc.num_throats('throat.corner_to_face') == 144

def test_fcc_add_boundary_pores(self):
fcc = op.network.FaceCenteredCubic(shape=[3, 3, 3])
Expand Down

0 comments on commit 8119bd9

Please sign in to comment.