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.
Files changed (108) hide show
  1. OpenPNM-1.1/MANIFEST.in +2 -0
  2. OpenPNM-1.1/OpenPNM/Algorithms/__FickianDiffusion__.py +67 -0
  3. OpenPNM-1.1/OpenPNM/Algorithms/__FourierConduction__.py +63 -0
  4. OpenPNM-1.1/OpenPNM/Algorithms/__GenericAlgorithm__.py +235 -0
  5. OpenPNM-1.1/OpenPNM/Algorithms/__GenericLinearTransport__.py +641 -0
  6. OpenPNM-1.1/OpenPNM/Algorithms/__InvasionPercolationForImbibition__.py +703 -0
  7. OpenPNM-1.1/OpenPNM/Algorithms/__InvasionPercolationTimed__.py +702 -0
  8. OpenPNM-1.1/OpenPNM/Algorithms/__InvasionPercolation__.py +156 -0
  9. OpenPNM-1.1/OpenPNM/Algorithms/__OhmicConduction__.py +64 -0
  10. OpenPNM-1.1/OpenPNM/Algorithms/__OrdinaryPercolation__.py +402 -0
  11. OpenPNM-1.1/OpenPNM/Algorithms/__StokesFlow__.py +64 -0
  12. OpenPNM-1.1/OpenPNM/Algorithms/__Tortuosity__.py +91 -0
  13. OpenPNM-1.1/OpenPNM/Algorithms/__init__.py +48 -0
  14. OpenPNM-1.1/OpenPNM/Base/__Controller__.py +480 -0
  15. OpenPNM-1.1/OpenPNM/Base/__Core__.py +1522 -0
  16. OpenPNM-1.1/OpenPNM/Base/__ModelsDict__.py +345 -0
  17. OpenPNM-1.1/OpenPNM/Base/__Tools__.py +72 -0
  18. OpenPNM-1.1/OpenPNM/Base/__init__.py +32 -0
  19. OpenPNM-1.1/OpenPNM/Geometry/__Boundary__.py +80 -0
  20. OpenPNM-1.1/OpenPNM/Geometry/__Cube_and_Cuboid__.py +64 -0
  21. OpenPNM-1.1/OpenPNM/Geometry/__GenericGeometry__.py +106 -0
  22. OpenPNM-1.1/OpenPNM/Geometry/__SGL10__.py +67 -0
  23. OpenPNM-1.1/OpenPNM/Geometry/__Stick_and_Ball__.py +68 -0
  24. OpenPNM-1.1/OpenPNM/Geometry/__TestGeometry__.py +51 -0
  25. OpenPNM-1.1/OpenPNM/Geometry/__Toray090__.py +68 -0
  26. OpenPNM-1.1/OpenPNM/Geometry/__Voronoi__.py +98 -0
  27. OpenPNM-1.1/OpenPNM/Geometry/__init__.py +47 -0
  28. OpenPNM-1.1/OpenPNM/Geometry/models/__init__.py +33 -0
  29. OpenPNM-1.1/OpenPNM/Geometry/models/pore_area.py +27 -0
  30. OpenPNM-1.1/OpenPNM/Geometry/models/pore_centroid.py +35 -0
  31. OpenPNM-1.1/OpenPNM/Geometry/models/pore_diameter.py +127 -0
  32. OpenPNM-1.1/OpenPNM/Geometry/models/pore_misc.py +55 -0
  33. OpenPNM-1.1/OpenPNM/Geometry/models/pore_seed.py +212 -0
  34. OpenPNM-1.1/OpenPNM/Geometry/models/pore_surface_area.py +28 -0
  35. OpenPNM-1.1/OpenPNM/Geometry/models/pore_vertices.py +19 -0
  36. OpenPNM-1.1/OpenPNM/Geometry/models/pore_volume.py +133 -0
  37. OpenPNM-1.1/OpenPNM/Geometry/models/throat_area.py +47 -0
  38. OpenPNM-1.1/OpenPNM/Geometry/models/throat_centroid.py +80 -0
  39. OpenPNM-1.1/OpenPNM/Geometry/models/throat_diameter.py +106 -0
  40. OpenPNM-1.1/OpenPNM/Geometry/models/throat_length.py +95 -0
  41. OpenPNM-1.1/OpenPNM/Geometry/models/throat_misc.py +42 -0
  42. OpenPNM-1.1/OpenPNM/Geometry/models/throat_normal.py +31 -0
  43. OpenPNM-1.1/OpenPNM/Geometry/models/throat_offset_vertices.py +191 -0
  44. OpenPNM-1.1/OpenPNM/Geometry/models/throat_perimeter.py +26 -0
  45. OpenPNM-1.1/OpenPNM/Geometry/models/throat_seed.py +12 -0
  46. OpenPNM-1.1/OpenPNM/Geometry/models/throat_shape_factor.py +37 -0
  47. OpenPNM-1.1/OpenPNM/Geometry/models/throat_surface_area.py +44 -0
  48. OpenPNM-1.1/OpenPNM/Geometry/models/throat_vector.py +27 -0
  49. OpenPNM-1.1/OpenPNM/Geometry/models/throat_vertices.py +19 -0
  50. OpenPNM-1.1/OpenPNM/Geometry/models/throat_volume.py +45 -0
  51. OpenPNM-1.1/OpenPNM/Network/__Cubic__.py +316 -0
  52. OpenPNM-1.1/OpenPNM/Network/__DelaunayCubic__.py +127 -0
  53. OpenPNM-1.1/OpenPNM/Network/__Delaunay__.py +600 -0
  54. OpenPNM-1.1/OpenPNM/Network/__GenericNetwork__.py +1184 -0
  55. OpenPNM-1.1/OpenPNM/Network/__MatFile__.py +331 -0
  56. OpenPNM-1.1/OpenPNM/Network/__TestNet__.py +109 -0
  57. OpenPNM-1.1/OpenPNM/Network/__init__.py +40 -0
  58. OpenPNM-1.1/OpenPNM/Network/models/__init__.py +12 -0
  59. OpenPNM-1.1/OpenPNM/Network/models/pore_topology.py +106 -0
  60. OpenPNM-1.1/OpenPNM/Phases/__Air__.py +63 -0
  61. OpenPNM-1.1/OpenPNM/Phases/__GenericPhase__.py +146 -0
  62. OpenPNM-1.1/OpenPNM/Phases/__Mercury__.py +71 -0
  63. OpenPNM-1.1/OpenPNM/Phases/__TestPhase__.py +46 -0
  64. OpenPNM-1.1/OpenPNM/Phases/__Water__.py +56 -0
  65. OpenPNM-1.1/OpenPNM/Phases/__init__.py +38 -0
  66. OpenPNM-1.1/OpenPNM/Phases/models/__init__.py +22 -0
  67. OpenPNM-1.1/OpenPNM/Phases/models/contact_angle.py +34 -0
  68. OpenPNM-1.1/OpenPNM/Phases/models/density.py +81 -0
  69. OpenPNM-1.1/OpenPNM/Phases/models/diffusivity.py +95 -0
  70. OpenPNM-1.1/OpenPNM/Phases/models/electrical_conductivity.py +10 -0
  71. OpenPNM-1.1/OpenPNM/Phases/models/misc.py +125 -0
  72. OpenPNM-1.1/OpenPNM/Phases/models/molar_density.py +69 -0
  73. OpenPNM-1.1/OpenPNM/Phases/models/molar_mass.py +31 -0
  74. OpenPNM-1.1/OpenPNM/Phases/models/surface_tension.py +104 -0
  75. OpenPNM-1.1/OpenPNM/Phases/models/thermal_conductivity.py +98 -0
  76. OpenPNM-1.1/OpenPNM/Phases/models/vapor_pressure.py +69 -0
  77. OpenPNM-1.1/OpenPNM/Phases/models/viscosity.py +103 -0
  78. OpenPNM-1.1/OpenPNM/Physics/__GenericPhysics__.py +111 -0
  79. OpenPNM-1.1/OpenPNM/Physics/__Standard__.py +51 -0
  80. OpenPNM-1.1/OpenPNM/Physics/__TestPhysics__.py +50 -0
  81. OpenPNM-1.1/OpenPNM/Physics/__init__.py +30 -0
  82. OpenPNM-1.1/OpenPNM/Physics/models/__init__.py +18 -0
  83. OpenPNM-1.1/OpenPNM/Physics/models/capillary_pressure.py +122 -0
  84. OpenPNM-1.1/OpenPNM/Physics/models/diffusive_conductance.py +82 -0
  85. OpenPNM-1.1/OpenPNM/Physics/models/electrical_conductance.py +59 -0
  86. OpenPNM-1.1/OpenPNM/Physics/models/generic_source_term.py +564 -0
  87. OpenPNM-1.1/OpenPNM/Physics/models/hydraulic_conductance.py +76 -0
  88. OpenPNM-1.1/OpenPNM/Physics/models/multiphase.py +133 -0
  89. OpenPNM-1.1/OpenPNM/Physics/models/thermal_conductance.py +67 -0
  90. OpenPNM-1.1/OpenPNM/Postprocessing/Graphics.py +251 -0
  91. OpenPNM-1.1/OpenPNM/Postprocessing/Plots.py +369 -0
  92. OpenPNM-1.1/OpenPNM/Postprocessing/__init__.py +10 -0
  93. OpenPNM-1.1/OpenPNM/Utilities/IO.py +277 -0
  94. OpenPNM-1.1/OpenPNM/Utilities/Shortcuts.py +17 -0
  95. OpenPNM-1.1/OpenPNM/Utilities/__init__.py +16 -0
  96. OpenPNM-1.1/OpenPNM/Utilities/misc.py +226 -0
  97. OpenPNM-1.1/OpenPNM/Utilities/transformations.py +1923 -0
  98. OpenPNM-1.1/OpenPNM/Utilities/vertexops.py +824 -0
  99. OpenPNM-1.1/OpenPNM/__init__.py +56 -0
  100. OpenPNM-1.1/OpenPNM.egg-info/PKG-INFO +11 -0
  101. OpenPNM-1.1/OpenPNM.egg-info/SOURCES.txt +107 -0
  102. OpenPNM-1.1/OpenPNM.egg-info/dependency_links.txt +1 -0
  103. OpenPNM-1.1/OpenPNM.egg-info/requires.txt +1 -0
  104. OpenPNM-1.1/OpenPNM.egg-info/top_level.txt +1 -0
  105. OpenPNM-1.1/PKG-INFO +11 -0
  106. OpenPNM-1.1/README.txt +88 -0
  107. OpenPNM-1.1/setup.cfg +7 -0
  108. OpenPNM-1.1/setup.py +39 -0
