Repository: PMEAL/OpenPNM

Issue:
Move Multiphase into the contrib folder
We are still trying to figure out how Multiphase should work, and how it should interact with Mixtures, etc.  In the spirit of actually getting 3.0 released, I think we should move it to contrib to allow us to break compatibility later.

Discussion:

Patch:
diff --git a/openpnm/contrib/__init__.py b/openpnm/contrib/__init__.py
index f1d1793be..994381c77 100644
--- a/openpnm/contrib/__init__.py
+++ b/openpnm/contrib/__init__.py
@@ -10,3 +10,4 @@ removed.
 """
 
 from ._transient_multiphysics import *
+from ._multiphase import MultiPhase
diff --git a/openpnm/phase/_multiphase.py b/openpnm/contrib/_multiphase.py
similarity index 98%
rename from openpnm/phase/_multiphase.py
rename to openpnm/contrib/_multiphase.py
index 3a31f4eef..dde582568 100644
--- a/openpnm/phase/_multiphase.py
+++ b/openpnm/contrib/_multiphase.py
@@ -53,8 +53,8 @@ class MultiPhase(GenericPhase):
     --------
     >>> import scipy as sp
     >>> import openpnm as op
-    >>> from openpnm.phase import Air, Water, MultiPhase
-
+    >>> from openpnm.phase import Air, Water
+    >>> from openpnm.contrib import MultiPhase
     >>> net = op.network.Cubic(shape=[5, 5, 5])
     >>> air = Air(network=net, name='air')  # Create two pure phases
     >>> water = Water(network=net, name='water')
@@ -160,7 +160,8 @@ class MultiPhase(GenericPhase):
         Examples
         --------
         >>> import openpnm as op
-        >>> from openpnm.phase import Air, Water, MultiPhase
+        >>> from openpnm.phase import Air, Water
+        >>> from openpnm.contrib import MultiPhase
         >>> from openpnm.models.misc import constant
 
         >>> net = op.network.Cubic(shape=[5, 5, 5])
@@ -261,7 +262,7 @@ class MultiPhase(GenericPhase):
         >>> net = op.network.Cubic(shape=[5, 5, 5])
         >>> air = op.phase.Air(network=net, name='air')
         >>> water = op.phase.Water(network=net, name='water')
-        >>> mphase = op.phase.MultiPhase(network=net, phases=[air, water])
+        >>> mphase = op.contrib.MultiPhase(network=net, phases=[air, water])
         >>> mphase._format_interface_prop(propname="throat.foo", phases=[air, water])
         'throat.foo.air:water'
 
diff --git a/openpnm/phase/__init__.py b/openpnm/phase/__init__.py
index 995ee1306..de874a32a 100644
--- a/openpnm/phase/__init__.py
+++ b/openpnm/phase/__init__.py
@@ -65,4 +65,3 @@ from ._generic import GenericPhase
 from ._air import Air
 from ._water import Water
 from ._mercury import Mercury
-from ._multiphase import MultiPhase
diff --git a/scripts/example_mass_partitioning.py b/scripts/example_mass_partitioning.py
index c0b083e16..f58a6b6b2 100644
--- a/scripts/example_mass_partitioning.py
+++ b/scripts/example_mass_partitioning.py
@@ -22,7 +22,7 @@ water = op.phase.Water(network=net, name="water")
 water["pore.diffusivity"] = air["pore.diffusivity"] * 0.2
 
 # Define MultiPhase object
-mphase = op.phase.MultiPhase(network=net, phases=[air, water])
+mphase = op.contrib.MultiPhase(network=net, phases=[air, water])
 mphase._set_automatic_throat_occupancy()
 mphase.set_occupancy(phase=air, pores=[0, 1, 2, 3, 4])
 mphase.set_occupancy(phase=water, pores=[5, 6, 7, 8, 9])
diff --git a/scripts/example_multiphase_diffusion.py b/scripts/example_multiphase_diffusion.py
index 0a5f6b636..3cb2ea674 100755
--- a/scripts/example_multiphase_diffusion.py
+++ b/scripts/example_multiphase_diffusion.py
@@ -14,7 +14,8 @@ top and the bottom of the network.
 """
 import openpnm as op
 from openpnm.network import Cubic
-from openpnm.phase import Air, Water, MultiPhase
+from openpnm.phase import Air, Water
+from openpnm.contrib import MultiPhase
 from openpnm.geometry import SpheresAndCylinders
 from openpnm.physics import Standard
 from openpnm.models.misc import constant
@@ -26,7 +27,7 @@ np.random.seed(10)
 # Define network, geometry and constituent phases
 shape = np.array([100, 100, 1])
 net = Cubic(shape=shape)
