pyEQL 0.5.2__py3-none-any.whl → 1.1.0__py3-none-any.whl
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.
- pyEQL/__init__.py +50 -43
- pyEQL/activity_correction.py +481 -707
- pyEQL/database/geothermal.dat +5693 -0
- pyEQL/database/llnl.dat +19305 -0
- pyEQL/database/phreeqc_license.txt +54 -0
- pyEQL/database/pyeql_db.json +35902 -0
- pyEQL/engines.py +793 -0
- pyEQL/equilibrium.py +148 -228
- pyEQL/functions.py +121 -416
- pyEQL/pint_custom_units.txt +2 -2
- pyEQL/presets/Ringers lactate.yaml +20 -0
- pyEQL/presets/normal saline.yaml +17 -0
- pyEQL/presets/rainwater.yaml +17 -0
- pyEQL/presets/seawater.yaml +29 -0
- pyEQL/presets/urine.yaml +26 -0
- pyEQL/presets/wastewater.yaml +21 -0
- pyEQL/salt_ion_match.py +53 -284
- pyEQL/solute.py +126 -191
- pyEQL/solution.py +2163 -2090
- pyEQL/utils.py +165 -0
- pyEQL-1.1.0.dist-info/AUTHORS.md +13 -0
- {pyEQL-0.5.2.dist-info → pyEQL-1.1.0.dist-info}/COPYING +1 -1
- pyEQL-0.5.2.dist-info/LICENSE → pyEQL-1.1.0.dist-info/LICENSE.txt +3 -7
- pyEQL-1.1.0.dist-info/METADATA +129 -0
- pyEQL-1.1.0.dist-info/RECORD +27 -0
- {pyEQL-0.5.2.dist-info → pyEQL-1.1.0.dist-info}/WHEEL +2 -1
- pyEQL/chemical_formula.py +0 -1006
- pyEQL/database/Erying_viscosity.tsv +0 -18
- pyEQL/database/Jones_Dole_B.tsv +0 -32
- pyEQL/database/Jones_Dole_B_inorganic_Jenkins.tsv +0 -75
- pyEQL/database/LICENSE +0 -4
- pyEQL/database/dielectric_parameter.tsv +0 -30
- pyEQL/database/diffusion_coefficient.tsv +0 -116
- pyEQL/database/hydrated_radius.tsv +0 -35
- pyEQL/database/ionic_radius.tsv +0 -35
- pyEQL/database/partial_molar_volume.tsv +0 -22
- pyEQL/database/pitzer_activity.tsv +0 -169
- pyEQL/database/pitzer_volume.tsv +0 -132
- pyEQL/database/template.tsv +0 -14
- pyEQL/database.py +0 -300
- pyEQL/elements.py +0 -4552
- pyEQL/logging_system.py +0 -53
- pyEQL/parameter.py +0 -435
- pyEQL/tests/__init__.py +0 -32
- pyEQL/tests/test_activity.py +0 -578
- pyEQL/tests/test_bulk_properties.py +0 -86
- pyEQL/tests/test_chemical_formula.py +0 -279
- pyEQL/tests/test_debye_length.py +0 -79
- pyEQL/tests/test_density.py +0 -106
- pyEQL/tests/test_dielectric.py +0 -153
- pyEQL/tests/test_effective_pitzer.py +0 -276
- pyEQL/tests/test_mixed_electrolyte_activity.py +0 -154
- pyEQL/tests/test_osmotic_coeff.py +0 -99
- pyEQL/tests/test_pyeql_volume_concentration.py +0 -428
- pyEQL/tests/test_salt_matching.py +0 -337
- pyEQL/tests/test_solute_properties.py +0 -251
- pyEQL/water_properties.py +0 -352
- pyEQL-0.5.2.dist-info/AUTHORS +0 -7
- pyEQL-0.5.2.dist-info/METADATA +0 -72
- pyEQL-0.5.2.dist-info/RECORD +0 -47
- pyEQL-0.5.2.dist-info/entry_points.txt +0 -3
- {pyEQL-0.5.2.dist-info → pyEQL-1.1.0.dist-info}/top_level.txt +0 -0
|
@@ -1,279 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
chemical_formula.py test suite
|
|
3
|
-
==============================
|
|
4
|
-
|
|
5
|
-
This file contains tests for the chemical formula interpreter module of pyEQL.
|
|
6
|
-
"""
|
|
7
|
-
|
|
8
|
-
import pyEQL
|
|
9
|
-
from pyEQL import chemical_formula as cf
|
|
10
|
-
import unittest
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
class Test_check_formula(unittest.TestCase, pyEQL.CustomAssertions):
|
|
14
|
-
"""
|
|
15
|
-
tests for the _check_formula() function
|
|
16
|
-
---------------------------------------
|
|
17
|
-
This function is the core of the library and enforces the rules for
|
|
18
|
-
chemical formula formatting.
|
|
19
|
-
"""
|
|
20
|
-
|
|
21
|
-
def test_check_formula_1(self):
|
|
22
|
-
input = "Fe2(SO4)3"
|
|
23
|
-
result = cf._check_formula(input)
|
|
24
|
-
expected = ["Fe", "2", "(", "S", "O", "4", ")", "3"]
|
|
25
|
-
|
|
26
|
-
self.assertEqual(result, expected)
|
|
27
|
-
|
|
28
|
-
def test_check_formula_2(self):
|
|
29
|
-
input = "C7H16"
|
|
30
|
-
result = cf._check_formula(input)
|
|
31
|
-
expected = ["C", "7", "H", "16"]
|
|
32
|
-
|
|
33
|
-
self.assertEqual(result, expected)
|
|
34
|
-
|
|
35
|
-
def test_check_formula_3(self):
|
|
36
|
-
input = "(NH3)2SO4"
|
|
37
|
-
result = cf._check_formula(input)
|
|
38
|
-
expected = ["(", "N", "H", "3", ")", "2", "S", "O", "4"]
|
|
39
|
-
|
|
40
|
-
self.assertEqual(result, expected)
|
|
41
|
-
|
|
42
|
-
def test_check_formula_4(self):
|
|
43
|
-
input = "MgCl2"
|
|
44
|
-
result = cf._check_formula(input)
|
|
45
|
-
expected = ["Mg", "Cl", "2"]
|
|
46
|
-
|
|
47
|
-
self.assertEqual(result, expected)
|
|
48
|
-
|
|
49
|
-
def test_check_formula_5(self):
|
|
50
|
-
input = "C100H202"
|
|
51
|
-
result = cf._check_formula(input)
|
|
52
|
-
expected = ["C", "100", "H", "202"]
|
|
53
|
-
|
|
54
|
-
self.assertEqual(result, expected)
|
|
55
|
-
|
|
56
|
-
def test_check_formula_6(self):
|
|
57
|
-
input = "Fe+++"
|
|
58
|
-
result = cf._check_formula(input)
|
|
59
|
-
expected = ["Fe", "+++"]
|
|
60
|
-
|
|
61
|
-
self.assertEqual(result, expected)
|
|
62
|
-
|
|
63
|
-
def test_check_formula_7(self):
|
|
64
|
-
input = "V+4"
|
|
65
|
-
result = cf._check_formula(input)
|
|
66
|
-
expected = ["V", "+", "4"]
|
|
67
|
-
|
|
68
|
-
self.assertEqual(result, expected)
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
# def test_choice(self):
|
|
72
|
-
# element = random.choice(self.seq)
|
|
73
|
-
# self.assertTrue(element in self.seq)
|
|
74
|
-
#
|
|
75
|
-
# def test_sample(self):
|
|
76
|
-
# with self.assertRaises(ValueError):
|
|
77
|
-
# random.sample(self.seq, 20)
|
|
78
|
-
# for element in random.sample(self.seq, 5):
|
|
79
|
-
# self.assertTrue(element in self.seq)
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
class Test_is_valid_formula(unittest.TestCase, pyEQL.CustomAssertions):
|
|
83
|
-
"""
|
|
84
|
-
tests for is_valid_formula()
|
|
85
|
-
----------------------------
|
|
86
|
-
"""
|
|
87
|
-
|
|
88
|
-
# A formula must start with a letter or an open parenthesis
|
|
89
|
-
def test_is_valid_formula_1(self):
|
|
90
|
-
input = "(NH3)2"
|
|
91
|
-
result = cf.is_valid_formula(input)
|
|
92
|
-
expected = True
|
|
93
|
-
|
|
94
|
-
self.assertEqual(result, expected)
|
|
95
|
-
|
|
96
|
-
# A formula must start with a letter or an open parenthesis
|
|
97
|
-
def test_is_valid_formula_2(self):
|
|
98
|
-
input = "3CO3-"
|
|
99
|
-
result = cf.is_valid_formula(input)
|
|
100
|
-
expected = False
|
|
101
|
-
|
|
102
|
-
self.assertEqual(result, expected)
|
|
103
|
-
|
|
104
|
-
# A formula cannot contain any non-alphanumeric characters beside '(', ')', '+', and '-'
|
|
105
|
-
def test_is_valid_formula_3(self):
|
|
106
|
-
input = "Na^+"
|
|
107
|
-
result = cf.is_valid_formula(input)
|
|
108
|
-
expected = False
|
|
109
|
-
|
|
110
|
-
self.assertEqual(result, expected)
|
|
111
|
-
|
|
112
|
-
# A formula cannot contain both '+' and '-'
|
|
113
|
-
def test_is_valid_formula_4(self):
|
|
114
|
-
input = "Na+-+"
|
|
115
|
-
result = cf.is_valid_formula(input)
|
|
116
|
-
expected = False
|
|
117
|
-
|
|
118
|
-
self.assertEqual(result, expected)
|
|
119
|
-
|
|
120
|
-
# An ionic formula must end with either a number, a '+', or a '-'
|
|
121
|
-
def test_is_valid_formula_5(self):
|
|
122
|
-
input = "HCO3-"
|
|
123
|
-
result = cf.is_valid_formula(input)
|
|
124
|
-
expected = True
|
|
125
|
-
|
|
126
|
-
self.assertEqual(result, expected)
|
|
127
|
-
|
|
128
|
-
# An ionic formula must end with either a number, a '+', or a '-'
|
|
129
|
-
def test_is_valid_formula_6(self):
|
|
130
|
-
input = "Fe++"
|
|
131
|
-
result = cf.is_valid_formula(input)
|
|
132
|
-
expected = True
|
|
133
|
-
|
|
134
|
-
self.assertEqual(result, expected)
|
|
135
|
-
|
|
136
|
-
# An ionic formula must end with either a number, a '+', or a '-'
|
|
137
|
-
def test_is_valid_formula_7(self):
|
|
138
|
-
input = "Mg+2"
|
|
139
|
-
result = cf.is_valid_formula(input)
|
|
140
|
-
expected = True
|
|
141
|
-
|
|
142
|
-
self.assertEqual(result, expected)
|
|
143
|
-
|
|
144
|
-
# An ionic formula must end with either a number, a '+', or a '-'
|
|
145
|
-
def test_is_valid_formula_8(self):
|
|
146
|
-
input = "V+5+"
|
|
147
|
-
result = cf.is_valid_formula(input)
|
|
148
|
-
expected = False
|
|
149
|
-
|
|
150
|
-
self.assertEqual(result, expected)
|
|
151
|
-
|
|
152
|
-
# Formulas must contain only valid atomic symbols that start with capital letters
|
|
153
|
-
def test_is_valid_formula_9(self):
|
|
154
|
-
input = "NaOH"
|
|
155
|
-
result = cf.is_valid_formula(input)
|
|
156
|
-
expected = True
|
|
157
|
-
|
|
158
|
-
self.assertEqual(result, expected)
|
|
159
|
-
|
|
160
|
-
# Formulas must contain only valid atomic symbols that start with capital letters
|
|
161
|
-
def test_is_valid_formula_9(self):
|
|
162
|
-
input = "naOH"
|
|
163
|
-
result = cf.is_valid_formula(input)
|
|
164
|
-
expected = False
|
|
165
|
-
|
|
166
|
-
self.assertEqual(result, expected)
|
|
167
|
-
|
|
168
|
-
# Formulas must contain only valid atomic symbols that start with capital letters
|
|
169
|
-
def test_is_valid_formula_10(self):
|
|
170
|
-
input = "HzCl"
|
|
171
|
-
result = cf.is_valid_formula(input)
|
|
172
|
-
expected = False
|
|
173
|
-
|
|
174
|
-
self.assertEqual(result, expected)
|
|
175
|
-
|
|
176
|
-
# A formula with parentheses must have the same number of '(' and ')'
|
|
177
|
-
def test_is_valid_formula_11(self):
|
|
178
|
-
input = "(NH3)2(NO3)2"
|
|
179
|
-
result = cf.is_valid_formula(input)
|
|
180
|
-
expected = True
|
|
181
|
-
|
|
182
|
-
self.assertEqual(result, expected)
|
|
183
|
-
|
|
184
|
-
# A formula with parentheses must have the same number of '(' and ')'
|
|
185
|
-
def test_is_valid_formula_12(self):
|
|
186
|
-
input = "Mg)(OH)2"
|
|
187
|
-
result = cf.is_valid_formula(input)
|
|
188
|
-
expected = False
|
|
189
|
-
|
|
190
|
-
self.assertEqual(result, expected)
|
|
191
|
-
|
|
192
|
-
# A formula cannot end with an open parenthesis
|
|
193
|
-
def test_is_valid_formula_13(self):
|
|
194
|
-
input = "Na+("
|
|
195
|
-
result = cf.is_valid_formula(input)
|
|
196
|
-
expected = False
|
|
197
|
-
|
|
198
|
-
self.assertEqual(result, expected)
|
|
199
|
-
|
|
200
|
-
# An open parenthesis must always be followed by an atomic symbol
|
|
201
|
-
def test_is_valid_formula_14(self):
|
|
202
|
-
input = "(3)Na+"
|
|
203
|
-
result = cf.is_valid_formula(input)
|
|
204
|
-
expected = False
|
|
205
|
-
|
|
206
|
-
self.assertEqual(result, expected)
|
|
207
|
-
|
|
208
|
-
# An open parenthesis must always be followed by an atomic symbol
|
|
209
|
-
def test_is_valid_formula_15(self):
|
|
210
|
-
input = "()"
|
|
211
|
-
result = cf.is_valid_formula(input)
|
|
212
|
-
expected = False
|
|
213
|
-
|
|
214
|
-
self.assertEqual(result, expected)
|
|
215
|
-
|
|
216
|
-
# A closed parenthesis may be followed by a number or used to designate a group
|
|
217
|
-
def test_is_valid_formula_16(self):
|
|
218
|
-
input = "CH3C(O)CH3"
|
|
219
|
-
result = cf.is_valid_formula(input)
|
|
220
|
-
expected = True
|
|
221
|
-
|
|
222
|
-
self.assertEqual(result, expected)
|
|
223
|
-
|
|
224
|
-
# A closed parenthesis may be followed by a number or used to designate a group
|
|
225
|
-
def test_is_valid_formula_17(self):
|
|
226
|
-
input = "Mg(OH)2"
|
|
227
|
-
result = cf.is_valid_formula(input)
|
|
228
|
-
expected = True
|
|
229
|
-
|
|
230
|
-
self.assertEqual(result, expected)
|
|
231
|
-
|
|
232
|
-
# An open parenthesis must always precede the nearest closed parenthesis
|
|
233
|
-
def test_is_valid_formula_17(self):
|
|
234
|
-
input = "CH3(CH)2(CH)2"
|
|
235
|
-
result = cf.is_valid_formula(input)
|
|
236
|
-
expected = True
|
|
237
|
-
|
|
238
|
-
self.assertEqual(result, expected)
|
|
239
|
-
|
|
240
|
-
# An open parenthesis must always precede the nearest closed parenthesis
|
|
241
|
-
def test_is_valid_formula_18(self):
|
|
242
|
-
input = ")Na+("
|
|
243
|
-
result = cf.is_valid_formula(input)
|
|
244
|
-
expected = False
|
|
245
|
-
|
|
246
|
-
self.assertEqual(result, expected)
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
class Test_consolidate_formula(unittest.TestCase, pyEQL.CustomAssertions):
|
|
250
|
-
"""
|
|
251
|
-
tests for _consolidate_formula()
|
|
252
|
-
--------------------------------
|
|
253
|
-
This function is important for calculating molecular weights correctly
|
|
254
|
-
"""
|
|
255
|
-
|
|
256
|
-
def test_is_valid_formula_1(self):
|
|
257
|
-
input = "Fe2(SO4)4"
|
|
258
|
-
result = cf._consolidate_formula(input)
|
|
259
|
-
expected = ["Fe", 2, "S", 4, "O", 16]
|
|
260
|
-
|
|
261
|
-
self.assertEqual(result, expected)
|
|
262
|
-
|
|
263
|
-
def test_is_valid_formula_2(self):
|
|
264
|
-
input = "(NH4)3PO4"
|
|
265
|
-
result = cf._consolidate_formula(input)
|
|
266
|
-
expected = ["N", 3, "H", 12, "P", 1, "O", 4]
|
|
267
|
-
|
|
268
|
-
self.assertEqual(result, expected)
|
|
269
|
-
|
|
270
|
-
def test_is_valid_formula_3(self):
|
|
271
|
-
input = "CH3(CH2)6CH3"
|
|
272
|
-
result = cf._consolidate_formula(input)
|
|
273
|
-
expected = ["C", 8, "H", 18]
|
|
274
|
-
|
|
275
|
-
self.assertEqual(result, expected)
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
if __name__ == "__main__":
|
|
279
|
-
unittest.main()
|
pyEQL/tests/test_debye_length.py
DELETED
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
pyEQL debye length test suite
|
|
3
|
-
============================================
|
|
4
|
-
|
|
5
|
-
This file contains tests that check the Debye Length
|
|
6
|
-
computations of pyEQL
|
|
7
|
-
|
|
8
|
-
"""
|
|
9
|
-
|
|
10
|
-
import pyEQL
|
|
11
|
-
import unittest
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
class Test_debye_length(unittest.TestCase, pyEQL.CustomAssertions):
|
|
15
|
-
"""
|
|
16
|
-
test the Debye Length calculations of various solutions
|
|
17
|
-
------------------------------------------------
|
|
18
|
-
|
|
19
|
-
Reference: [1] M. Hu, B. Mi, Enabling graphene oxide nanosheets as water separation membranes,
|
|
20
|
-
Environ. Sci. Technol. 47 (2013) 3715–3723. doi:10.1021/es400571g.
|
|
21
|
-
|
|
22
|
-
0.1 mM NaCl: 31nm
|
|
23
|
-
10 mM NaCl: 3.1 nm
|
|
24
|
-
0.1 mM Na2SO4: 18nm
|
|
25
|
-
10 mM Na2SO4: 1.8nm
|
|
26
|
-
|
|
27
|
-
"""
|
|
28
|
-
|
|
29
|
-
def setUp(self):
|
|
30
|
-
# relative error tolerance for assertWithinExperimentalError
|
|
31
|
-
self.tol = 0.03
|
|
32
|
-
|
|
33
|
-
def test_debye_length_1(self):
|
|
34
|
-
"""
|
|
35
|
-
|
|
36
|
-
"""
|
|
37
|
-
s1 = pyEQL.Solution([["Na+", "0.1 mmol/L"], ["Cl-", "0.1 mmol/L"]])
|
|
38
|
-
|
|
39
|
-
result = s1.get_debye_length().magnitude
|
|
40
|
-
expected = 31
|
|
41
|
-
|
|
42
|
-
self.assertWithinExperimentalError(result, expected, self.tol)
|
|
43
|
-
|
|
44
|
-
def test_debye_length_2(self):
|
|
45
|
-
"""
|
|
46
|
-
|
|
47
|
-
"""
|
|
48
|
-
s1 = pyEQL.Solution([["Na+", "10 mmol/L"], ["Cl-", "10 mmol/L"]])
|
|
49
|
-
|
|
50
|
-
result = s1.get_debye_length().magnitude
|
|
51
|
-
expected = 3.1
|
|
52
|
-
|
|
53
|
-
self.assertWithinExperimentalError(result, expected, self.tol)
|
|
54
|
-
|
|
55
|
-
def test_debye_length_3(self):
|
|
56
|
-
"""
|
|
57
|
-
|
|
58
|
-
"""
|
|
59
|
-
s1 = pyEQL.Solution([["Na+", "0.2 mmol/L"], ["SO4-2", "0.1 mmol/L"]])
|
|
60
|
-
|
|
61
|
-
result = s1.get_debye_length().magnitude
|
|
62
|
-
expected = 18
|
|
63
|
-
|
|
64
|
-
self.assertWithinExperimentalError(result, expected, self.tol)
|
|
65
|
-
|
|
66
|
-
def test_debye_length_4(self):
|
|
67
|
-
"""
|
|
68
|
-
|
|
69
|
-
"""
|
|
70
|
-
s1 = pyEQL.Solution([["Na+", "20 mmol/L"], ["SO4-2", "10 mmol/L"]])
|
|
71
|
-
|
|
72
|
-
result = s1.get_debye_length().magnitude
|
|
73
|
-
expected = 1.8
|
|
74
|
-
|
|
75
|
-
self.assertWithinExperimentalError(result, expected, self.tol)
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
if __name__ == "__main__":
|
|
79
|
-
unittest.main()
|
pyEQL/tests/test_density.py
DELETED
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
pyEQL density test suite
|
|
3
|
-
============================================
|
|
4
|
-
|
|
5
|
-
This file contains tests that check the density of electrolyte solutions
|
|
6
|
-
that are computed using the Pitzer model to get partial molar volumes.
|
|
7
|
-
|
|
8
|
-
NOTE: generally, these tests check the module output against experimental
|
|
9
|
-
data rather than the theoretical result of the respective functions. In some
|
|
10
|
-
cases, the output is also tested against a well-established model published
|
|
11
|
-
by USGS(PHREEQC)
|
|
12
|
-
"""
|
|
13
|
-
|
|
14
|
-
import pyEQL
|
|
15
|
-
import unittest
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
class Test_density_nacl(unittest.TestCase, pyEQL.CustomAssertions):
|
|
19
|
-
"""
|
|
20
|
-
test Pitzer model for density of NaCl
|
|
21
|
-
------------------------------------------------
|
|
22
|
-
"""
|
|
23
|
-
|
|
24
|
-
def setUp(self):
|
|
25
|
-
# relative error tolerance for assertWithinExperimentalError
|
|
26
|
-
self.tol = 0.01
|
|
27
|
-
|
|
28
|
-
def test_density_pitzer_nacl_1(self):
|
|
29
|
-
"""
|
|
30
|
-
calculate the density at each concentration and compare
|
|
31
|
-
to experimental data
|
|
32
|
-
|
|
33
|
-
Published density values at 25 degC over a range of NaCl concentrations up
|
|
34
|
-
to saturation are found in J. Phys. Chem. Reference Data Vol 13 (1), 1984, p.84
|
|
35
|
-
|
|
36
|
-
"""
|
|
37
|
-
# list of concentrations to test, mol/kg
|
|
38
|
-
conc_list = [0.1, 0.25, 0.5, 0.75, 1, 2, 3, 4, 5, 6]
|
|
39
|
-
|
|
40
|
-
# list of published experimental densities
|
|
41
|
-
pub_density = [
|
|
42
|
-
1.00117,
|
|
43
|
-
1.00722,
|
|
44
|
-
1.01710,
|
|
45
|
-
1.02676,
|
|
46
|
-
1.03623,
|
|
47
|
-
1.07228,
|
|
48
|
-
1.10577,
|
|
49
|
-
1.13705,
|
|
50
|
-
1.16644,
|
|
51
|
-
1.1942,
|
|
52
|
-
]
|
|
53
|
-
|
|
54
|
-
for i in range(len(conc_list)):
|
|
55
|
-
with self.subTest(conc=conc_list[i]):
|
|
56
|
-
conc = str(conc_list[i]) + "mol/kg"
|
|
57
|
-
sol = pyEQL.Solution()
|
|
58
|
-
sol.add_solute("Na+", conc)
|
|
59
|
-
sol.add_solute("Cl-", conc)
|
|
60
|
-
result = sol.get_density().to("g/mL").magnitude
|
|
61
|
-
expected = pub_density[i]
|
|
62
|
-
|
|
63
|
-
self.assertWithinExperimentalError(result, expected, self.tol)
|
|
64
|
-
|
|
65
|
-
def test_density_pitzer_nacl_phreeqc_1(self):
|
|
66
|
-
"""
|
|
67
|
-
calculate the density at each concentration and compare
|
|
68
|
-
to the output of the PHREEQC model
|
|
69
|
-
|
|
70
|
-
PHREEQC version 3.1.4 was used to calculate density, conductivity, water
|
|
71
|
-
activity, and NaCl activity coefficient for NaCl solutions up to 6m.
|
|
72
|
-
The Pitzer model (pitzer.dat) database was used.
|
|
73
|
-
<http://wwwbrr.cr.usgs.gov/projects/GWC_coupled/phreeqc/>
|
|
74
|
-
|
|
75
|
-
"""
|
|
76
|
-
# list of concentrations to test, mol/kg
|
|
77
|
-
conc_list = [0.1, 0.25, 0.5, 0.75, 1, 2, 3, 4, 5, 6]
|
|
78
|
-
|
|
79
|
-
# list of modeled densities
|
|
80
|
-
phreeqc_pitzer_density = [
|
|
81
|
-
1.00115,
|
|
82
|
-
1.00718,
|
|
83
|
-
1.01702,
|
|
84
|
-
1.02664,
|
|
85
|
-
1.03606,
|
|
86
|
-
1.07204,
|
|
87
|
-
1.10562,
|
|
88
|
-
1.13705,
|
|
89
|
-
1.16651,
|
|
90
|
-
1.19417,
|
|
91
|
-
]
|
|
92
|
-
|
|
93
|
-
for i in range(len(conc_list)):
|
|
94
|
-
with self.subTest(conc=conc_list[i]):
|
|
95
|
-
conc = str(conc_list[i]) + "mol/kg"
|
|
96
|
-
sol = pyEQL.Solution()
|
|
97
|
-
sol.add_solute("Na+", conc)
|
|
98
|
-
sol.add_solute("Cl-", conc)
|
|
99
|
-
result = sol.get_density().to("g/mL").magnitude
|
|
100
|
-
expected = phreeqc_pitzer_density[i]
|
|
101
|
-
|
|
102
|
-
self.assertWithinExperimentalError(result, expected, self.tol)
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
if __name__ == "__main__":
|
|
106
|
-
unittest.main()
|
pyEQL/tests/test_dielectric.py
DELETED
|
@@ -1,153 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
pyEQL dielectric constant test suite
|
|
3
|
-
============================================
|
|
4
|
-
|
|
5
|
-
This file contains tests that check the dielectric constant
|
|
6
|
-
computations of pyEQL
|
|
7
|
-
|
|
8
|
-
"""
|
|
9
|
-
|
|
10
|
-
import pyEQL
|
|
11
|
-
import unittest
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
class Test_dielectric(unittest.TestCase, pyEQL.CustomAssertions):
|
|
15
|
-
"""
|
|
16
|
-
test the Dielectric Constant calculations of various solutions
|
|
17
|
-
------------------------------------------------
|
|
18
|
-
|
|
19
|
-
Reference: A. Zuber, L. Cardozo-Filho, V.F. Cabral, R.F. Checoni, M. Castier, An empirical equation for the
|
|
20
|
-
dielectric constant in aqueous and nonaqueous electrolyte mixtures, Fluid Phase Equilib. 376 (2014) 116–123.
|
|
21
|
-
doi:10.1016/j.fluid.2014.05.037.
|
|
22
|
-
|
|
23
|
-
"""
|
|
24
|
-
|
|
25
|
-
def setUp(self):
|
|
26
|
-
# relative error tolerance for assertWithinExperimentalError
|
|
27
|
-
self.tol = 0.01
|
|
28
|
-
|
|
29
|
-
def test_dielectric_constant(self):
|
|
30
|
-
"""
|
|
31
|
-
4.4 mol/kg NaCl = 46
|
|
32
|
-
"""
|
|
33
|
-
s1 = pyEQL.Solution([["Na+", "4.4 mol/kg"], ["Cl-", "4.4 mol/kg"]])
|
|
34
|
-
|
|
35
|
-
result = s1.get_dielectric_constant().magnitude
|
|
36
|
-
expected = 46
|
|
37
|
-
|
|
38
|
-
self.assertWithinExperimentalError(result, expected, self.tol)
|
|
39
|
-
|
|
40
|
-
def test_dielectric_constant2(self):
|
|
41
|
-
"""
|
|
42
|
-
2 mol/kg NaCl = 58
|
|
43
|
-
"""
|
|
44
|
-
s1 = pyEQL.Solution([["Na+", "2 mol/kg"], ["Cl-", "2 mol/kg"]])
|
|
45
|
-
|
|
46
|
-
result = s1.get_dielectric_constant().magnitude
|
|
47
|
-
expected = 58
|
|
48
|
-
|
|
49
|
-
self.assertWithinExperimentalError(result, expected, self.tol)
|
|
50
|
-
|
|
51
|
-
def test_dielectric_constant3(self):
|
|
52
|
-
"""
|
|
53
|
-
1 mol/kg NaCl = 66
|
|
54
|
-
"""
|
|
55
|
-
s1 = pyEQL.Solution([["Na+", "1 mol/kg"], ["Cl-", "1 mol/kg"]])
|
|
56
|
-
|
|
57
|
-
result = s1.get_dielectric_constant().magnitude
|
|
58
|
-
expected = 66
|
|
59
|
-
|
|
60
|
-
self.assertWithinExperimentalError(result, expected, self.tol)
|
|
61
|
-
|
|
62
|
-
def test_dielectric_constant4(self):
|
|
63
|
-
"""
|
|
64
|
-
1 mol/kg KBr = 67
|
|
65
|
-
"""
|
|
66
|
-
s1 = pyEQL.Solution([["K+", "1 mol/kg"], ["Br-", "1 mol/kg"]])
|
|
67
|
-
|
|
68
|
-
result = s1.get_dielectric_constant().magnitude
|
|
69
|
-
expected = 67
|
|
70
|
-
|
|
71
|
-
self.assertWithinExperimentalError(result, expected, self.tol)
|
|
72
|
-
|
|
73
|
-
def test_dielectric_constant5(self):
|
|
74
|
-
"""
|
|
75
|
-
3.4 mol/kg KBr = 51
|
|
76
|
-
"""
|
|
77
|
-
s1 = pyEQL.Solution([["K+", "3.4 mol/kg"], ["Br-", "3.4 mol/kg"]])
|
|
78
|
-
|
|
79
|
-
result = s1.get_dielectric_constant().magnitude
|
|
80
|
-
expected = 51
|
|
81
|
-
|
|
82
|
-
self.assertWithinExperimentalError(result, expected, self.tol)
|
|
83
|
-
|
|
84
|
-
def test_dielectric_constant6(self):
|
|
85
|
-
"""
|
|
86
|
-
5 mol/kg LiCl = 39
|
|
87
|
-
"""
|
|
88
|
-
s1 = pyEQL.Solution([["Li+", "5 mol/kg"], ["Cl-", "5 mol/kg"]])
|
|
89
|
-
|
|
90
|
-
result = s1.get_dielectric_constant().magnitude
|
|
91
|
-
expected = 39
|
|
92
|
-
|
|
93
|
-
self.assertWithinExperimentalError(result, expected, self.tol)
|
|
94
|
-
|
|
95
|
-
def test_dielectric_constant7(self):
|
|
96
|
-
"""
|
|
97
|
-
1 mol/kg LiCl = 64
|
|
98
|
-
"""
|
|
99
|
-
s1 = pyEQL.Solution([["Li+", "1 mol/kg"], ["Cl-", "1 mol/kg"]])
|
|
100
|
-
|
|
101
|
-
result = s1.get_dielectric_constant().magnitude
|
|
102
|
-
expected = 64
|
|
103
|
-
|
|
104
|
-
self.assertWithinExperimentalError(result, expected, self.tol)
|
|
105
|
-
|
|
106
|
-
@unittest.expectedFailure
|
|
107
|
-
def test_dielectric_constant8(self):
|
|
108
|
-
"""
|
|
109
|
-
12 mol/kg LiCl = 24
|
|
110
|
-
"""
|
|
111
|
-
s1 = pyEQL.Solution([["Li+", "12 mol/kg"], ["Cl-", "12 mol/kg"]])
|
|
112
|
-
|
|
113
|
-
result = s1.get_dielectric_constant().magnitude
|
|
114
|
-
expected = 24
|
|
115
|
-
|
|
116
|
-
self.assertWithinExperimentalError(result, expected, self.tol)
|
|
117
|
-
|
|
118
|
-
def test_dielectric_constant9(self):
|
|
119
|
-
"""
|
|
120
|
-
6.5 mol/kg RbCl = 43
|
|
121
|
-
"""
|
|
122
|
-
s1 = pyEQL.Solution([["Rb+", "6.5 mol/kg"], ["Cl-", "6.5 mol/kg"]])
|
|
123
|
-
|
|
124
|
-
result = s1.get_dielectric_constant().magnitude
|
|
125
|
-
expected = 43
|
|
126
|
-
|
|
127
|
-
self.assertWithinExperimentalError(result, expected, self.tol)
|
|
128
|
-
|
|
129
|
-
def test_dielectric_constant9(self):
|
|
130
|
-
"""
|
|
131
|
-
2.1 mol/kg RbCl = 59
|
|
132
|
-
"""
|
|
133
|
-
s1 = pyEQL.Solution([["Rb+", "2.1 mol/kg"], ["Cl-", "2.1 mol/kg"]])
|
|
134
|
-
|
|
135
|
-
result = s1.get_dielectric_constant().magnitude
|
|
136
|
-
expected = 59
|
|
137
|
-
|
|
138
|
-
self.assertWithinExperimentalError(result, expected, self.tol)
|
|
139
|
-
|
|
140
|
-
def test_dielectric_constant9(self):
|
|
141
|
-
"""
|
|
142
|
-
0.5 mol/kg RbCl = 73
|
|
143
|
-
"""
|
|
144
|
-
s1 = pyEQL.Solution([["Rb+", "0.5 mol/kg"], ["Cl-", "0.5 mol/kg"]])
|
|
145
|
-
|
|
146
|
-
result = s1.get_dielectric_constant().magnitude
|
|
147
|
-
expected = 73
|
|
148
|
-
|
|
149
|
-
self.assertWithinExperimentalError(result, expected, self.tol)
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
if __name__ == "__main__":
|
|
153
|
-
unittest.main()
|