openpnm 1.0.0__zip
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- OpenPNM-1.1/MANIFEST.in +2 -0
- OpenPNM-1.1/OpenPNM/Algorithms/__FickianDiffusion__.py +67 -0
- OpenPNM-1.1/OpenPNM/Algorithms/__FourierConduction__.py +63 -0
- OpenPNM-1.1/OpenPNM/Algorithms/__GenericAlgorithm__.py +235 -0
- OpenPNM-1.1/OpenPNM/Algorithms/__GenericLinearTransport__.py +641 -0
- OpenPNM-1.1/OpenPNM/Algorithms/__InvasionPercolationForImbibition__.py +703 -0
- OpenPNM-1.1/OpenPNM/Algorithms/__InvasionPercolationTimed__.py +702 -0
- OpenPNM-1.1/OpenPNM/Algorithms/__InvasionPercolation__.py +156 -0
- OpenPNM-1.1/OpenPNM/Algorithms/__OhmicConduction__.py +64 -0
- OpenPNM-1.1/OpenPNM/Algorithms/__OrdinaryPercolation__.py +402 -0
- OpenPNM-1.1/OpenPNM/Algorithms/__StokesFlow__.py +64 -0
- OpenPNM-1.1/OpenPNM/Algorithms/__Tortuosity__.py +91 -0
- OpenPNM-1.1/OpenPNM/Algorithms/__init__.py +48 -0
- OpenPNM-1.1/OpenPNM/Base/__Controller__.py +480 -0
- OpenPNM-1.1/OpenPNM/Base/__Core__.py +1522 -0
- OpenPNM-1.1/OpenPNM/Base/__ModelsDict__.py +345 -0
- OpenPNM-1.1/OpenPNM/Base/__Tools__.py +72 -0
- OpenPNM-1.1/OpenPNM/Base/__init__.py +32 -0
- OpenPNM-1.1/OpenPNM/Geometry/__Boundary__.py +80 -0
- OpenPNM-1.1/OpenPNM/Geometry/__Cube_and_Cuboid__.py +64 -0
- OpenPNM-1.1/OpenPNM/Geometry/__GenericGeometry__.py +106 -0
- OpenPNM-1.1/OpenPNM/Geometry/__SGL10__.py +67 -0
- OpenPNM-1.1/OpenPNM/Geometry/__Stick_and_Ball__.py +68 -0
- OpenPNM-1.1/OpenPNM/Geometry/__TestGeometry__.py +51 -0
- OpenPNM-1.1/OpenPNM/Geometry/__Toray090__.py +68 -0
- OpenPNM-1.1/OpenPNM/Geometry/__Voronoi__.py +98 -0
- OpenPNM-1.1/OpenPNM/Geometry/__init__.py +47 -0
- OpenPNM-1.1/OpenPNM/Geometry/models/__init__.py +33 -0
- OpenPNM-1.1/OpenPNM/Geometry/models/pore_area.py +27 -0
- OpenPNM-1.1/OpenPNM/Geometry/models/pore_centroid.py +35 -0
- OpenPNM-1.1/OpenPNM/Geometry/models/pore_diameter.py +127 -0
- OpenPNM-1.1/OpenPNM/Geometry/models/pore_misc.py +55 -0
- OpenPNM-1.1/OpenPNM/Geometry/models/pore_seed.py +212 -0
- OpenPNM-1.1/OpenPNM/Geometry/models/pore_surface_area.py +28 -0
- OpenPNM-1.1/OpenPNM/Geometry/models/pore_vertices.py +19 -0
- OpenPNM-1.1/OpenPNM/Geometry/models/pore_volume.py +133 -0
- OpenPNM-1.1/OpenPNM/Geometry/models/throat_area.py +47 -0
- OpenPNM-1.1/OpenPNM/Geometry/models/throat_centroid.py +80 -0
- OpenPNM-1.1/OpenPNM/Geometry/models/throat_diameter.py +106 -0
- OpenPNM-1.1/OpenPNM/Geometry/models/throat_length.py +95 -0
- OpenPNM-1.1/OpenPNM/Geometry/models/throat_misc.py +42 -0
- OpenPNM-1.1/OpenPNM/Geometry/models/throat_normal.py +31 -0
- OpenPNM-1.1/OpenPNM/Geometry/models/throat_offset_vertices.py +191 -0
- OpenPNM-1.1/OpenPNM/Geometry/models/throat_perimeter.py +26 -0
- OpenPNM-1.1/OpenPNM/Geometry/models/throat_seed.py +12 -0
- OpenPNM-1.1/OpenPNM/Geometry/models/throat_shape_factor.py +37 -0
- OpenPNM-1.1/OpenPNM/Geometry/models/throat_surface_area.py +44 -0
- OpenPNM-1.1/OpenPNM/Geometry/models/throat_vector.py +27 -0
- OpenPNM-1.1/OpenPNM/Geometry/models/throat_vertices.py +19 -0
- OpenPNM-1.1/OpenPNM/Geometry/models/throat_volume.py +45 -0
- OpenPNM-1.1/OpenPNM/Network/__Cubic__.py +316 -0
- OpenPNM-1.1/OpenPNM/Network/__DelaunayCubic__.py +127 -0
- OpenPNM-1.1/OpenPNM/Network/__Delaunay__.py +600 -0
- OpenPNM-1.1/OpenPNM/Network/__GenericNetwork__.py +1184 -0
- OpenPNM-1.1/OpenPNM/Network/__MatFile__.py +331 -0
- OpenPNM-1.1/OpenPNM/Network/__TestNet__.py +109 -0
- OpenPNM-1.1/OpenPNM/Network/__init__.py +40 -0
- OpenPNM-1.1/OpenPNM/Network/models/__init__.py +12 -0
- OpenPNM-1.1/OpenPNM/Network/models/pore_topology.py +106 -0
- OpenPNM-1.1/OpenPNM/Phases/__Air__.py +63 -0
- OpenPNM-1.1/OpenPNM/Phases/__GenericPhase__.py +146 -0
- OpenPNM-1.1/OpenPNM/Phases/__Mercury__.py +71 -0
- OpenPNM-1.1/OpenPNM/Phases/__TestPhase__.py +46 -0
- OpenPNM-1.1/OpenPNM/Phases/__Water__.py +56 -0
- OpenPNM-1.1/OpenPNM/Phases/__init__.py +38 -0
- OpenPNM-1.1/OpenPNM/Phases/models/__init__.py +22 -0
- OpenPNM-1.1/OpenPNM/Phases/models/contact_angle.py +34 -0
- OpenPNM-1.1/OpenPNM/Phases/models/density.py +81 -0
- OpenPNM-1.1/OpenPNM/Phases/models/diffusivity.py +95 -0
- OpenPNM-1.1/OpenPNM/Phases/models/electrical_conductivity.py +10 -0
- OpenPNM-1.1/OpenPNM/Phases/models/misc.py +125 -0
- OpenPNM-1.1/OpenPNM/Phases/models/molar_density.py +69 -0
- OpenPNM-1.1/OpenPNM/Phases/models/molar_mass.py +31 -0
- OpenPNM-1.1/OpenPNM/Phases/models/surface_tension.py +104 -0
- OpenPNM-1.1/OpenPNM/Phases/models/thermal_conductivity.py +98 -0
- OpenPNM-1.1/OpenPNM/Phases/models/vapor_pressure.py +69 -0
- OpenPNM-1.1/OpenPNM/Phases/models/viscosity.py +103 -0
- OpenPNM-1.1/OpenPNM/Physics/__GenericPhysics__.py +111 -0
- OpenPNM-1.1/OpenPNM/Physics/__Standard__.py +51 -0
- OpenPNM-1.1/OpenPNM/Physics/__TestPhysics__.py +50 -0
- OpenPNM-1.1/OpenPNM/Physics/__init__.py +30 -0
- OpenPNM-1.1/OpenPNM/Physics/models/__init__.py +18 -0
- OpenPNM-1.1/OpenPNM/Physics/models/capillary_pressure.py +122 -0
- OpenPNM-1.1/OpenPNM/Physics/models/diffusive_conductance.py +82 -0
- OpenPNM-1.1/OpenPNM/Physics/models/electrical_conductance.py +59 -0
- OpenPNM-1.1/OpenPNM/Physics/models/generic_source_term.py +564 -0
- OpenPNM-1.1/OpenPNM/Physics/models/hydraulic_conductance.py +76 -0
- OpenPNM-1.1/OpenPNM/Physics/models/multiphase.py +133 -0
- OpenPNM-1.1/OpenPNM/Physics/models/thermal_conductance.py +67 -0
- OpenPNM-1.1/OpenPNM/Postprocessing/Graphics.py +251 -0
- OpenPNM-1.1/OpenPNM/Postprocessing/Plots.py +369 -0
- OpenPNM-1.1/OpenPNM/Postprocessing/__init__.py +10 -0
- OpenPNM-1.1/OpenPNM/Utilities/IO.py +277 -0
- OpenPNM-1.1/OpenPNM/Utilities/Shortcuts.py +17 -0
- OpenPNM-1.1/OpenPNM/Utilities/__init__.py +16 -0
- OpenPNM-1.1/OpenPNM/Utilities/misc.py +226 -0
- OpenPNM-1.1/OpenPNM/Utilities/transformations.py +1923 -0
- OpenPNM-1.1/OpenPNM/Utilities/vertexops.py +824 -0
- OpenPNM-1.1/OpenPNM/__init__.py +56 -0
- OpenPNM-1.1/OpenPNM.egg-info/PKG-INFO +11 -0
- OpenPNM-1.1/OpenPNM.egg-info/SOURCES.txt +107 -0
- OpenPNM-1.1/OpenPNM.egg-info/dependency_links.txt +1 -0
- OpenPNM-1.1/OpenPNM.egg-info/requires.txt +1 -0
- OpenPNM-1.1/OpenPNM.egg-info/top_level.txt +1 -0
- OpenPNM-1.1/PKG-INFO +11 -0
- OpenPNM-1.1/README.txt +88 -0
- OpenPNM-1.1/setup.cfg +7 -0
- OpenPNM-1.1/setup.py +39 -0
OpenPNM-1.1/MANIFEST.in
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""
|
|
3
|
+
===============================================================================
|
|
4
|
+
module __FickianDiffusion__: Diffusive mass transfer
|
|
5
|
+
===============================================================================
|
|
6
|
+
|
|
7
|
+
"""
|
|
8
|
+
import scipy as sp
|
|
9
|
+
from OpenPNM.Algorithms import GenericLinearTransport
|
|
10
|
+
from OpenPNM.Base import logging
|
|
11
|
+
logger = logging.getLogger(__name__)
|
|
12
|
+
|
|
13
|
+
class FickianDiffusion(GenericLinearTransport):
|
|
14
|
+
r'''
|
|
15
|
+
A subclass of GenericLinearTransport to simulate binary diffusion. The 2
|
|
16
|
+
main roles of this subclass are to set the default property names and to
|
|
17
|
+
implement a method for calculating the effective diffusion coefficient
|
|
18
|
+
of the network.
|
|
19
|
+
|
|
20
|
+
Examples
|
|
21
|
+
--------
|
|
22
|
+
>>> import OpenPNM
|
|
23
|
+
>>> pn = OpenPNM.Network.TestNet()
|
|
24
|
+
>>> geo = OpenPNM.Geometry.TestGeometry(network=pn,pores=pn.pores(),throats=pn.throats())
|
|
25
|
+
>>> phase1 = OpenPNM.Phases.TestPhase(network=pn)
|
|
26
|
+
>>> phys1 = OpenPNM.Physics.TestPhysics(network=pn, phase=phase1,pores=pn.pores(),throats=pn.throats())
|
|
27
|
+
>>> alg = OpenPNM.Algorithms.FickianDiffusion(network=pn, phase=phase1)
|
|
28
|
+
>>> BC1_pores = pn.pores('top')
|
|
29
|
+
>>> alg.set_boundary_conditions(bctype='Dirichlet', bcvalue=0.6, pores=BC1_pores)
|
|
30
|
+
>>> BC2_pores = pn.pores('bottom')
|
|
31
|
+
>>> alg.set_boundary_conditions(bctype='Dirichlet', bcvalue=0.4, pores=BC2_pores)
|
|
32
|
+
>>> alg.run()
|
|
33
|
+
>>> alg.return_results()
|
|
34
|
+
>>> Deff = round(alg.calc_eff_diffusivity(), 3)
|
|
35
|
+
>>> print(Deff) #unless something changed with our test objects, this should print "0.025"
|
|
36
|
+
0.025
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
'''
|
|
40
|
+
|
|
41
|
+
def __init__(self,**kwargs):
|
|
42
|
+
r'''
|
|
43
|
+
|
|
44
|
+
'''
|
|
45
|
+
super(FickianDiffusion,self).__init__(**kwargs)
|
|
46
|
+
logger.info('Create '+self.__class__.__name__+' Object')
|
|
47
|
+
|
|
48
|
+
def setup(self,conductance='diffusive_conductance',quantity='mole_fraction',super_pore_conductance=None,**params):
|
|
49
|
+
r'''
|
|
50
|
+
This setup provides the initial requirements for the solver setup.
|
|
51
|
+
'''
|
|
52
|
+
logger.info("Setup "+self.__class__.__name__)
|
|
53
|
+
super(FickianDiffusion,self).setup(conductance=conductance,quantity=quantity,super_pore_conductance=super_pore_conductance)
|
|
54
|
+
|
|
55
|
+
def calc_eff_diffusivity(self):
|
|
56
|
+
r'''
|
|
57
|
+
This calculates the effective diffusivity in this linear transport algorithm.
|
|
58
|
+
'''
|
|
59
|
+
D_normal = self._calc_eff_prop()
|
|
60
|
+
self._eff_property = D_normal/sp.mean(self._phase['pore.molar_density'])
|
|
61
|
+
return self._eff_property
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
if __name__ == '__main__':
|
|
65
|
+
import doctest
|
|
66
|
+
doctest.testmod(verbose=True)
|
|
67
|
+
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""
|
|
3
|
+
===============================================================================
|
|
4
|
+
module __FourierConduction__: Conductive heat transfer
|
|
5
|
+
===============================================================================
|
|
6
|
+
|
|
7
|
+
A subclass of GenericLinearTransport to simulate heat conduction
|
|
8
|
+
|
|
9
|
+
"""
|
|
10
|
+
import scipy as sp
|
|
11
|
+
from OpenPNM.Algorithms import GenericLinearTransport
|
|
12
|
+
from OpenPNM.Base import logging
|
|
13
|
+
logger = logging.getLogger(__name__)
|
|
14
|
+
|
|
15
|
+
class FourierConduction(GenericLinearTransport):
|
|
16
|
+
r"""
|
|
17
|
+
A subclass of GenericLinearTransport to simulate heat conduction. The 2
|
|
18
|
+
main roles of this subclass are to set the default property names and to
|
|
19
|
+
implement a method for calculating the effective conductivity of the network.
|
|
20
|
+
|
|
21
|
+
Examples
|
|
22
|
+
--------
|
|
23
|
+
>>> import OpenPNM
|
|
24
|
+
>>> pn = OpenPNM.Network.TestNet()
|
|
25
|
+
>>> geo = OpenPNM.Geometry.TestGeometry(network=pn,pores=pn.pores(),throats=pn.throats())
|
|
26
|
+
>>> phase1 = OpenPNM.Phases.TestPhase(network=pn)
|
|
27
|
+
>>> phys1 = OpenPNM.Physics.TestPhysics(network=pn, phase=phase1,pores=pn.pores(),throats=pn.throats())
|
|
28
|
+
>>> alg = OpenPNM.Algorithms.FourierConduction(network=pn, phase=phase1)
|
|
29
|
+
>>> BC1_pores = pn.pores('top')
|
|
30
|
+
>>> alg.set_boundary_conditions(bctype='Dirichlet', bcvalue=0.6, pores=BC1_pores)
|
|
31
|
+
>>> BC2_pores = pn.pores('bottom')
|
|
32
|
+
>>> alg.set_boundary_conditions(bctype='Dirichlet', bcvalue=0.4, pores=BC2_pores)
|
|
33
|
+
>>> alg.run()
|
|
34
|
+
>>> alg.return_results()
|
|
35
|
+
>>> Ceff = round(alg._calc_eff_prop(), 3) #This line and the next line should fail until someone writes this function
|
|
36
|
+
>>> print(Ceff) #unless something changed with our test objects, this should print "0.025"
|
|
37
|
+
0.822
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
"""
|
|
41
|
+
|
|
42
|
+
def __init__(self,**kwargs):
|
|
43
|
+
r'''
|
|
44
|
+
'''
|
|
45
|
+
super(FourierConduction,self).__init__(**kwargs)
|
|
46
|
+
logger.info('Create '+self.__class__.__name__+' Object')
|
|
47
|
+
|
|
48
|
+
def setup(self,conductance='thermal_conductance',quantity='temperature',super_pore_conductance=None,**params):
|
|
49
|
+
r'''
|
|
50
|
+
This setup provides the initial requirements for the solver setup.
|
|
51
|
+
'''
|
|
52
|
+
logger.info("Setup "+self.__class__.__name__)
|
|
53
|
+
super(FourierConduction,self).setup(conductance=conductance,quantity=quantity,super_pore_conductance=super_pore_conductance)
|
|
54
|
+
|
|
55
|
+
def calc_effective_conductivity(self):
|
|
56
|
+
r'''
|
|
57
|
+
This calculates the effective thermal conductivity in this linear transport algorithm.
|
|
58
|
+
'''
|
|
59
|
+
return self._calc_eff_prop()
|
|
60
|
+
|
|
61
|
+
if __name__ == '__main__':
|
|
62
|
+
import doctest
|
|
63
|
+
doctest.testmod(verbose=True)
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""
|
|
3
|
+
===============================================================================
|
|
4
|
+
module __GenericAlgorithm__: Base class to build custom algorithms
|
|
5
|
+
==================================================================
|
|
6
|
+
|
|
7
|
+
This generic class contains the recommended methods for subclassed algorithms.
|
|
8
|
+
It inherits from Core, so is Python Dict with the OpenPNM data control methods.
|
|
9
|
+
|
|
10
|
+
"""
|
|
11
|
+
import scipy as sp
|
|
12
|
+
from OpenPNM.Base import Core
|
|
13
|
+
from OpenPNM.Base import logging
|
|
14
|
+
from OpenPNM.Network import GenericNetwork
|
|
15
|
+
logger = logging.getLogger(__name__)
|
|
16
|
+
|
|
17
|
+
class GenericAlgorithm(Core):
|
|
18
|
+
r"""
|
|
19
|
+
GenericAlgorithm - Base class to execute algorithms
|
|
20
|
+
|
|
21
|
+
Parameters
|
|
22
|
+
----------
|
|
23
|
+
network : OpenPNM Network Object
|
|
24
|
+
The network object to which this algorithm will apply.
|
|
25
|
+
|
|
26
|
+
name : string, optional
|
|
27
|
+
Name of this algorithm
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
Notes
|
|
31
|
+
-----
|
|
32
|
+
If no network is supplied an empty algorithm object is returned. This is
|
|
33
|
+
useful for loading in a saved algorithm from memory.
|
|
34
|
+
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
def __init__(self,network=None,**kwords):
|
|
38
|
+
r"""
|
|
39
|
+
Initialize
|
|
40
|
+
"""
|
|
41
|
+
super(GenericAlgorithm,self).__init__(**kwords)
|
|
42
|
+
logger.name = self.name
|
|
43
|
+
|
|
44
|
+
if network is None:
|
|
45
|
+
self._net = GenericNetwork()
|
|
46
|
+
else:
|
|
47
|
+
self._net = network
|
|
48
|
+
|
|
49
|
+
# Initialize label 'all' in the object's own info dictionaries
|
|
50
|
+
self['pore.all'] = self._net['pore.all']
|
|
51
|
+
self['throat.all'] = self._net['throat.all']
|
|
52
|
+
|
|
53
|
+
def run(self,**params):
|
|
54
|
+
r"""
|
|
55
|
+
Main run command for the algorithm
|
|
56
|
+
"""
|
|
57
|
+
self._do_outer_iteration_stage()
|
|
58
|
+
|
|
59
|
+
def _do_outer_iteration_stage(self):
|
|
60
|
+
r"""
|
|
61
|
+
Executes the outer iteration stage
|
|
62
|
+
"""
|
|
63
|
+
self._do_one_outer_iteration()
|
|
64
|
+
|
|
65
|
+
def _do_one_outer_iteration(self):
|
|
66
|
+
r"""
|
|
67
|
+
One iteration of an outer iteration loop for an algorithm
|
|
68
|
+
(e.g. time or parametric study)
|
|
69
|
+
"""
|
|
70
|
+
self._do_inner_iteration_stage()
|
|
71
|
+
|
|
72
|
+
def _do_inner_iteration_stage(self):
|
|
73
|
+
r"""
|
|
74
|
+
Executes the inner iteration stage
|
|
75
|
+
"""
|
|
76
|
+
self._do_one_inner_iteration()
|
|
77
|
+
|
|
78
|
+
def _do_one_inner_iteration(self):
|
|
79
|
+
r"""
|
|
80
|
+
Executes one inner iteration
|
|
81
|
+
"""
|
|
82
|
+
pass
|
|
83
|
+
|
|
84
|
+
def return_results(self,**kwargs):
|
|
85
|
+
pass
|
|
86
|
+
|
|
87
|
+
def set_boundary_conditions(self,component=None,bctype='',bcvalue=None,pores=None,throats=None,mode='merge'):
|
|
88
|
+
r'''
|
|
89
|
+
Apply boundary conditions to specified pores or throats
|
|
90
|
+
|
|
91
|
+
Parameters
|
|
92
|
+
----------
|
|
93
|
+
bctype : string
|
|
94
|
+
Specifies the type or the name of boundary condition to apply. The types can be one one of the followings:
|
|
95
|
+
|
|
96
|
+
- 'Dirichlet' : Specify the quantity in each location
|
|
97
|
+
- 'Neumann' : Specify the flow rate into each location
|
|
98
|
+
- 'Neumann_group' : Specify the net flow rate into a group of pores/throats
|
|
99
|
+
component : OpenPNM Phase object
|
|
100
|
+
The Phase object to which this BC applies
|
|
101
|
+
bcvalue : array_like
|
|
102
|
+
The boundary value to apply, such as concentration or rate
|
|
103
|
+
pores : array_like
|
|
104
|
+
The pores where the boundary conditions should be applied
|
|
105
|
+
throats : array_like
|
|
106
|
+
The throats where the boundary conditions should be applied
|
|
107
|
+
mode : string, optional
|
|
108
|
+
Controls how the conditions are applied. Options are:
|
|
109
|
+
|
|
110
|
+
- 'merge': Inserts the specified values, leaving existing values elsewhere
|
|
111
|
+
- 'overwrite': Inserts specified values, clearing all other values
|
|
112
|
+
- 'remove': Removes boundary conditions from specified locations
|
|
113
|
+
|
|
114
|
+
Notes
|
|
115
|
+
-----
|
|
116
|
+
1. It is not possible to have multiple boundary conditions for a specified location in just one algorithm.
|
|
117
|
+
So when new condition is going to be applied to a specific location, any existing one
|
|
118
|
+
should be removed or overwritten.
|
|
119
|
+
2- BCs for pores and for throats should be applied independently.
|
|
120
|
+
'''
|
|
121
|
+
try: self._existing_BC
|
|
122
|
+
except: self._existing_BC = []
|
|
123
|
+
if component is None:
|
|
124
|
+
if sp.size(self._phases)!=1:
|
|
125
|
+
raise Exception('In each use of set_boundary_conditions method, one component should be specified or attached to the algorithm.' )
|
|
126
|
+
else:
|
|
127
|
+
component = self._phases[0]
|
|
128
|
+
else:
|
|
129
|
+
if sp.size(component)!=1:
|
|
130
|
+
raise Exception('For using set_boundary_conditions method, only one component should be specified.')
|
|
131
|
+
|
|
132
|
+
if mode not in ['merge','overwrite','remove']:
|
|
133
|
+
raise Exception('The mode ('+mode+') cannot be applied to the set_boundary_conditions!')
|
|
134
|
+
|
|
135
|
+
logger.debug('BC applies to the component: '+component.name)
|
|
136
|
+
#If mode is 'remove', also bypass checks
|
|
137
|
+
if mode == 'remove':
|
|
138
|
+
if pores is None and throats is None:
|
|
139
|
+
if bctype=='':
|
|
140
|
+
raise Exception('No bctype/pore/throat is specified')
|
|
141
|
+
else:
|
|
142
|
+
for item in self.labels():
|
|
143
|
+
if bctype == (item.split('.')[-1]).replace(self._phase.name+'_',"") :
|
|
144
|
+
element = item.split('.')[0]
|
|
145
|
+
try:
|
|
146
|
+
del self[element+'.'+component.name+'_bcval_'+bctype]
|
|
147
|
+
except: pass
|
|
148
|
+
try:
|
|
149
|
+
del self[element+'.'+component.name+'_'+bctype]
|
|
150
|
+
except:
|
|
151
|
+
pass
|
|
152
|
+
logger.debug('Removing '+bctype+' from all locations for '+component.name+' in '+self.name)
|
|
153
|
+
self._existing_BC.remove(bctype)
|
|
154
|
+
else:
|
|
155
|
+
if pores is not None:
|
|
156
|
+
if bctype!='':
|
|
157
|
+
self['pore.'+component.name+'_bcval_'+bctype][pores] = sp.nan
|
|
158
|
+
self['pore.'+component.name+'_'+bctype][pores] = False
|
|
159
|
+
logger.debug('Removing '+bctype+' from the specified pores for '+component.name+' in '+self.name)
|
|
160
|
+
else: raise Exception('Cannot remove BC from the pores unless bctype is specified')
|
|
161
|
+
|
|
162
|
+
if throats is not None:
|
|
163
|
+
if bctype!='':
|
|
164
|
+
self['throat.'+component.name+'_bcval_'+bctype][throats] = sp.nan
|
|
165
|
+
self['throat.'+component.name+'_'+bctype][throats] = False
|
|
166
|
+
logger.debug('Removing '+bctype+' from the specified throats for '+component.name+' in '+self.name)
|
|
167
|
+
else: raise Exception('Cannot remove BC from the throats unless bctype is specified')
|
|
168
|
+
|
|
169
|
+
return
|
|
170
|
+
#Validate bctype
|
|
171
|
+
if bctype == '':
|
|
172
|
+
raise Exception('bctype must be specified')
|
|
173
|
+
#Validate pores/throats
|
|
174
|
+
if pores is None and throats is None:
|
|
175
|
+
raise Exception('pores/throats must be specified')
|
|
176
|
+
elif pores is not None and throats is not None:
|
|
177
|
+
raise Exception('BC for pores and throats must be specified independently')
|
|
178
|
+
elif throats is None:
|
|
179
|
+
element ='pore'
|
|
180
|
+
loc = sp.array(pores,ndmin=1)
|
|
181
|
+
all_length = self.num_pores()
|
|
182
|
+
elif pores is None:
|
|
183
|
+
element ='throat'
|
|
184
|
+
loc = sp.array(throats,ndmin=1)
|
|
185
|
+
all_length = self.num_throats()
|
|
186
|
+
else:
|
|
187
|
+
raise Exception('Problem with the pore and/or throat list')
|
|
188
|
+
#Validate bcvalue
|
|
189
|
+
if bcvalue is not None:
|
|
190
|
+
#Check bcvalues are compatible with bctypes
|
|
191
|
+
if bctype == 'Neumann_group': #Only scalars are acceptable
|
|
192
|
+
if sp.size(bcvalue) != 1:
|
|
193
|
+
raise Exception('When specifying Neumann_group, bcval should be a scalar')
|
|
194
|
+
else:
|
|
195
|
+
bcvalue = sp.float64(bcvalue)
|
|
196
|
+
if 'Neumann_group' not in self._existing_BC:
|
|
197
|
+
setattr(self,'_'+element+'_'+component.name+'_Neumann_group_location',[])
|
|
198
|
+
getattr(self,'_'+element+'_'+component.name+'_Neumann_group_location').append(loc)
|
|
199
|
+
else: #Only scalars or Np/Nt-long are acceptable
|
|
200
|
+
if sp.size(bcvalue) == 1:
|
|
201
|
+
bcvalue = sp.ones(sp.shape(loc))*bcvalue
|
|
202
|
+
elif sp.size(bcvalue) != sp.size(loc):
|
|
203
|
+
raise Exception('The pore/throat list and bcvalue list are different lengths')
|
|
204
|
+
#Confirm that prop and label arrays exist
|
|
205
|
+
if element+'.'+component.name+'_bcval_'+bctype not in self.props():
|
|
206
|
+
self[element+'.'+component.name+'_bcval_'+bctype] = sp.ones((all_length,),dtype=float)*sp.nan
|
|
207
|
+
if element+'.'+component.name+'_'+bctype not in self.labels():
|
|
208
|
+
self[element+'.'+component.name+'_'+bctype] = sp.zeros((all_length,),dtype=bool)
|
|
209
|
+
#Check all BC from specified locations, prior to setting new ones
|
|
210
|
+
for item in self.labels():
|
|
211
|
+
bcname = (item.split('.')[-1]).replace(component.name+'_',"")
|
|
212
|
+
if bcname in self._existing_BC and item.split('.')[0]==element:
|
|
213
|
+
if mode=='merge':
|
|
214
|
+
try:
|
|
215
|
+
self[element+'.'+component.name+'_bcval_'+bcname][loc]
|
|
216
|
+
if not (sp.isnan(self[element+'.'+component.name+'_bcval_'+bcname][loc]).all() and sp.sum(self[element+'.'+component.name+'_'+bcname][loc])==0):
|
|
217
|
+
raise Exception('Because of the existing BCs, the method cannot apply new BC with the merge mode to the specified pore/throat.')
|
|
218
|
+
except KeyError: pass
|
|
219
|
+
#Set boundary conditions based on supplied mode
|
|
220
|
+
if mode == 'merge':
|
|
221
|
+
if bcvalue is not None: self[element+'.'+component.name+'_bcval_'+bctype][loc] = bcvalue
|
|
222
|
+
self[element+'.'+component.name+'_'+bctype][loc] = True
|
|
223
|
+
if bctype not in self._existing_BC: self._existing_BC.append(bctype)
|
|
224
|
+
elif mode == 'overwrite':
|
|
225
|
+
self[element+'.'+component.name+'_bcval_'+bctype] = sp.ones((all_length,),dtype=float)*sp.nan
|
|
226
|
+
if bcvalue is not None: self[element+'.'+component.name+'_bcval_'+bctype][loc] = bcvalue
|
|
227
|
+
self[element+'.'+component.name+'_'+bctype] = sp.zeros((all_length,),dtype=bool)
|
|
228
|
+
self[element+'.'+component.name+'_'+bctype][loc] = True
|
|
229
|
+
if bctype not in self._existing_BC: self._existing_BC.append(bctype)
|
|
230
|
+
|
|
231
|
+
if __name__ == '__main__':
|
|
232
|
+
import OpenPNM
|
|
233
|
+
pn = OpenPNM.Network.TestNet()
|
|
234
|
+
test = OpenPNM.Algorithms.GenericAlgorithm(network=pn)
|
|
235
|
+
test.run()
|