Repository: PMEAL/OpenPNM
Pull request #1820 (2021-01-23 00:49:52)

Adding filter_pores_by_z function to topotools


Patch:
diff --git a/openpnm/phases/MultiPhase.py b/openpnm/phases/MultiPhase.py
index ec0380208..db3611a26 100644
--- a/openpnm/phases/MultiPhase.py
+++ b/openpnm/phases/MultiPhase.py
@@ -150,24 +150,28 @@ class MultiPhase(GenericPhase):
         >>> water = Water(network=net, name='water')
         >>> mphase = MultiPhase(network=net, phases=[air, water], name='multi')
 
-        # Now, assign some pores to air and the rest to water
+        Now, assign some pores to air and the rest to water
+
         >>> Ps = net['pore.coords'][:, 0] < 3  # Pick some pores to be air filled
         >>> Ts = net.find_neighbor_throats(pores=Ps)  # Find neighboring throats
         >>> Ts = net.tomask(throats=Ts)  # Convert throat indices to mask
         >>> mphase.set_occupancy(phase=air, Pvals=Ps, Tvals=Ts)  # Assign occupancies
         >>> mphase.set_occupancy(phase=water, Pvals=~Ps, Tvals=~Ts)
 
-        # Now, add an interface model for binary partition coefficient
+        Now, add an interface model for binary partition coefficient
+
         >>> mphase.set_binary_partition_coef(phases=[air, water],
         ...                                  model=constant,
         ...                                  value=0.5)
 
-        # Now, verify that K12 for interface throats is 0.5
+        Now, verify that K12 for interface throats is 0.5
+
         >>> Ts_interface = net.find_neighbor_throats(Ps, mode="xor")
         >>> K12_interface = mphase["throat.partition_coef.all"][Ts_interface]
         >>> assert K12_interface.mean() == 0.5
 
-        # Finally, verify that K12 for non-interface throats is 1.
+        Finally, verify that K12 for non-interface throats is 1.
+
         >>> Ts_rest = ~ np.isin(net.Ts, Ts_interface)
         >>> K12_rest = mphase["throat.partition_coef.all"][Ts_rest]
         >>> assert K12_rest.mean() == 1.
diff --git a/openpnm/topotools/__init__.py b/openpnm/topotools/__init__.py
index c64bc983a..85d8c248c 100644
--- a/openpnm/topotools/__init__.py
+++ b/openpnm/topotools/__init__.py
@@ -15,6 +15,7 @@ from .topotools import clone_pores
 from .topotools import connect_pores
 from .topotools import dimensionality
 from .topotools import extend
+from .topotools import filter_pores_by_z
 from .topotools import find_surface_pores
 from .topotools import find_pore_to_pore_distance
 from .topotools import generate_base_points
diff --git a/openpnm/topotools/topotools.py b/openpnm/topotools/topotools.py
index a8ea3d647..f57c95320 100644
--- a/openpnm/topotools/topotools.py
+++ b/openpnm/topotools/topotools.py
@@ -2,7 +2,7 @@ import numpy as np
 import scipy as sp
 import scipy.ndimage as spim
 from scipy.sparse import csgraph
-from scipy.spatial import ConvexHull, delaunay_plot_2d
+from scipy.spatial import ConvexHull
 from openpnm.utils import logging, Workspace
 logger = logging.getLogger(__name__)
 ws = Workspace()
@@ -993,6 +993,32 @@ def find_pore_to_pore_distance(network, pores1=None, pores2=None):
     return cdist(coords[p1], coords[p2])
 
 
+def filter_pores_by_z(network, pores, z=1):
+    r"""
+    Find pores with a given number of neighbors
+
+    Parameters
+    ----------
+    network : OpenPNM Network object
+        The network on which the query is to be performed
+    pores : array_like
+        The pores to be filtered
+    z : int
+        The coordination number to filter by
+
+    Returns
+    -------
+    pores : array_like
+        The pores which have the specified coordination number
+
+    """
+    pores = network._parse_indices(pores)
+    Nz = network.num_neighbors(pores=pores)
+    orphans = np.where(Nz == z)[0]
+    hits = pores[orphans]
+    return hits
+
+
 def subdivide(network, pores, shape, labels=[]):
     r'''
     It trim the pores and replace them by cubic networks with the sent shape.


Test patch:
diff --git a/tests/unit/topotools/TopotoolsTest.py b/tests/unit/topotools/TopotoolsTest.py
index 19988d121..7eff8c981 100644
--- a/tests/unit/topotools/TopotoolsTest.py
+++ b/tests/unit/topotools/TopotoolsTest.py
@@ -436,6 +436,19 @@ class TopotoolsTest:
                                   pores2=pores2, mode='delaunay')
         assert pn.Nt == 436
 
+    def test_filter_pores_by_z(self):
+        pn = op.network.Cubic(shape=[4, 4, 1])
+        Ps = op.topotools.filter_pores_by_z(network=pn, pores=0, z=1)
+        assert_allclose(Ps, [])
+        Ps = op.topotools.filter_pores_by_z(network=pn, pores=0, z=2)
+        assert_allclose(Ps, [0])
+        Ps = op.topotools.filter_pores_by_z(network=pn, pores=[0, 1], z=1)
+        assert_allclose(Ps, [])
+        Ps = op.topotools.filter_pores_by_z(network=pn, pores=[0, 1], z=2)
+        assert_allclose(Ps, [0])
+        Ps = op.topotools.filter_pores_by_z(network=pn, pores=pn.Ps, z=4)
+        assert_allclose(Ps, [5, 6, 9, 10])
+
 
 if __name__ == '__main__':