@@ -0,0 +1,146 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ ===============================================================================
4
+ module __GenericPhase__: Base class for building Phase objects
5
+ ===============================================================================
6
+
7
+ """
8
+ from OpenPNM.Base import Core, Tools, logging
9
+ logger = logging.getLogger(__name__)
10
+ from OpenPNM.Network import GenericNetwork
11
+ import OpenPNM.Phases.models
12
+ import scipy as sp
13
+
14
+ class GenericPhase(Core):
15
+ r"""
16
+ Base class to generate a generic phase object. The user must specify models
17
+ and parameters for all the properties they require. Classes for several
18
+ common phases are included with OpenPNM and can be found under OpenPNM.Phases.
19
+
20
+ Parameters
21
+ ----------
22
+ network : OpenPNM Network object
23
+ The network to which this Phase should be attached
24
+
25
+ components : list of OpenPNM Phase objects
26
+ These Phase objects are ficticious or virtual phases that are the pure
27
+ components from which the mixture is made. They are used to calculate
28
+ and store any pure component data. If none are supplied then this
29
+ object will act like either a pure component, a mixture whose properties
30
+ are well known (like air) and need not to be found from consideration of
31
+ the pure component properties.
32
+
33
+ name : str, optional
34
+ A unique string name to identify the Phase object, typically same as
35
+ instance name but can be anything.
36
+
37
+ """
38
+ def __init__(self,network=None,components=[],**kwargs):
39
+ super(GenericPhase,self).__init__(**kwargs)
40
+ logger.name = self.name
41
+
42
+ if network is None:
43
+ self._net = GenericNetwork()
44
+ else:
45
+ self._net = network
46
+
47
+ # Initialize label 'all' in the object's own info dictionaries
48
+ self['pore.all'] = self._net['pore.all']
49
+ self['throat.all'] = self._net['throat.all']
50
+
51
+ #Set standard conditions on the fluid to get started
52
+ self['pore.temperature'] = 298.0
53
+ self['pore.pressure'] = 101325.0
54
+
55
+ # Register Ohase object in Network dictionary
56
+ self._net['pore.'+self.name] = True
57
+ self._net['throat.'+self.name] = True
58
+
59
+ if components != []:
60
+ for comp in components:
61
+ self.set_component(phase=comp)
62
+ self._net._phases.append(self) # Append this Phase to the Network
63
+
64
+ def __setitem__(self,prop,value):
65
+ for phys in self._physics:
66
+ if (prop in phys.keys()) and ('all' not in prop.split('.')):
67
+ logger.error(prop+' is already defined in at least one associated Physics object')
68
+ return
69
+ super(GenericPhase,self).__setitem__(prop,value)
70
+
71
+ def __getitem__(self,key):
72
+ if key.split('.')[-1] == self.name:
73
+ element = key.split('.')[0]
74
+ return self[element+'.all']
75
+ if key not in self.keys():
76
+ logger.debug(key+' not on Phase, constructing data from Physics')
77
+ return self._interleave_data(key,sources=self._physics)
78
+ else:
79
+ return super(GenericPhase,self).__getitem__(key)
80
+
81
+ def set_component(self,phase,mode='add'):
82
+ r'''
83
+ This method is used to add or remove a ficticious phase object to this
84
+ object.
85
+
86
+ Parameters
87
+ ----------
88
+ phase : OpenPNM Phase object
89
+ This is the ficticious phase object defining a pure component.
90
+
91
+ mode : string
92
+ Indicates whether to 'add' or 'remove' the supplied Phase object
93
+ '''
94
+ if mode == 'add':
95
+ if phase.name in self.phases():
96
+ logger.error('Phase already present')
97
+ pass
98
+ else:
99
+ self._phases.append(phase) # Associate any sub-phases with self
100
+ phase._phases.append(self) # Associate self with sub-phases
101
+ #Add models for components to inherit mixture T and P
102
+ phase.models.add(propname='pore.temperature',model=OpenPNM.Phases.models.misc.mixture_value)
103
+ phase.models.add(propname='pore.pressure',model=OpenPNM.Phases.models.misc.mixture_value)
104
+ #Move T and P models to beginning of regeneration order
105
+ phase.models.reorder({'pore.temperature':0,'pore.pressure':1})
106
+ elif mode == 'remove':
107
+ if phase.name in self.phases():
108
+ self._phases.remove(phase)
109
+ phase._phases = []
110
+ else:
111
+ logger.error('Phase not found')
112
+ pass
113
+
114
+ def check_mixture_health(self):
115
+ r'''
116
+ Query the properties of the 'virtual phases' that make up a mixture
117
+ to ensure they all add up
118
+ '''
119
+ mole_sum = sp.zeros((self.Np,))
120
+ for comp in self._phases:
121
+ try:
122
+ mole_sum = mole_sum + comp['pore.mole_fraction']
123
+ except:
124
+ pass
125
+ return mole_sum
126
+
127
+ def check_physics_health(self):
128
+ r'''
129
+ Perform a check to find pores which have overlapping or undefined Physics
130
+ '''
131
+ phys = self.physics()
132
+ Ptemp = sp.zeros((self.Np,))
133
+ Ttemp = sp.zeros((self.Nt,))
134
+ for item in phys:
135
+ Pind = self['pore.'+item]
136
+ Tind = self['throat.'+item]
137
+ Ptemp[Pind] = Ptemp[Pind] + 1
138
+ Ttemp[Tind] = Ttemp[Tind] + 1
139
+ health = Tools.HealthDict()
140
+ health['overlapping_pores'] = sp.where(Ptemp>1)[0].tolist()
141
+ health['undefined_pores'] = sp.where(Ptemp==0)[0].tolist()
142
+ health['overlapping_throats'] = sp.where(Ttemp>1)[0].tolist()
143
+ health['undefined_throats'] = sp.where(Ttemp==0)[0].tolist()
144
+ return health
145
+
146
+
@@ -0,0 +1,71 @@
1
+ # -*- coding: utf-8 -*-
2
+ from OpenPNM.Phases import GenericPhase
3
+ from OpenPNM.Phases import models as fm
4
+
5
+ class Mercury(GenericPhase):
6
+ r"""
7
+ Creates Phase object with a default name 'Hg' and preset values for
8
+ mercury.
9
+
10
+ Parameters
11
+ ----------
12
+ network : OpenPNM Network object
13
+ The network to which this phase object will be attached.
14
+
15
+ Notes
16
+ -----
17
+ This explicit association is necessary so the Phase object can initialize
18
+ data arrays of the correct size to store network data.
19
+ The initial properties are all at std conditions of T = 298 K and P = 1 atm.
20
+
21
+ References
22
+ ----------
23
+ [1] Thermophysical Properties of Materials for Nuclear Engineering: IAEA, Vienna, 2008. ISBN 978-92-0-106508-7:
24
+
25
+ Examples
26
+ --------
27
+ >>> import OpenPNM
28
+ >>> pn = OpenPNM.Network.TestNet()
29
+ >>> hg = OpenPNM.Phases.Mercury(network=pn)
30
+
31
+ """
32
+ def __init__(self,name=None,**kwargs):
33
+ super(Mercury,self).__init__(name=name,**kwargs)
34
+ self._generate()
35
+
36
+ def _generate(self):
37
+ self['pore.molecular_weight'] = 0.2006 # kg/mol
38
+ self['pore.critical_pressure'] = 1.662E8 # Pa
39
+ self['pore.critical_temperature'] = 1733 # K
40
+ self['pore.critical_volume'] = 0.000189 # kg/m3
41
+ self['pore.contact_angle'] = 140 # Degree
42
+ self.models.add(propname='pore.vapor_pressure', # Pa
43
+ model=fm.vapor_pressure.antoine,
44
+ A=9.85767,
45
+ B=3007.129,
46
+ C=-10.001)
47
+ self.models.add(propname='pore.density', # kg/m3
48
+ model=fm.misc.linear,
49
+ poreprop='pore.temperature',
50
+ b=14280.9,
51
+ m=-2.47004)
52
+ self.models.add(propname='pore.molar_density',
53
+ model=fm.molar_density.standard) # mol/m3
54
+ self.models.add(propname='pore.surface_tension', # N/m
55
+ model=fm.misc.linear,
56
+ poreprop='pore.temperature',
57
+ b=0.56254,
58
+ m=-0.00028)
59
+ self.models.add(propname='pore.thermal_conductivity', # W/m.K
60
+ model=fm.misc.polynomial,
61
+ poreprop='pore.temperature',
62
+ a = [3.98691,0.0170967, -0.0000063862])
63
+ self.models.add(propname='pore.viscosity', # kg/m.s
64
+ model=fm.misc.polynomial,
65
+ poreprop='pore.temperature',
66
+ a = [0.00355837,-0.0000100131,1.23684E-08,-5.16836E-12])
67
+
68
+ if __name__ =="__main__":
69
+ import OpenPNM
70
+ pn = OpenPNM.Network.TestNet()
71
+ air = OpenPNM.Phases.Air(network=pn)
@@ -0,0 +1,46 @@
1
+ # -*- coding: utf-8 -*-
2
+ from OpenPNM.Phases import GenericPhase
3
+
4
+ class TestPhase(GenericPhase):
5
+ r'''
6
+ Creates Phase object with a default name 'testphase' and preset values for an air-like
7
+
8
+ Parameters
9
+ ----------
10
+ network : OpenPNM Network object
11
+ The network to which this phase object will be attached.
12
+
13
+ Notes
14
+ -----
15
+ This explicit association is necessary so the Phase object can initialize
16
+ data arrays of the correct size to store network data.
17
+
18
+ Examples
19
+ --------
20
+ >>> import OpenPNM
21
+ >>> pn = OpenPNM.Network.TestNet()
22
+ >>> water = OpenPNM.Phases.Water(network=pn)
23
+ '''
24
+ def __init__(self,name=None,**kwargs):
25
+ super(TestPhase,self).__init__(name=name,**kwargs)
26
+ self._generate()
27
+
28
+ def _generate(self):
29
+ self['pore.temperature'] = 298.0
30
+ self['pore.surface_tension'] = 0.072
31
+ self['pore.pressure'] = 101325.0
32
+ self['pore.diffusivity'] = 5.4785e-06
33
+ self['pore.molar_density'] = 40.89
34
+ self['pore.viscosity'] = 1.8443e-05
35
+ self['pore.molecular_weight'] = 28.97
36
+ self['pore.critical_temperature'] = 132.5
37
+ self['pore.critical_volume'] = 0.0883
38
+ self['pore.contact_angle'] = 120
39
+ self['pore.thermal_conductivity'] = 1
40
+ self['throat.thermal_conductivity'] = self.interpolate_data(data=self['pore.thermal_conductivity'])
41
+
42
+
43
+ if __name__ =="__main__":
44
+ import OpenPNM
45
+ pn = OpenPNM.Network.TestNet()
46
+ water = OpenPNM.Phases.Water(network=pn)
@@ -0,0 +1,56 @@
1
+ # -*- coding: utf-8 -*-
2
+ from OpenPNM.Phases import GenericPhase
3
+ from OpenPNM.Phases import models as fm
4
+
5
+ class Water(GenericPhase):
6
+ r'''
7
+ Creates Phase object with preset values for Water
8
+
9
+ Parameters
10
+ ----------
11
+ network : OpenPNM Network object
12
+ The Network to which this phase object will be associated.
13
+
14
+ Notes
15
+ -----
16
+ This explicit association is necessary so the Phase object can initialize
17
+ data arrays of the correct size to store network data.
18
+ The initial properties are all at std conditions of T = 298 K and P = 1 atm.
19
+
20
+ Examples
21
+ --------
22
+ >>> import OpenPNM
23
+ >>> pn = OpenPNM.Network.TestNet()
24
+ >>> water = OpenPNM.Phases.Water(network=pn)
25
+ '''
26
+ def __init__(self,name=None,**kwargs):
27
+ super(Water,self).__init__(name=name,**kwargs)
28
+ self._generate()
29
+
30
+ def _generate(self):
31
+ self['pore.molecular_weight'] = 0.01802 # kg/mol
32
+ self['pore.critical_pressure'] = 2.2064E7 # Pa
33
+ self['pore.critical_temperature'] = 647.1 # K
34
+ self['pore.critical_volume'] = 0.003106 # kg/m3
35
+ self['pore.contact_angle'] = 110.0 # Degree
36
+ self.models.add(propname='pore.density',
37
+ model=fm.density.water) # kg/m3
38
+ self.models.add(propname='pore.molar_density',
39
+ model=fm.molar_density.standard) # mol/m3
40
+ self['pore.diffusivity'] = 1e-9 # m2/s
41
+ self.models.add(propname='pore.surface_tension',
42
+ model=fm.surface_tension.water) # N/m
43
+ self.models.add(propname='pore.thermal_conductivity',
44
+ model=fm.thermal_conductivity.water) # W/m.K
45
+ self.models.add(propname='pore.vapor_pressure', # Pa
46
+ model=fm.vapor_pressure.antoine,
47
+ A=10.1965,
48
+ B=1730.63,
49
+ C=-39.720)
50
+ self.models.add(propname='pore.viscosity',
51
+ model=fm.viscosity.water) # kg/m.s
52
+
53
+ if __name__ =="__main__":
54
+ import OpenPNM
55
+ pn = OpenPNM.Network.TestNet()
56
+ water = OpenPNM.Phases.Water(network=pn)
@@ -0,0 +1,38 @@
1
+ r"""
2
+ ###############################################################################
3
+ :mod:`OpenPNM.Phases` -- Phase Property Estimation Methods
4
+ ###############################################################################
5
+
6
+ Contents
7
+ --------
8
+ GenericPhase: The basic class which defines how a Phase is instantiated. It
9
+ also has a few specific method for querying the health of mixtures or physics
10
+ objects.
11
+
12
+ Subclasses: OpenPNM includes a few pre-written subclasses that describe the
13
+ most commonly used materials, like Air, Water and Mercury. Creating a custom
14
+ Phase subclass simply requires placing a file in the Phases directory and it
15
+ will be automatically loaded.
16
+
17
+ Classes
18
+ -------
19
+
20
+ .. autoclass:: GenericPhase
21
+ :members:
22
+
23
+ .. autoclass:: Air
24
+ :members:
25
+
26
+ .. autoclass:: Water
27
+ :members:
28
+
29
+ .. autoclass:: Mercury
30
+ :members:
31
+
32
+ """
33
+ from .__GenericPhase__ import GenericPhase
34
+ from .__Air__ import Air
35
+ from .__Water__ import Water
36
+ from .__Mercury__ import Mercury
37
+ from .__TestPhase__ import TestPhase
38
+ from . import models
@@ -0,0 +1,22 @@
1
+ r"""
2
+ *******************************************************************************
3
+ models -- Functions for calculating thermofluid properties
4
+ *******************************************************************************
5
+
6
+ Contents
7
+ --------
8
+ This module contains methods for estimating phase properties
9
+
10
+ """
11
+
12
+ from . import contact_angle
13
+ from . import density
14
+ from . import diffusivity
15
+ from . import electrical_conductivity
16
+ from . import misc
17
+ from . import molar_density
18
+ from . import molar_mass
19
+ from . import surface_tension
20
+ from . import thermal_conductivity
21
+ from . import vapor_pressure
22
+ from . import viscosity
@@ -0,0 +1,34 @@
1
+ r"""
2
+ ===============================================================================
3
+ Submodule -- contact_angle
4
+ ===============================================================================
5
+
6
+ """
7
+ import scipy as sp
8
+
9
+ def young(phase,
10
+ sigma_sg,
11
+ sigma_sl,
12
+ surface_tension='pore.surface_tension',
13
+ **kwargs):
14
+ r'''
15
+ Calculate contact angle using Young's equation
16
+
17
+ Notes
18
+ -----
19
+ Young's equation is: sigma_lg*Cos(theta)=sigma_sg - sigma_sl
20
+ where
21
+ sigma_lg is the liquid-gas surface tension [N/m]
22
+ sigma_sg is the solid-gas surface tension [N/m]
23
+ sigma_sl is the solid-liquid interfacial tension [J/m^2]
24
+ theta is the Young contact angle [rad]
25
+
26
+ '''
27
+ if surface_tension.split('.')[0] == 'pore':
28
+ sigma = phase[surface_tension]
29
+ sigma = phase.interpolate_data(data=sigma)
30
+ else:
31
+ sigma = phase[surface_tension]
32
+ theta = sp.arccos((sigma_sg - sigma_sl)/phase[surface_tension])
33
+ theta = sp.rad2deg(theta)
34
+ return theta
@@ -0,0 +1,81 @@
1
+ r"""
2
+ ===============================================================================
3
+ Submodule -- density
4
+ ===============================================================================
5
+
6
+ """
7
+ import scipy as _sp
8
+
9
+ def standard(phase,**kwargs):
10
+ r'''
11
+ Calculates the mass density from the molecular weight and molar density
12
+ '''
13
+ MW = phase['pore.molecular_weight']
14
+ rho = phase['pore.molar_density']
15
+ value = rho*MW
16
+ return value
17
+
18
+ def ideal_gas(phase,**kwargs):
19
+ r"""
20
+ Uses ideal gas law to calculate the mass density of an ideal gas
21
+
22
+ Parameters
23
+ ----------
24
+ P, T, MW: float, array_like
25
+ P pressure of the gas in [Pa]
26
+ T temperature of the gas in [K]
27
+ MW molecular weight of the gas in [kg/kmole]
28
+
29
+ Returns
30
+ -------
31
+ rho, the density in [mol/m3]
32
+
33
+ """
34
+
35
+ P = phase['pore.pressure']
36
+ T = phase['pore.temperature']
37
+ MW = phase['pore.molecular_weight']
38
+ R = 8.31447
39
+ value = P/(R*T)*MW
40
+ return value
41
+
42
+ def water(phase,**kwargs):
43
+ r"""
44
+ Calculates density of pure water or seawater at atmospheric pressure
45
+ using Eq. (8) given by Sharqawy et. al [1]_. Values at temperature higher
46
+ than the normal boiling temperature are calculated at the saturation pressure.
47
+
48
+ Parameters
49
+ ----------
50
+ T, S: strings
51
+ Property names where phase temperature and salinity are located.
52
+
53
+ Returns
54
+ -------
55
+ rho_sw, the density of water/seawater in [kg/m3]
56
+
57
+ Notes
58
+ -----
59
+ T must be in K, and S in g of salt per kg of phase, or ppt (parts per
60
+ thousand)
61
+ VALIDITY: 273 < T < 453 K; 0 < S < 160 g/kg;
62
+ ACCURACY: 0.1 %
63
+
64
+ References
65
+ ----------
66
+ [1] Sharqawy M. H., Lienhard J. H., and Zubair, S. M., Desalination and Water Treatment, 2010.
67
+
68
+ """
69
+ T = phase['pore.temperature']
70
+ try:
71
+ S = phase['pore.salinity']
72
+ except:
73
+ S = 0
74
+ a1=9.9992293295E+02; a2=2.0341179217E-02; a3=-6.1624591598E-03; a4=2.2614664708E-05; a5=-4.6570659168E-08
75
+ b1=8.0200240891E-01; b2=-2.0005183488E-03; b3=1.6771024982E-05; b4=-3.0600536746E-08; b5=-1.6132224742E-11
76
+ TC = T-273.15
77
+ rho_w = a1 + a2*TC + a3*TC**2 + a4*TC**3 + a5*TC**4;
78
+ D_rho = b1*S + b2*S*TC + b3*S*(TC**2) + b4*S*(TC**3) + b5*(S**2)*(TC**2);
79
+ rho_sw = rho_w + D_rho
80
+ value = rho_sw
81
+ return value
@@ -0,0 +1,95 @@
1
+ r"""
2
+ ===============================================================================
3
+ Submodule -- diffusivity
4
+ ===============================================================================
5
+
6
+ """
7
+ import scipy as sp
8
+
9
+ def fuller(phase,MA,MB,vA,vB,**kwargs):
10
+ r"""
11
+ Uses Fuller model to estimate diffusion coefficient for gases from first
12
+ principles at conditions of interest
13
+
14
+ Parameters
15
+ ----------
16
+ MA : float, array_like
17
+ Molecular weight of component A [kg/mol]
18
+ MB : float, array_like
19
+ Molecular weight of component B [kg/mol]
20
+ vA: float, array_like
21
+ Sum of atomic diffusion volumes for component A
22
+ vB: float, array_like
23
+ Sum of atomic diffusion volumes for component B
24
+ """
25
+
26
+ T = phase['pore.temperature']
27
+ P = phase['pore.pressure']
28
+ MAB = 2*(1.0/MA+1.0/MB)**(-1)
29
+ MAB = MAB*1e3
30
+ P = P*1e-5
31
+ value = 0.00143*T**1.75/(P*(MAB**0.5)*(vA**(1./3)+vB**(1./3))**2)*1e-4
32
+ return value
33
+
34
+ def fuller_scaling(phase,DABo,To,Po,**kwargs):
35
+ r"""
36
+ Uses Fuller model to adjust a diffusion coefficient for gases from reference conditions to conditions of interest
37
+
38
+ Parameters
39
+ ----------
40
+ phase : OpenPNM Phase Object
41
+
42
+ DABo : float, array_like
43
+ Diffusion coefficient at reference conditions
44
+
45
+ Po, To : float, array_like
46
+ Pressure & temperature at reference conditions, respectively
47
+ """
48
+ Ti = phase['pore.temperature']
49
+ Pi = phase['pore.pressure']
50
+ value = DABo*(Ti/To)**1.75*(Po/Pi)
51
+ return value
52
+
53
+ def tyn_calus(phase,VA,VB,sigma_A,sigma_B,**kwargs):
54
+ r"""
55
+ Uses Tyn_Calus model to estimate diffusion coefficient in a dilute liquid solution of A in B from first principles at conditions of interest
56
+
57
+ Parameters
58
+ ----------
59
+ T : float, array_like
60
+ Temperature of interest (K)
61
+ viscosity : float, array_like
62
+ Viscosity of solvent (Pa.s)
63
+ VA : float, array_like
64
+ Molar volume of component A at boiling temperature (m3/mol)
65
+ VB : float, array_like
66
+ Molar volume of component B at boiling temperature (m3/mol)
67
+ sigmaA: float, array_like
68
+ Surface tension of component A at boiling temperature (N/m)
69
+ sigmaB: float, array_like
70
+ Surface tension of component B at boiling temperature (N/m)
71
+
72
+ """
73
+ T = phase['pore.temperature']
74
+ mu = phase['pore.viscosity']
75
+ value = 8.93e-8*(VB*1e6)**0.267/(VA*1e6)**0.433*T*(sigma_B/sigma_A)**0.15/(mu*1e3)
76
+ return value
77
+
78
+ def tyn_calus_Scaling(phase,DABo,To,mu_o,**kwargs):
79
+ r"""
80
+ Uses Tyn_Calus model to adjust a diffusion coeffciient for liquids from reference conditions to conditions of interest
81
+
82
+ Parameters
83
+ ----------
84
+ phase : OpenPNM Phase Object
85
+
86
+ DABo : float, array_like
87
+ Diffusion coefficient at reference conditions
88
+
89
+ mu_o, To : float, array_like
90
+ Viscosity & temperature at reference conditions, respectively
91
+ """
92
+ Ti = phase['pore.temperature']
93
+ mu_i = phase['pore.viscosity']
94
+ value = DABo*(Ti/To)*(mu_o/mu_i)
95
+ return value
@@ -0,0 +1,10 @@
1
+ r"""
2
+ ===============================================================================
3
+ Submodule -- electrical_conductance
4
+ ===============================================================================
5
+
6
+ """
7
+ import scipy as sp
8
+
9
+ def na(**kwargs):
10
+ print('Not Implemented Yet')