Repository: PMEAL/OpenPNM
Pull request #1996 (2021-09-09 20:03:23)

added get_conduit_data method plus tests
This PR adds the ``get_conduit_data`` to the Base class.  It does not yet add the magic functionality that we talked about: ``pn['conduit.diameter']``.  This is something we need to think about more.  So basically, this PR adds a handy function with no downside (except feature creep I guess).  


Patch:
diff --git a/openpnm/core/Base.py b/openpnm/core/Base.py
index a7904d82d..00320b63f 100644
--- a/openpnm/core/Base.py
+++ b/openpnm/core/Base.py
@@ -1307,6 +1307,45 @@ class Base(dict):
             values *= self[propname].units
         return values
 
+    def get_conduit_data(self, prop, mode='mean'):
+        r"""
+        Combined requested data into a single 3-column array
+
+        Parameters
+        ----------
+        prop : string
+            The dictionary key to the property of interest
+        mode : string
+            How interpolation should be peformed for missing values. If values
+            are present for both pores and throats, then this argument is
+            ignored.  The ``interpolate`` data method is used.  Options are:
+
+                * 'mean' (default)
+                    Finds the mean value of the neighboring pores (or throats)
+                * 'min'
+                    Finds the minimuem of the neighboring pores (or throats)
+                * 'max'
+                    Finds the maximum of the neighboring pores (or throats)
+
+        Returns
+        -------
+        conduit_data : ndarray
+            An Nt-by-3 array with each column containg the requested property
+            for each pore-throat-pore conduit.
+
+        """
+        try:
+            T = self['throat.' + prop]
+            try:
+                P1, P2 = self['pore.' + prop][self.network.conns].T
+            except KeyError:
+                P = self.interpolate_data(propname='throat.'+prop, mode=mode)
+                P1, P2 = P[self.network.conns].T
+        except KeyError:
+            P1, P2 = self['pore.' + prop][self.network.conns].T
+            T = self.interpolate_data(propname='pore.'+prop, mode=mode)
+        return np.vstack((P1, T, P2)).T
+
     def filter_by_label(self, pores=[], throats=[], labels=None, mode='or'):
         r"""
         Returns which of the supplied pores (or throats) has the specified


Test patch:
diff --git a/tests/unit/core/BaseTest.py b/tests/unit/core/BaseTest.py
index 0845b89b8..6d7694cc5 100644
--- a/tests/unit/core/BaseTest.py
+++ b/tests/unit/core/BaseTest.py
@@ -976,6 +976,19 @@ class BaseTest:
         with pytest.raises(Exception):
             op.core.Base(name="temp", project=obj.project)
 
+    def test_get_conduit_data(self):
+        pn = op.network.Cubic(shape=[3, 3, 3])
+        pn['pore.diameter'] = 2.0
+        a = pn.get_conduit_data('diameter')
+        assert np.all(a.shape == (54, 3))
+        assert a.sum() == np.prod(a.shape)*2.0
+        pn['throat.volume'] = 2.0
+        b = pn.get_conduit_data('volume')
+        assert np.all(b.shape == (54, 3))
+        assert b.sum() == 2*np.prod(b.shape)
+        with pytest.raises(KeyError):
+            pn.get_conduit_data('blah')
+
 
 if __name__ == '__main__':