Skip to content

Commit

Permalink
Merge branch 'dev'
Browse files Browse the repository at this point in the history
  • Loading branch information
jgostick committed Aug 17, 2018
2 parents c63b105 + ab332bc commit da7c75a
Show file tree
Hide file tree
Showing 78 changed files with 2,124 additions and 1,040 deletions.
3 changes: 2 additions & 1 deletion docs/getting_started/quick_start.rst
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,8 @@ We must assign models to each of our Physics. The ``hg`` phase will be used to
>>> phys_h2o.add_model(propname='throat.hydraulic_conductance',
... model=model,
... pore_viscosity='pore.viscosity',
... throat_equivalent_area='throat.equivalent_area',
... pore_diameter='pore.diameter',
... throat_diameter='throat.diameter',
... throat_conduit_lengths='throat.conduit_lengths')
--------------------------------------------------------------------------------
Expand Down
2 changes: 1 addition & 1 deletion docs/userguide/data_storage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ The ``labels`` method can be used to obtain a list of all defined labels. This m
.. code-block:: python
>>> pn.labels()
['pore.all', 'pore.back', 'pore.bottom', 'pore.dummy_1', 'pore.dummy_2', 'pore.front', 'pore.internal', 'pore.left', 'pore.right', 'pore.top', 'throat.all', 'throat.internal']
['pore.all', 'pore.back', 'pore.bottom', 'pore.dummy_1', 'pore.dummy_2', 'pore.front', 'pore.internal', 'pore.left', 'pore.right', 'pore.surface', 'pore.top', 'throat.all', 'throat.internal', 'throat.surface']
This results can also be viewed with ``print(pn.labels())``.

Expand Down
13 changes: 11 additions & 2 deletions example_script.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import openpnm as op
ws = op.Workspace()
ws.settings['loglevel'] = 40
proj = ws.new_project()

pn = op.network.Cubic(shape=[10, 10, 10], spacing=1e-4, project=proj)
Expand Down Expand Up @@ -32,14 +33,22 @@
phys_air['pore.A'] = -1e-5
phys_air.add_model(propname='pore.2nd_order_rxn', model=mod,
quantity='pore.concentration',
prefactor='pore.A', exponent='pore.n')
prefactor='pore.A', exponent='pore.n',
regen_mode='deferred')
rxn = op.algorithms.FickianDiffusion(network=pn)
rxn.setup(phase=air)
Ps = pn.find_nearby_pores(pores=500, r=5e-4, flatten=True)
Ps = pn.find_nearby_pores(pores=50, r=5e-4, flatten=True)
rxn.set_source(propname='pore.2nd_order_rxn', pores=Ps)
rxn.set_value_BC(pores=pn.pores('top'), values=1)
rxn.run()
air.update(rxn.results())

fd = op.algorithms.FickianDiffusion(network=pn)
fd.setup(phase=air)
fd.set_value_BC(pores=pn.pores('left'), values=1)
fd.set_value_BC(pores=pn.pores('right'), values=0)
fd.run()
fd.calc_eff_diffusivity()

# Output network and phases to a VTP file for visualization in Paraview
# proj.export_data(network=pn, phases=[hg, air, water], filename='output.vtp')
17 changes: 8 additions & 9 deletions openpnm/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
import logging as _logging
r"""
**OpenPNM**
__version__ = '2.0.0-b2'
OpenPNM is a package for performing pore network simulations of transport in
porous materials
"""

__version__ = '2.0.0-b3'

from . import utils
from .utils import Workspace, Project
Expand All @@ -14,10 +20,3 @@
from . import algorithms
from . import io
from . import materials