-geom = StickAndBall(network=net, pores=net.Ps, throats=net.Ts)
+geom = op.geometry.SpheresAndCylinders(network=net, pores=net.Ps, throats=net.Ts)
 air = Air(network=net, name="air")
 water = Water(network=net, name="water")
 water["pore.diffusivity"] = air["pore.diffusivity"] * 0.05
@@ -57,7 +58,7 @@ phys.add_model(propname="throat.diffusive_conductance", model=mdiff)
 # Fickian diffusion
 fd = op.algorithms.FickianDiffusion(network=net, phase=mphase)
 # Set source term
-phys["pore.A1"] = -1e-8 * geom["pore.area"]
+phys["pore.A1"] = -1e-8 * geom["pore.cross_sectional_area"]
 phys["pore.A2"] = 0.0
 phys.add_model(
     propname="pore.rxn",
@@ -85,4 +86,4 @@ c2d = np.rot90(c.reshape(shape).squeeze())
 plt.imshow(c2d)
 plt.colorbar()
 
-op.io.XDMF.export_data(network=net, phases=mphase, filename="network")
+#op.io.XDMF.export_data(network=net, phases=mphase, filename="network")


Test patch:
diff --git a/tests/unit/algorithms/GenericTransportTest.py b/tests/unit/algorithms/GenericTransportTest.py
index ee5788abf..3b9e83f96 100644
--- a/tests/unit/algorithms/GenericTransportTest.py
+++ b/tests/unit/algorithms/GenericTransportTest.py
@@ -178,7 +178,7 @@ class GenericTransportTest:
         geom = op.geometry.SpheresAndCylinders(network=net, pores=net.Ps, throats=net.Ts)
         air = op.phase.Air(network=net)
         water = op.phase.Water(network=net)
-        m = op.phase.MultiPhase(network=net, phases=[air, water])
+        m = op.contrib.MultiPhase(network=net, phases=[air, water])
         m.set_occupancy(phase=air, pores=[0, 1, 2])
         m.set_occupancy(phase=water, pores=[3, 4, 5])
         const = op.models.misc.constant
diff --git a/tests/unit/models/physics/DiffusiveConductanceTest.py b/tests/unit/models/physics/DiffusiveConductanceTest.py
index cf5990b9a..e0143389e 100644
--- a/tests/unit/models/physics/DiffusiveConductanceTest.py
+++ b/tests/unit/models/physics/DiffusiveConductanceTest.py
@@ -89,7 +89,7 @@ class DiffusiveConductanceTest:
         geom['throat.diffusive_size_factors'] = self.size_factors_dict
         air = op.phase.Air(network=net)
         water = op.phase.Water(network=net)
-        m = op.phase.MultiPhase(network=net, phases=[air, water])
+        m = op.contrib.MultiPhase(network=net, phases=[air, water])
         m.set_occupancy(phase=air, pores=[0, 1, 2])
         m.set_occupancy(phase=water, pores=[3, 4, 5])
         const = op.models.misc.constant
diff --git a/tests/unit/phases/MultiPhaseTest.py b/tests/unit/phases/MultiPhaseTest.py
index a0e47061f..e3e687fcc 100644
--- a/tests/unit/phases/MultiPhaseTest.py
+++ b/tests/unit/phases/MultiPhaseTest.py
@@ -15,7 +15,7 @@ class MultiPhaseTest:
 
     def test_multiphase_init(self):
         phases = [self.air, self.water]
-        m = op.phase.MultiPhase(network=self.net, phases=phases)
+        m = op.contrib.MultiPhase(network=self.net, phases=phases)
 
         assert np.all(m['pore.occupancy.all'] == 0.0)
         assert np.all(m['throat.occupancy.all'] == 0.0)
@@ -25,7 +25,7 @@ class MultiPhaseTest:
 
     def test_multiphase_no_occupancy_yet(self):
         phases = [self.air, self.water]
-        m = op.phase.MultiPhase(network=self.net, phases=phases)
+        m = op.contrib.MultiPhase(network=self.net, phases=phases)
         self.water['pore.temperature'] = 300
 
         assert np.all(self.water['pore.temperature'] == 300)
@@ -35,7 +35,7 @@ class MultiPhaseTest:
 
     def test_multiphase_set_occupancy_w_indices_only(self):
         phases = [self.air, self.water]
-        m = op.phase.MultiPhase(network=self.net, phases=phases)
+        m = op.contrib.MultiPhase(network=self.net, phases=phases)
 
         Ps_water = np.array([0, 1, 2])
         Ps_water_mask = self.net.to_mask(pores=Ps_water)
@@ -51,7 +51,7 @@ class MultiPhaseTest:
 
     def test_multiphase_set_occupancy_w_values_only(self):
         phases = [self.air, self.water]
-        m = op.phase.MultiPhase(network=self.net, phases=phases)
+        m = op.contrib.MultiPhase(network=self.net, phases=phases)
 
         Pvals = np.array([0.5, 0.9, 0.01])
         Tvals = np.array([0.9, 0.01])
@@ -80,7 +80,7 @@ class MultiPhaseTest:
 
     def test_multiphase_set_occupancy_w_pore_indices_and_Pvals(self):
         phases = [self.air, self.water]
-        m = op.phase.MultiPhase(network=self.net, phases=phases)
+        m = op.contrib.MultiPhase(network=self.net, phases=phases)
 
         Ps_water = np.array([0, 1, 2])
         Pvals = np.array([0.5, 0.9, 0.01])
@@ -122,7 +122,7 @@ class MultiPhaseTest:
         assert m["throat.occupancy.water"][Ts_water].mean() == 0.23
 
     def test_multiphase_automatic_throat_occupancy(self):
-        m = op.phase.MultiPhase(network=self.net, phases=[self.air,
+        m = op.contrib.MultiPhase(network=self.net, phases=[self.air,
                                                            self.water])
         pores = np.random.choice(self.net.Ps, size=100, replace=False)
         Pvals = np.random.random(pores.size)
@@ -140,14 +140,14 @@ class MultiPhaseTest:
         assert_allclose(m["throat.occupancy.water"], np.minimum(oc1, oc2))
 
     def test_multiphase_occupancy_set_single_phase(self):
-        m = op.phase.MultiPhase(network=self.net)
+        m = op.contrib.MultiPhase(network=self.net)
         self.water['pore.temperature'] = 300
         assert np.all(self.water['pore.temperature'] == 300)
         m.set_occupancy(phase=self.water, Pvals=1, Tvals=1)
         assert np.all(m['pore.temperature'] == 300)
 
     def test_multiphase_occupancy_set_two_phase(self):
-        m = op.phase.MultiPhase(network=self.net)
+        m = op.contrib.MultiPhase(network=self.net)
         self.water['pore.temperature'] = 300
         self.air['pore.temperature'] = 200
 
@@ -165,7 +165,7 @@ class MultiPhaseTest:
 
     def test_mutliphase_partition_coef(self):
         phases = [self.water, self.air, self.oil]
-        m = op.phase.MultiPhase(network=self.net, phases=phases)
+        m = op.contrib.MultiPhase(network=self.net, phases=phases)
 
         x, y, z = self.net["pore.coords"].T
         ps_water = self.net.Ps[(y <= 3) + (y >= 8)]
@@ -231,24 +231,24 @@ class MultiPhaseTest:
     def test_multiphase_invalid_phase(self):
         pn = op.network.Cubic(shape=[3, 3, 3])
         water = op.phase.Water(network=pn)
-        m = op.phase.MultiPhase(network=self.net)
+        m = op.contrib.MultiPhase(network=self.net)
         with pytest.raises(Exception):
             m.set_occupancy(phase=water)
 
     def test_multiphase_invalid_occupancy(self):
-        m = op.phase.MultiPhase(network=self.net, phases=[self.water, self.air])
+        m = op.contrib.MultiPhase(network=self.net, phases=[self.water, self.air])
         # The next line ideally should throw an Exception, but warning for now
         m.set_occupancy(phase=self.water, Pvals=1.5, Tvals=2.5)
 
     def test_format_interface_prop(self):
         phases = [self.water, self.air]
-        m = op.phase.MultiPhase(network=self.net, phases=phases)
+        m = op.contrib.MultiPhase(network=self.net, phases=phases)
         propname = m._format_interface_prop(propname="throat.foo", phases=phases)
         assert propname == "throat.foo.water:air"
 
     def test_get_phases_names(self):
         phases = [self.water, self.air]
-        m = op.phase.MultiPhase(network=self.net, phases=phases)
+        m = op.contrib.MultiPhase(network=self.net, phases=phases)
         names = m._get_phases_names("throat.foo.air:water")
         assert names[0] == "air"
         assert names[1] == "water"
@@ -261,7 +261,7 @@ class MultiPhaseTest:
         oil = op.phase.Water(network=net, name="oil")
 
         # Create MultiPhase and set phase occupancies
-        m = op.phase.MultiPhase(network=net, phases=[water, air, oil])
+        m = op.contrib.MultiPhase(network=net, phases=[water, air, oil])
         m.set_occupancy(air, pores=[0, 1])
         m.set_occupancy(water, pores=[2, 3])
         m.set_occupancy(oil, pores=[4, 5])