diff --git a/examples/tutorials/08_simulating_transport.ipynb b/examples/tutorials/08_simulating_transport.ipynb index 3b5651ae54..0985222d93 100644 --- a/examples/tutorials/08_simulating_transport.ipynb +++ b/examples/tutorials/08_simulating_transport.ipynb @@ -23,7 +23,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 1, "id": "94917bac", "metadata": {}, "outputs": [ @@ -31,6 +31,120 @@ "name": "stdout", "output_type": "stream", "text": [ + "[nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan\n", + " nan nan nan nan nan nan nan]\n", + "[nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan\n", + " nan nan nan nan nan nan nan]\n", + "[nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan\n", + " nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan\n", + " nan nan nan nan]\n", + "[nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan\n", + " nan nan nan nan nan nan nan]\n", + "[nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan\n", + " nan nan nan nan nan nan nan]\n", + "[nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan\n", + " nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan\n", + " nan nan nan nan]\n", + "[nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan\n", + " nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan\n", + " nan nan nan nan]\n", + "[nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan\n", + " nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan\n", + " nan nan nan nan]\n", + "[[nan nan nan]\n", + " [nan nan nan]\n", + " [nan nan nan]\n", + " [nan nan nan]\n", + " [nan nan nan]\n", + " [nan nan nan]\n", + " [nan nan nan]\n", + " [nan nan nan]\n", + " [nan nan nan]\n", + " [nan nan nan]\n", + " [nan nan nan]\n", + " [nan nan nan]\n", + " [nan nan nan]\n", + " [nan nan nan]\n", + " [nan nan nan]\n", + " [nan nan nan]\n", + " [nan nan nan]\n", + " [nan nan nan]\n", + " [nan nan nan]\n", + " [nan nan nan]\n", + " [nan nan nan]\n", + " [nan nan nan]\n", + " [nan nan nan]\n", + " [nan nan nan]\n", + " [nan nan nan]\n", + " [nan nan nan]\n", + " [nan nan nan]\n", + " [nan nan nan]\n", + " [nan nan nan]\n", + " [nan nan nan]\n", + " [nan nan nan]\n", + " [nan nan nan]\n", + " [nan nan nan]\n", + " [nan nan nan]\n", + " [nan nan nan]\n", + " [nan nan nan]\n", + " [nan nan nan]\n", + " [nan nan nan]\n", + " [nan nan nan]\n", + " [nan nan nan]]\n", + "[[nan nan nan]\n", + " [nan nan nan]\n", + " [nan nan nan]\n", + " [nan nan nan]\n", + " [nan nan nan]\n", + " [nan nan nan]\n", + " [nan nan nan]\n", + " [nan nan nan]\n", + " [nan nan nan]\n", + " [nan nan nan]\n", + " [nan nan nan]\n", + " [nan nan nan]\n", + " [nan nan nan]\n", + " [nan nan nan]\n", + " [nan nan nan]\n", + " [nan nan nan]\n", + " [nan nan nan]\n", + " [nan nan nan]\n", + " [nan nan nan]\n", + " [nan nan nan]\n", + " [nan nan nan]\n", + " [nan nan nan]\n", + " [nan nan nan]\n", + " [nan nan nan]\n", + " [nan nan nan]\n", + " [nan nan nan]\n", + " [nan nan nan]\n", + " [nan nan nan]\n", + " [nan nan nan]\n", + " [nan nan nan]\n", + " [nan nan nan]\n", + " [nan nan nan]\n", + " [nan nan nan]\n", + " [nan nan nan]\n", + " [nan nan nan]\n", + " [nan nan nan]\n", + " [nan nan nan]\n", + " [nan nan nan]\n", + " [nan nan nan]\n", + " [nan nan nan]]\n", + "[nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan\n", + " nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan\n", + " nan nan nan nan]\n", + "[nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan\n", + " nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan\n", + " nan nan nan nan]\n", + "[nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan\n", + " nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan\n", + " nan nan nan nan]\n", + "[nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan\n", + " nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan\n", + " nan nan nan nan]\n", + "[nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan\n", + " nan nan nan nan nan nan nan]\n", "\n", "══════════════════════════════════════════════════════════════════════════════\n", "net : \n", @@ -92,7 +206,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 2, "id": "b5e3a75a", "metadata": {}, "outputs": [], @@ -110,7 +224,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 3, "id": "029d1797", "metadata": {}, "outputs": [ @@ -118,6 +232,8 @@ "name": "stdout", "output_type": "stream", "text": [ + "[nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan\n", + " nan nan nan nan nan nan nan]\n", "\n", "══════════════════════════════════════════════════════════════════════════════\n", "phase_01 : \n", @@ -152,7 +268,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 4, "id": "8833d1ee", "metadata": {}, "outputs": [ @@ -194,7 +310,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 5, "id": "647bde31", "metadata": {}, "outputs": [ @@ -235,7 +351,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 6, "id": "d4544d8b", "metadata": {}, "outputs": [ @@ -252,7 +368,7 @@ " 0.00089319, 0.00089319, 0.00089319, 0.00089319, 0.00089319])" ] }, - "execution_count": 7, + "execution_count": 6, "metadata": {}, "output_type": "execute_result" } @@ -263,7 +379,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 7, "id": "cf30019f", "metadata": {}, "outputs": [ @@ -280,7 +396,7 @@ " 0.00089319, 0.00089319, 0.00089319, 0.00089319, 0.00089319])" ] }, - "execution_count": 8, + "execution_count": 7, "metadata": {}, "output_type": "execute_result" } @@ -301,7 +417,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 8, "id": "29b8bf9d", "metadata": {}, "outputs": [ @@ -343,7 +459,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 9, "id": "3caad7c7", "metadata": {}, "outputs": [ @@ -385,7 +501,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 10, "id": "f14cea28", "metadata": {}, "outputs": [ @@ -411,7 +527,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 11, "id": "732f855a", "metadata": {}, "outputs": [], @@ -661,7 +777,7 @@ "\n", "$$ Q = \\bigg( \\frac{\\mu}{F_{h, i}} + \\frac{\\mu}{F_{h, k}} + \\frac{\\mu}{F_{h, j}} \\bigg) ^ {-1} \\Delta P $$\n", "\n", - "This can be computed by hand:" + "This can be computed by hand as follows. Note that we write the hydraulic conductance in an Nt by 2 array the OpenPNM convention is to store conductance values in an Nt by 2 array for symmetric and asymmetric physics." ] }, { @@ -672,7 +788,9 @@ "outputs": [], "source": [ "F_h = water['throat.hydraulic_size_factors']\n", - "water['throat.hydraulic_conductance'] = (mu * (1/F_h).sum(axis=1))**(-1)" + "gh = (mu * (1/F_h).sum(axis=1))**(-1)\n", + "gh = np.vstack((gh, gh)).T\n", + "water['throat.hydraulic_conductance'] = gh" ] }, { diff --git a/src/openpnm/algorithms/_advection_diffusion.py b/src/openpnm/algorithms/_advection_diffusion.py index f3f177c250..f31c3b1cc9 100644 --- a/src/openpnm/algorithms/_advection_diffusion.py +++ b/src/openpnm/algorithms/_advection_diffusion.py @@ -81,6 +81,9 @@ def set_outflow_BC(self, pores, mode='add'): C12 = network.conns[throats] P12 = phase[self.settings['pressure']][C12] gh = phase[self.settings['hydraulic_conductance']][throats] + # Special treatment when gh is not Nt by 1 + if gh.size == 2 * len(throats): + gh = gh[:, 0] # assumes hydraulic conductance is symmetric Q12 = -gh * np.diff(P12, axis=1).squeeze() Qp = np.zeros(self.Np) np.add.at(Qp, C12[:, 0], -Q12) diff --git a/src/openpnm/models/physics/_utils.py b/src/openpnm/models/physics/_utils.py index 0a7a859b70..b929d30c39 100644 --- a/src/openpnm/models/physics/_utils.py +++ b/src/openpnm/models/physics/_utils.py @@ -53,11 +53,12 @@ def _poisson_conductance(phase, g1 = D1 * F1 gt = Dt * Ft g2 = D2 * F2 - return 1 / (1 / g1 + 1 / gt + 1 / g2) + G = 1 / (1 / g1 + 1 / gt + 1 / g2) else: # Otherwise, i.e., the size factor for the entire conduit is only known F = network[size_factors] - return Dt * F + G = Dt * F + return vstack((G, G)).T def _get_key_props(phase=None, diff --git a/src/openpnm/models/physics/ad_dif_conductance/_funcs.py b/src/openpnm/models/physics/ad_dif_conductance/_funcs.py index dda067e16d..3f3e158b34 100644 --- a/src/openpnm/models/physics/ad_dif_conductance/_funcs.py +++ b/src/openpnm/models/physics/ad_dif_conductance/_funcs.py @@ -61,6 +61,9 @@ def ad_dif( else: raise Exception(f"Shape of {throat_diffusive_conductance} must either" r" be (Nt,1) or (Nt,2)") + # Special treatment when gh is not Nt by 1 + if gh.size == 2 * network.Nt: + gh = gh[:, 0] # assumes hydraulic conductance is symmetric Qij = -gh * _np.diff(P[cn], axis=1).squeeze() Qij = _np.append(Qij, -Qij) diff --git a/src/openpnm/models/physics/diffusive_conductance/_funcs.py b/src/openpnm/models/physics/diffusive_conductance/_funcs.py index 37f3b623c5..4a76e0fafb 100644 --- a/src/openpnm/models/physics/diffusive_conductance/_funcs.py +++ b/src/openpnm/models/physics/diffusive_conductance/_funcs.py @@ -193,4 +193,4 @@ def taylor_aris_diffusion(phase, gtot = 1 / (1/g1 + 1/gt + 1/g2) else: gtot = Dt * (1 + Pet**2 / 192) * F - return gtot + return _np.vstack((gtot, gtot)).T diff --git a/src/openpnm/models/physics/hydraulic_conductance/_funcs.py b/src/openpnm/models/physics/hydraulic_conductance/_funcs.py index f13ec78424..64ba404e13 100644 --- a/src/openpnm/models/physics/hydraulic_conductance/_funcs.py +++ b/src/openpnm/models/physics/hydraulic_conductance/_funcs.py @@ -50,7 +50,8 @@ def generic_hydraulic( g1 = F1 / mu1 gt = Ft / mut g2 = F2 / mu2 - return 1 / (1/g1 + 1/gt + 1/g2) + G = 1 / (1/g1 + 1/gt + 1/g2) + return _np.vstack((G, G)).T @_doctxt @@ -203,4 +204,5 @@ def valvatne_blunt( gt = kt * At**2 * Gt / mu_t value = L1 / gp[conns[:, 0]] + Lt / gt + L2 / gp[conns[:, 1]] - return 1 / value + G = 1 / value + return _np.vstack((G, G)).T diff --git a/tests/unit/models/physics/DiffusiveConductanceTest.py b/tests/unit/models/physics/DiffusiveConductanceTest.py index 5a114bc0db..f32bbc9046 100644 --- a/tests/unit/models/physics/DiffusiveConductanceTest.py +++ b/tests/unit/models/physics/DiffusiveConductanceTest.py @@ -1,6 +1,7 @@ import numpy as np import openpnm as op from numpy.testing import assert_allclose +import openpnm.models.physics.diffusive_conductance as diffusive_conductance class DiffusiveConductanceTest: @@ -120,6 +121,15 @@ def test_taylor_aris_diffusion(self): desired = np.array([0.121193, 0.126131, 0.118578]) assert_allclose(actual, desired, rtol=1e-5) + def test_conductance_shape(self): + available_models = [ + getattr(diffusive_conductance, model_name) + for model_name in dir(diffusive_conductance) + if callable(getattr(diffusive_conductance, model_name)) + ] + for model in available_models: + G = model(phase=self.phase) + assert_allclose(G.shape, (self.net.Nt, 2), rtol=0) if __name__ == '__main__': diff --git a/tests/unit/models/physics/ElectricalConductanceTest.py b/tests/unit/models/physics/ElectricalConductanceTest.py index 9420f1c7c1..4ee698d626 100644 --- a/tests/unit/models/physics/ElectricalConductanceTest.py +++ b/tests/unit/models/physics/ElectricalConductanceTest.py @@ -1,5 +1,6 @@ import numpy as np from numpy.testing import assert_allclose +import openpnm.models.physics.electrical_conductance as electrical_conductance import openpnm as op @@ -29,6 +30,15 @@ def test_series_resistors(self): actual = np.mean(self.phase['throat.electrical_conductance']) assert_allclose(actual, desired=0.091205, rtol=1e-5) + def test_conductance_shape(self): + available_models = [ + getattr(electrical_conductance, model_name) + for model_name in dir(electrical_conductance) + if callable(getattr(electrical_conductance, model_name)) + ] + for model in available_models: + G = model(phase=self.phase) + assert_allclose(G.shape, (self.net.Nt, 2), rtol=0) if __name__ == '__main__': diff --git a/tests/unit/models/physics/HydraulicConductanceTest.py b/tests/unit/models/physics/HydraulicConductanceTest.py index 21a9a58d5b..79d8ae8135 100644 --- a/tests/unit/models/physics/HydraulicConductanceTest.py +++ b/tests/unit/models/physics/HydraulicConductanceTest.py @@ -1,6 +1,7 @@ import openpnm as op import numpy as np from numpy.testing import assert_allclose +import openpnm.models.physics.hydraulic_conductance as hydraulic_conductance class HydraulicConductanceTest: @@ -53,7 +54,16 @@ def test_valvatne_blunt(self): actual = self.phase['throat.valvatne_conductance'].mean() desired = 6198.347107 assert_allclose(actual, desired=desired) - + + def test_conductance_shape(self): + available_models = [ + getattr(hydraulic_conductance, model_name) + for model_name in dir(hydraulic_conductance) + if callable(getattr(hydraulic_conductance, model_name)) + ] + for model in available_models: + G = model(phase=self.phase) + assert_allclose(G.shape, (self.net.Nt, 2), rtol=0) if __name__ == '__main__': diff --git a/tests/unit/models/physics/ThermalConductanceTest.py b/tests/unit/models/physics/ThermalConductanceTest.py index 858abe1dae..df050f87dc 100644 --- a/tests/unit/models/physics/ThermalConductanceTest.py +++ b/tests/unit/models/physics/ThermalConductanceTest.py @@ -1,5 +1,6 @@ import numpy as np from numpy.testing import assert_allclose +import openpnm.models.physics.thermal_conductance as thermal_conductance import openpnm as op @@ -28,6 +29,16 @@ def test_series_resistors(self): actual = self.phase['throat.thermal_conductance'].mean() desired = 1 / (1/(0.4*0.5) + 1/(0.2*0.5) + 1/(0.3*0.5)) assert_allclose(actual, desired) + + def test_conductance_shape(self): + available_models = [ + getattr(thermal_conductance, model_name) + for model_name in dir(thermal_conductance) + if callable(getattr(thermal_conductance, model_name)) + ] + for model in available_models: + G = model(phase=self.phase) + assert_allclose(G.shape, (self.net.Nt, 2), rtol=0) if __name__ == '__main__':