# Set up logging to file - see previous section for more details
log_format = \
'%(asctime)s | %(levelname)-8s | %(name)s.%(funcName)s | %(message)s'
_logging.basicConfig(level=_logging.WARNING, format=log_format)
del log_format
28 changes: 19 additions & 9 deletions openpnm/algorithms/AdvectionDiffusion.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,26 @@ class AdvectionDiffusion(ReactiveTransport):
"""

def __init__(self, settings={}, **kwargs):
def_set = {'quantity': 'pore.concentration',
'diffusive_conductance': 'throat.diffusive_conductance',
'hydraulic_conductance': 'throat.hydraulic_conductance',
'pressure': 'pore.pressure',
's_scheme': 'powerlaw',
'gui': {'setup': {'quantity': '',
'diffusive_conductance': '',
'hydraulic_conductance': '',
'pressure': '',
's_scheme': ''},
'set_rate_BC': {'pores': None,
'values': None},
'set_value_BC': {'pores': None,
'values': None},
'set_source': {'pores': None,
'propname': ''}
}
}
super().__init__(**kwargs)
# Set some default settings
self.settings.update({'quantity': 'pore.concentration',
'diffusive_conductance':
'throat.diffusive_conductance',
'hydraulic_conductance':
'throat.hydraulic_conductance',
'pressure': 'pore.pressure',
's_scheme': 'powerlaw'})
# Apply any received settings to overwrite defaults
self.settings.update(def_set)
self.settings.update(settings)

def setup(self, phase=None, quantity='', diffusive_conductance='',
Expand Down
40 changes: 34 additions & 6 deletions openpnm/algorithms/Dispersion.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,43 @@ class Dispersion(ReactiveTransport):
'''
def __init__(self, settings={}, **kwargs):
def_set = {'quantity': 'pore.concentration',
'diffusive_conductance': 'throat.diffusive_conductance',
'hydraulic_conductance': 'throat.hydraulic_conductance',
'pressure': 'pore.pressure',
'gui': {'setup': {'quantity': '',
'diffusive_conductance': '',
'hydraulic_conductance': '',
'pressure': ''},
'set_rate_BC': {'pores': None,
'values': None},
'set_value_BC': {'pores': None,
'values': None},
'set_source': {'pores': None,
'propname': ''}
}
}
super().__init__(**kwargs)
self.settings.update({'quantity': 'pore.concentration',
'hydraulic_conductance':
'throat.hydraulic_conductance',
'diffusive_conductance':
'throat.diffusive_conductance',
'pressure': 'pore.pressure'})
self.settings.update(def_set)
self.settings.update(settings)

def setup(self, phase=None, quantity='', diffusive_conductance='',
hydraulic_conductance='', pressure='', **kwargs):
r"""
"""
if phase:
self.settings['phase'] = phase.name
if quantity:
self.settings['quantity'] = quantity
if diffusive_conductance:
self.settings['diffusive_conductance'] = diffusive_conductance
if hydraulic_conductance:
self.settings['hydraulic_conductance'] = hydraulic_conductance
if pressure:
self.settings['pressure'] = pressure
super().setup(**kwargs)

def _build_A(self, force=False):
r"""
"""
Expand Down
105 changes: 86 additions & 19 deletions openpnm/algorithms/FickianDiffusion.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,61 @@
import scipy as sp
from openpnm.algorithms import ReactiveTransport
from openpnm.utils import logging
logger = logging.getLogger(__name__)


class FickianDiffusion(ReactiveTransport):
r"""
A subclass of GenericLinearTransport to simulate binary diffusion. The 2
main roles of this subclass are to set the default property names and to
implement a method for calculating the effective diffusion coefficient
of the network.
A class to simulate binary diffusion.
Parameters
----------
network : OpenPNM Network object
The network on which this algorithm operates
project : OpenPNM Projecxt object
Either a network or a project must be specified
name : string, optional
A unique name to give the object for easier identification. If not
given, one is generated.
Notes
-----
Fickian diffusion in porous materials occurs in the void space, but
becuase the diffusion is defined to pores it is impacted by the porosity
and tortuosity of the network. Thus the total diffusive flux through the
network is reduced. This class can be used to simualte diffusion-reaction
in domains with arbitrarily complex boundary conditions, or it can be used
to calculate the effective diffusivity of the network by applying
controlled boundary conditions on opposing faces, calculate the diffusion
rate, and inverting Fick's first law:
.. math::
D_{eff} = N_{A}*L/(A*\Delta C_{A})
This class includes a method for calculating Deff automatically assuming
appropriate boundary conditions were applied (``calc_eff_diffusivity``).
The length and area of the domain should be supplied, but if they are
not an attempt is made to calculate them.
"""

def __init__(self, settings={}, **kwargs):
def_set = {'quantity': 'pore.concentration',
'conductance': 'throat.diffusive_conductance',
'gui': {'setup': {'quantity': '',
'conductance': ''},
'set_rate_BC': {'pores': None,
'values': None},
'set_value_BC': {'pores': None,
'values': None},
'set_source': {'pores': None,
'propname': ''}
}
}
super().__init__(**kwargs)
self.settings.update({'quantity': 'pore.concentration',
'conductance': 'throat.diffusive_conductance'})
self.settings.update(def_set)
self.settings.update(settings)

def setup(self, phase=None, quantity='', conductance='', **kwargs):
Expand All @@ -27,20 +66,17 @@ def setup(self, phase=None, quantity='', conductance='', **kwargs):
Parameters
----------
phase : OpenPNM Phase object
The phase on which the algorithm is to be run. If no value is
given, the existing value is kept.
The phase on which the algorithm is to be run.
quantity : string
The name of the physical quantity to be calcualted. If no value is
given, the existing value is kept. The default value is
``'pore.mole_fraction'``.
(default is ``'pore.mole_fraction'``) The name of the physical
quantity to be calculated.
conductance : string
The name of the pore-scale transport conductance values. These
are typically calculate by a model attached to a *Physics* object
associated with the given *Phase*. If no value is given, the
existing value is kept. The default value is
``'throat.diffusive_conductance'``.
(default is ``'throat.diffusive_conductance'``) The name of the
pore-scale transport conductance values. These are typically
calculated by a model attached to a *Physics* object associated
with the given *Phase*.
Notes
-----
Expand All @@ -56,9 +92,40 @@ def setup(self, phase=None, quantity='', conductance='', **kwargs):
self.settings['conductance'] = conductance
super().setup(**kwargs)

def calc_eff_diffusivity(self):
def calc_eff_diffusivity(self, inlets=None, outlets=None,
domain_area=None, domain_length=None):
r"""
This calculates the effective diffusivity in this linear transport
algorithm.
Parameters
----------
inlets : array_like
The pores where the inlet composition boundary conditions were
applied. If not given an attempt is made to infer them from the
algorithm.
outlets : array_like
The pores where the outlet composition boundary conditions were
applied. If not given an attempt is made to infer them from the
algorithm.
domain_area : scalar, optional
The area of the inlet (and outlet) boundary faces. If not given
then an attempt is made to estimate it, but it is usually
underestimated.
domain_length : scalar, optional
The length of the domain between the inlet and outlet boundary
faces. If not given then an attempt is made to estimate it, but it
is usually underestimated.
Notes
-----
The area and length of the domain are found using the bounding box
around the inlet and outlet pores which do not necessarily lie on the
edge of the domain, resulting in underestimation of sizes.
"""
return self._calc_eff_prop()
return self._calc_eff_prop(inlets=inlets, outlets=outlets,
domain_area=domain_area,
domain_length=domain_length)
51 changes: 46 additions & 5 deletions openpnm/algorithms/FourierConduction.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,21 @@ class FourierConduction(ReactiveTransport):
network.
"""

def __init__(self, settings={}, **kwargs):
def_set = {'quantity': 'pore.temperature',
'conductance': 'throat.thermal_conductance',
'gui': {'setup': {'quantity': '',
'conductance': ''},
'set_rate_BC': {'pores': None,
'values': None},
'set_value_BC': {'pores': None,
'values': None},
'set_source': {'pores': None,
'propname': ''}
}
}
super().__init__(**kwargs)
self.settings.update({'quantity': 'pore.temperature',
'conductance': 'throat.thermal_conductance'})
self.settings.update(def_set)
self.settings.update(settings)

def setup(self, phase=None, quantity='', conductance='', **kwargs):
Expand Down Expand Up @@ -55,8 +65,39 @@ def setup(self, phase=None, quantity='', conductance='', **kwargs):
self.settings['conductance'] = conductance
super().setup(**kwargs)

def calc_effective_conductivity(self):
def calc_effective_conductivity(self, inlets=None, outlets=None,
domain_area=None, domain_length=None):
r"""
This calculates the effective thermal conductivity.
Parameters
----------
inlets : array_like
The pores where the inlet temperature boundary conditions were
applied. If not given an attempt is made to infer them from the
algorithm.
outlets : array_like
The pores where the outlet temperature boundary conditions were
applied. If not given an attempt is made to infer them from the
algorithm.
domain_area : scalar, optional
The area of the inlet (and outlet) boundary faces. If not given
then an attempt is made to estimate it, but it is usually
underestimated.
domain_length : scalar, optional
The length of the domain between the inlet and outlet boundary
faces. If not given then an attempt is made to estimate it, but it
is usually underestimated.
Notes
-----
The area and length of the domain are found using the bounding box
around the inlet and outlet pores which do not necessarily lie on the
edge of the domain, resulting in underestimation of sizes.
"""
return self._calc_eff_prop()
return self._calc_eff_prop(inlets=inlets, outlets=outlets,
domain_area=domain_area,
domain_length=domain_length)
8 changes: 7 additions & 1 deletion openpnm/algorithms/GenericAlgorithm.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,13 @@ def __init__(self, network=None, project=None, settings={}, **kwargs):
project = network.project
super().__init__(project=project, **kwargs)

if project.network is not None:
# Deal with network or project arguments
if network is not None:
if project is not None:
assert network is project.network
else:
project = network.project
if project:
self['pore.all'] = np.ones((project.network.Np, ), dtype=bool)
self['throat.all'] = np.ones((project.network.Nt, ), dtype=bool)

Expand Down

0 comments on commit da7c75a

Please sign in to comment.