pyEQL 0.5.2__py3-none-any.whl → 1.0.3__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.
Files changed (62) hide show
  1. pyEQL/__init__.py +50 -43
  2. pyEQL/activity_correction.py +481 -707
  3. pyEQL/database/geothermal.dat +5693 -0
  4. pyEQL/database/llnl.dat +19305 -0
  5. pyEQL/database/phreeqc_license.txt +54 -0
  6. pyEQL/database/pyeql_db.json +35902 -0
  7. pyEQL/engines.py +793 -0
  8. pyEQL/equilibrium.py +148 -228
  9. pyEQL/functions.py +121 -416
  10. pyEQL/pint_custom_units.txt +2 -2
  11. pyEQL/presets/Ringers lactate.yaml +20 -0
  12. pyEQL/presets/normal saline.yaml +17 -0
  13. pyEQL/presets/rainwater.yaml +17 -0
  14. pyEQL/presets/seawater.yaml +29 -0
  15. pyEQL/presets/urine.yaml +26 -0
  16. pyEQL/presets/wastewater.yaml +21 -0
  17. pyEQL/salt_ion_match.py +53 -284
  18. pyEQL/solute.py +126 -191
  19. pyEQL/solution.py +2163 -2090
  20. pyEQL/utils.py +211 -0
  21. pyEQL-1.0.3.dist-info/AUTHORS.md +13 -0
  22. {pyEQL-0.5.2.dist-info → pyEQL-1.0.3.dist-info}/COPYING +1 -1
  23. pyEQL-0.5.2.dist-info/LICENSE → pyEQL-1.0.3.dist-info/LICENSE.txt +3 -7
  24. pyEQL-1.0.3.dist-info/METADATA +131 -0
  25. pyEQL-1.0.3.dist-info/RECORD +27 -0
  26. {pyEQL-0.5.2.dist-info → pyEQL-1.0.3.dist-info}/WHEEL +1 -1
  27. pyEQL/chemical_formula.py +0 -1006
  28. pyEQL/database/Erying_viscosity.tsv +0 -18
  29. pyEQL/database/Jones_Dole_B.tsv +0 -32
  30. pyEQL/database/Jones_Dole_B_inorganic_Jenkins.tsv +0 -75
  31. pyEQL/database/LICENSE +0 -4
  32. pyEQL/database/dielectric_parameter.tsv +0 -30
  33. pyEQL/database/diffusion_coefficient.tsv +0 -116
  34. pyEQL/database/hydrated_radius.tsv +0 -35
  35. pyEQL/database/ionic_radius.tsv +0 -35
  36. pyEQL/database/partial_molar_volume.tsv +0 -22
  37. pyEQL/database/pitzer_activity.tsv +0 -169
  38. pyEQL/database/pitzer_volume.tsv +0 -132
  39. pyEQL/database/template.tsv +0 -14
  40. pyEQL/database.py +0 -300
  41. pyEQL/elements.py +0 -4552
  42. pyEQL/logging_system.py +0 -53
  43. pyEQL/parameter.py +0 -435
  44. pyEQL/tests/__init__.py +0 -32
  45. pyEQL/tests/test_activity.py +0 -578
  46. pyEQL/tests/test_bulk_properties.py +0 -86
  47. pyEQL/tests/test_chemical_formula.py +0 -279
  48. pyEQL/tests/test_debye_length.py +0 -79
  49. pyEQL/tests/test_density.py +0 -106
  50. pyEQL/tests/test_dielectric.py +0 -153
  51. pyEQL/tests/test_effective_pitzer.py +0 -276
  52. pyEQL/tests/test_mixed_electrolyte_activity.py +0 -154
  53. pyEQL/tests/test_osmotic_coeff.py +0 -99
  54. pyEQL/tests/test_pyeql_volume_concentration.py +0 -428
  55. pyEQL/tests/test_salt_matching.py +0 -337
  56. pyEQL/tests/test_solute_properties.py +0 -251
  57. pyEQL/water_properties.py +0 -352
  58. pyEQL-0.5.2.dist-info/AUTHORS +0 -7
  59. pyEQL-0.5.2.dist-info/METADATA +0 -72
  60. pyEQL-0.5.2.dist-info/RECORD +0 -47
  61. pyEQL-0.5.2.dist-info/entry_points.txt +0 -3
  62. {pyEQL-0.5.2.dist-info → pyEQL-1.0.3.dist-info}/top_level.txt +0 -0
@@ -1,578 +0,0 @@
1
- """
2
- pyEQL activity correction methods test suite
3
- ============================================
4
-
5
- This file contains tests for some of the activity correction methods
6
- employed by pyEQL.
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_activity_pitzer_nacl(unittest.TestCase, pyEQL.CustomAssertions):
19
- """
20
- test Pitzer model for activity of NaCl
21
- ------------------------------------------------
22
- """
23
-
24
- def setUp(self):
25
- self.s1 = pyEQL.Solution([["Na+", "0.1 mol/L"], ["Cl-", "0.1 mol/L"]])
26
-
27
- # relative error tolerance for assertWithinExperimentalError
28
- self.tol = 0.05
29
-
30
- def test_activity_pitzer_coeff_units(self):
31
- # the activity coefficient should be dimensionless
32
- result = self.s1.get_activity_coefficient("Na+").dimensionality
33
- self.assertEqual(result, "")
34
-
35
- def test_activity_pitzer_units(self):
36
- # the activity should be dimensionless
37
- result = self.s1.get_activity("Na+").dimensionality
38
- self.assertEqual(result, "")
39
-
40
- def test_activity_pitzer_equality(self):
41
- # the activity coefficient of both the Na+ and Cl- should be the same
42
- a1 = self.s1.get_activity_coefficient("Na+")
43
- a2 = self.s1.get_activity_coefficient("Cl-")
44
- self.assertEqual(a1, a2)
45
-
46
- def test_activity_crc_HCl(self):
47
- """
48
- calculate the activity coefficient of HCl at each concentration and compare
49
- to experimental data
50
-
51
- Experimental activity coefficient values at 25 degC are found in
52
- *CRC Handbook of Chemistry and Physics*, Mean Activity Coefficients of Electrolytes as a Function of
53
- Concentration, in: W.M. Haynes (Ed.), 92nd ed., 2011.
54
-
55
- """
56
- cation = "H+"
57
- nu_cation = 1
58
- anion = "Cl-"
59
- nu_anion = 1
60
-
61
- # list of concentrations to test, mol/kg
62
- conc_list = [0.001, 0.002, 0.005, 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5]
63
-
64
- # list of published experimental activity coefficients
65
- pub_activity_coeff = [
66
- 0.965,
67
- 0.952,
68
- 0.929,
69
- 0.905,
70
- 0.876,
71
- 0.832,
72
- 0.797,
73
- 0.768,
74
- 0.759,
75
- 0.811,
76
- 1.009,
77
- 2.380,
78
- ]
79
-
80
- for i in range(len(conc_list)):
81
- with self.subTest(conc=conc_list[i]):
82
- conc_c = str(conc_list[i] * nu_cation) + "mol/kg"
83
- conc_a = str(conc_list[i] * nu_anion) + "mol/kg"
84
- sol = pyEQL.Solution()
85
- sol.add_solute(cation, conc_c)
86
- sol.add_solute(anion, conc_a)
87
- act_cat = sol.get_activity_coefficient(cation)
88
- act_an = sol.get_activity_coefficient(anion)
89
- result = (act_cat ** nu_cation * act_an ** nu_anion) ** (
90
- 1 / (nu_cation + nu_anion)
91
- )
92
- expected = pub_activity_coeff[i]
93
-
94
- self.assertWithinExperimentalError(result, expected, self.tol)
95
-
96
- def test_activity_crc_CsI(self):
97
- """
98
- calculate the activity coefficient of CsI at each concentration and compare
99
- to experimental data
100
-
101
- Experimental activity coefficient values at 25 degC are found in
102
- *CRC Handbook of Chemistry and Physics*, Mean Activity Coefficients of Electrolytes as a Function of
103
- Concentration, in: W.M. Haynes (Ed.), 92nd ed., 2011.
104
-
105
- """
106
- cation = "Cs+"
107
- nu_cation = 1
108
- anion = "I-"
109
- nu_anion = 1
110
-
111
- # list of concentrations to test, mol/kg
112
- conc_list = [0.001, 0.002, 0.005, 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2]
113
-
114
- # list of published experimental activity coefficients
115
- pub_activity_coeff = [
116
- 0.965,
117
- 0.951,
118
- 0.925,
119
- 0.898,
120
- 0.863,
121
- 0.804,
122
- 0.749,
123
- 0.688,
124
- 0.601,
125
- 0.534,
126
- 0.470,
127
- ]
128
-
129
- for i in range(len(conc_list)):
130
- with self.subTest(conc=conc_list[i]):
131
- conc_c = str(conc_list[i] * nu_cation) + "mol/kg"
132
- conc_a = str(conc_list[i] * nu_anion) + "mol/kg"
133
- sol = pyEQL.Solution()
134
- sol.add_solute(cation, conc_c)
135
- sol.add_solute(anion, conc_a)
136
- act_cat = sol.get_activity_coefficient(cation)
137
- act_an = sol.get_activity_coefficient(anion)
138
- result = (act_cat ** nu_cation * act_an ** nu_anion) ** (
139
- 1 / (nu_cation + nu_anion)
140
- )
141
- expected = pub_activity_coeff[i]
142
-
143
- self.assertWithinExperimentalError(result, expected, self.tol)
144
-
145
- def test_activity_crc_bacl2(self):
146
- """
147
- calculate the activity coefficient of BaCl2 at each concentration and compare
148
- to experimental data
149
-
150
- Experimental activity coefficient values at 25 degC are found in
151
- *CRC Handbook of Chemistry and Physics*, Mean Activity Coefficients of Electrolytes as a Function of
152
- Concentration, in: W.M. Haynes (Ed.), 92nd ed., 2011.
153
-
154
- """
155
- # list of concentrations to test, mol/kg
156
- conc_list = [0.001, 0.002, 0.005, 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1]
157
-
158
- # list of published experimental activity coefficients
159
- pub_activity_coeff = [
160
- 0.887,
161
- 0.849,
162
- 0.782,
163
- 0.721,
164
- 0.653,
165
- 0.559,
166
- 0.492,
167
- 0.436,
168
- 0.391,
169
- 0.393,
170
- ]
171
-
172
- for i in range(len(conc_list)):
173
- with self.subTest(conc=conc_list[i]):
174
- conc_c = str(conc_list[i]) + "mol/kg"
175
- conc_a = str(conc_list[i] * 2) + "mol/kg"
176
- sol = pyEQL.Solution()
177
- sol.add_solute("Ba+2", conc_c)
178
- sol.add_solute("Cl-", conc_a)
179
- act_cat = sol.get_activity_coefficient("Ba+2")
180
- act_an = sol.get_activity_coefficient("Cl-")
181
- result = (act_cat ** 1 * act_an ** 2) ** (1 / 3)
182
- expected = pub_activity_coeff[i]
183
-
184
- self.assertWithinExperimentalError(result, expected, self.tol)
185
-
186
- def test_activity_crc_licl(self):
187
- """
188
- calculate the activity coefficient of LiCl at each concentration and compare
189
- to experimental data
190
-
191
- Experimental activity coefficient values at 25 degC are found in
192
- *CRC Handbook of Chemistry and Physics*, Mean Activity Coefficients of Electrolytes as a Function of
193
- Concentration, in: W.M. Haynes (Ed.), 92nd ed., 2011.
194
-
195
- """
196
- # list of concentrations to test, mol/kg
197
- conc_list = [0.001, 0.002, 0.005, 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5]
198
-
199
- # list of published experimental activity coefficients
200
- pub_activity_coeff = [
201
- 0.965,
202
- 0.952,
203
- 0.928,
204
- 0.904,
205
- 0.874,
206
- 0.827,
207
- 0.789,
208
- 0.756,
209
- 0.739,
210
- 0.775,
211
- 0.924,
212
- 2.0,
213
- ]
214
-
215
- for i in range(len(conc_list)):
216
- with self.subTest(conc=conc_list[i]):
217
- conc_c = str(conc_list[i]) + "mol/kg"
218
- conc_a = str(conc_list[i]) + "mol/kg"
219
- sol = pyEQL.Solution()
220
- sol.add_solute("Li+", conc_c)
221
- sol.add_solute("Cl-", conc_a)
222
- act_cat = sol.get_activity_coefficient("Li+")
223
- act_an = sol.get_activity_coefficient("Cl-")
224
- result = (act_cat ** 1 * act_an ** 1) ** (1 / 2)
225
- expected = pub_activity_coeff[i]
226
-
227
- self.assertWithinExperimentalError(result, expected, self.tol)
228
-
229
- def test_activity_crc_rbcl(self):
230
- """
231
- calculate the activity coefficient of RbCl at each concentration and compare
232
- to experimental data
233
-
234
- Experimental activity coefficient values at 25 degC are found in
235
- *CRC Handbook of Chemistry and Physics*, Mean Activity Coefficients of Electrolytes as a Function of
236
- Concentration, in: W.M. Haynes (Ed.), 92nd ed., 2011.
237
-
238
- """
239
- # list of concentrations to test, mol/kg
240
- conc_list = [0.001, 0.002, 0.005, 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5]
241
-
242
- # list of published experimental activity coefficients
243
- pub_activity_coeff = [
244
- 0.965,
245
- 0.951,
246
- 0.926,
247
- 0.900,
248
- 0.867,
249
- 0.811,
250
- 0.761,
251
- 0.707,
252
- 0.633,
253
- 0.583,
254
- 0.546,
255
- 0.544,
256
- ]
257
-
258
- for i in range(len(conc_list)):
259
- with self.subTest(conc=conc_list[i]):
260
- conc_c = str(conc_list[i]) + "mol/kg"
261
- conc_a = str(conc_list[i]) + "mol/kg"
262
- sol = pyEQL.Solution()
263
- sol.add_solute("Rb+", conc_c)
264
- sol.add_solute("Cl-", conc_a)
265
- result = sol.get_activity_coefficient("Rb+")
266
- expected = pub_activity_coeff[i]
267
-
268
- self.assertWithinExperimentalError(result, expected, self.tol)
269
-
270
- def test_activity_crc_MgCl2(self):
271
- """
272
- calculate the activity coefficient of MgCl2 at each concentration and compare
273
- to experimental data
274
-
275
- Experimental activity coefficient values at 25 degC are found in
276
- *CRC Handbook of Chemistry and Physics*, Mean Activity Coefficients of Electrolytes as a Function of
277
- Concentration, in: W.M. Haynes (Ed.), 92nd ed., 2011.
278
-
279
- """
280
- cation = "Mg+2"
281
- nu_cation = 1
282
- anion = "Cl-"
283
- nu_anion = 2
284
-
285
- # list of concentrations to test, mol/kg
286
- conc_list = [0.001, 0.002, 0.005, 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5]
287
-
288
- # list of published experimental activity coefficients
289
- pub_activity_coeff = [
290
- 0.889,
291
- 0.852,
292
- 0.790,
293
- 0.734,
294
- 0.672,
295
- 0.590,
296
- 0.535,
297
- 0.493,
298
- 0.485,
299
- 0.577,
300
- 1.065,
301
- 14.40,
302
- ]
303
-
304
- for i in range(len(conc_list)):
305
- with self.subTest(conc=conc_list[i]):
306
- conc_c = str(conc_list[i] * nu_cation) + "mol/kg"
307
- conc_a = str(conc_list[i] * nu_anion) + "mol/kg"
308
- sol = pyEQL.Solution()
309
- sol.add_solute(cation, conc_c)
310
- sol.add_solute(anion, conc_a)
311
- act_cat = sol.get_activity_coefficient(cation)
312
- act_an = sol.get_activity_coefficient(anion)
313
- result = (act_cat ** nu_cation * act_an ** nu_anion) ** (
314
- 1 / (nu_cation + nu_anion)
315
- )
316
- expected = pub_activity_coeff[i]
317
-
318
- self.assertWithinExperimentalError(result, expected, self.tol)
319
-
320
- def test_activity_crc_KBr(self):
321
- """
322
- calculate the activity coefficient of KBr at each concentration and compare
323
- to experimental data
324
-
325
- Experimental activity coefficient values at 25 degC are found in
326
- *CRC Handbook of Chemistry and Physics*, Mean Activity Coefficients of Electrolytes as a Function of
327
- Concentration, in: W.M. Haynes (Ed.), 92nd ed., 2011.
328
-
329
- """
330
- cation = "K+"
331
- nu_cation = 1
332
- anion = "Br-"
333
- nu_anion = 1
334
-
335
- # list of concentrations to test, mol/kg
336
- conc_list = [0.001, 0.002, 0.005, 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5]
337
-
338
- # list of published experimental activity coefficients
339
- pub_activity_coeff = [
340
- 0.965,
341
- 0.952,
342
- 0.927,
343
- 0.902,
344
- 0.870,
345
- 0.817,
346
- 0.771,
347
- 0.722,
348
- 0.658,
349
- 0.617,
350
- 0.593,
351
- 0.626,
352
- ]
353
-
354
- for i in range(len(conc_list)):
355
- with self.subTest(conc=conc_list[i]):
356
- conc_c = str(conc_list[i] * nu_cation) + "mol/kg"
357
- conc_a = str(conc_list[i] * nu_anion) + "mol/kg"
358
- sol = pyEQL.Solution()
359
- sol.add_solute(cation, conc_c)
360
- sol.add_solute(anion, conc_a)
361
- act_cat = sol.get_activity_coefficient(cation)
362
- act_an = sol.get_activity_coefficient(anion)
363
- result = (act_cat ** nu_cation * act_an ** nu_anion) ** (
364
- 1 / (nu_cation + nu_anion)
365
- )
366
- expected = pub_activity_coeff[i]
367
-
368
- self.assertWithinExperimentalError(result, expected, self.tol)
369
-
370
- def test_activity_crc_k2so4(self):
371
- """
372
- calculate the activity coefficient of K2SO4 at each concentration and compare
373
- to experimental data
374
-
375
- Experimental activity coefficient values at 25 degC are found in
376
- *CRC Handbook of Chemistry and Physics*, Mean Activity Coefficients of Electrolytes as a Function of
377
- Concentration, in: W.M. Haynes (Ed.), 92nd ed., 2011.
378
-
379
- """
380
- # list of concentrations to test, mol/kg
381
- conc_list = [0.001, 0.002, 0.005, 0.01, 0.02, 0.05, 0.1, 0.2, 0.5]
382
-
383
- # list of published experimental activity coefficients
384
- pub_activity_coeff = [
385
- 0.885,
386
- 0.844,
387
- 0.772,
388
- 0.704,
389
- 0.625,
390
- 0.511,
391
- 0.424,
392
- 0.343,
393
- 0.251,
394
- ]
395
-
396
- for i in range(len(conc_list)):
397
- with self.subTest(conc=conc_list[i]):
398
- conc_c = str(conc_list[i] * 2) + "mol/kg"
399
- conc_a = str(conc_list[i]) + "mol/kg"
400
- sol = pyEQL.Solution()
401
- sol.add_solute("K+", conc_c)
402
- sol.add_solute("SO4-2", conc_a)
403
- act_cat = sol.get_activity_coefficient("K+")
404
- act_an = sol.get_activity_coefficient("SO4-2")
405
- result = (act_cat ** 2 * act_an ** 1) ** (1 / 3)
406
- expected = pub_activity_coeff[i]
407
-
408
- self.assertWithinExperimentalError(result, expected, self.tol)
409
-
410
- def test_activity_pitzer_nacl_1(self):
411
- """
412
- calculate the activity coefficient at each concentration and compare
413
- to experimental data
414
-
415
- Experimental activity coefficient values at 25 degC are found in
416
- *J. Phys. Chem. Reference Data* Vol 13 (1), 1984, p.53.
417
-
418
- """
419
- # list of concentrations to test, mol/kg
420
- conc_list = [0.1, 0.25, 0.5, 0.75, 1, 2, 3, 4, 5, 6]
421
-
422
- # list of published experimental activity coefficients
423
- pub_activity_coeff = [
424
- 0.778,
425
- 0.72,
426
- 0.681,
427
- 0.665,
428
- 0.657,
429
- 0.669,
430
- 0.714,
431
- 0.782,
432
- 0.873,
433
- 0.987,
434
- ]
435
-
436
- for i in range(len(conc_list)):
437
- with self.subTest(conc=conc_list[i]):
438
- conc = str(conc_list[i]) + "mol/kg"
439
- sol = pyEQL.Solution()
440
- sol.add_solute("Na+", conc)
441
- sol.add_solute("Cl-", conc)
442
- result = sol.get_activity_coefficient("Na+")
443
- expected = pub_activity_coeff[i]
444
-
445
- self.assertWithinExperimentalError(result, expected, self.tol)
446
-
447
- # The pitzer model diverges a bit from experimental data at high concentration
448
- @unittest.expectedFailure
449
- def test_water_activity_pitzer_nacl_1(self):
450
- """
451
- calculate the water activity at each concentration and compare
452
- to experimental data
453
-
454
- Experimental osmotic coefficients for NaCl are found in:
455
- Pitzer and Pelper, 1984. "Thermodyamic Properties of Aqueous Sodium Chloride Solutions"
456
- *J. Phys. Chem. Ref. Data* 13(1).
457
-
458
- Osmotic coefficients were converted into water activity according to the equation
459
- found in
460
- Blandamer, Mike J., Engberts, Jan B. F. N., Gleeson, Peter T., Reis,
461
- Joao Carlos R., 2005. "Activity of water in aqueous systems: A frequently
462
- neglected property." *Chemical Society Review* 34, 440-458.
463
-
464
- .. math:: ln a_w = - \\Phi M_w \\sum_i m_i
465
-
466
- Where :math:`M_w` is the molar mass of water (0.018015 kg/mol) and :math:`m_i` is the molal concentration
467
- of each species.
468
-
469
- """
470
- # list of concentrations to test, mol/kg
471
- conc_list = [0.1, 0.25, 0.5, 0.75, 1, 2, 3, 4, 5, 6]
472
-
473
- # list of published experimental water activity
474
- pub_water_activity = [
475
- 0.9964,
476
- 0.9910,
477
- 0.9821,
478
- 0.9733,
479
- 0.9646,
480
- 0.9304,
481
- 0.8975,
482
- 0.8657,
483
- 0.8351,
484
- 0.8055,
485
- ]
486
-
487
- for i in range(len(conc_list)):
488
- with self.subTest(conc=conc_list[i]):
489
- conc = str(conc_list[i]) + "mol/kg"
490
- sol = pyEQL.Solution()
491
- sol.add_solute("Na+", conc)
492
- sol.add_solute("Cl-", conc)
493
- result = sol.get_water_activity()
494
- expected = pub_water_activity[i]
495
-
496
- self.assertWithinExperimentalError(result, expected, self.tol)
497
-
498
- def test_activity_pitzer_phreeqc_nacl_2(self):
499
- """
500
- calculate the activity coefficient at each concentration and compare
501
- to the output of the PHREEQC model
502
-
503
- PHREEQC version 3.1.4 was used to calculate density, conductivity, water
504
- activity, and NaCl activity coefficient for NaCl solutions up to 6m.
505
- The Pitzer model (pitzer.dat) database was used.
506
- <http://wwwbrr.cr.usgs.gov/projects/GWC_coupled/phreeqc/>
507
-
508
- """
509
- # list of concentrations to test, mol/kg
510
- conc_list = [0.1, 0.25, 0.5, 0.75, 1, 2, 3, 4, 5, 6]
511
-
512
- # list of modeled activity coefficients
513
- phreeqc_pitzer_activity_coeff = [
514
- 0.7771,
515
- 0.7186,
516
- 0.6799,
517
- 0.6629,
518
- 0.6561,
519
- 0.6675,
520
- 0.7128,
521
- 0.7825,
522
- 0.8729,
523
- 0.9874,
524
- ]
525
-
526
- for i in range(len(conc_list)):
527
- with self.subTest(conc=conc_list[i]):
528
- conc = str(conc_list[i]) + "mol/kg"
529
- sol = pyEQL.Solution()
530
- sol.add_solute("Na+", conc)
531
- sol.add_solute("Cl-", conc)
532
- result = sol.get_activity_coefficient("Na+")
533
- expected = phreeqc_pitzer_activity_coeff[i]
534
-
535
- self.assertWithinExperimentalError(result, expected, self.tol)
536
-
537
- def test_water_activity_phreeqc_pitzer_nacl_2(self):
538
- """
539
- calculate the water activity at each concentration and compare
540
- to the output of the PHREEQC model
541
-
542
- PHREEQC version 3.1.4 was used to calculate density, conductivity, water
543
- activity, and NaCl activity coefficient for NaCl solutions up to 6m.
544
- The Pitzer model (pitzer.dat) database was used.
545
- <http://wwwbrr.cr.usgs.gov/projects/GWC_coupled/phreeqc/>
546
-
547
- """
548
- # list of concentrations to test, mol/kg
549
- conc_list = [0.1, 0.25, 0.5, 0.75, 1, 2, 3, 4, 5, 6]
550
-
551
- # list of modeled water activities
552
- phreeqc_pitzer_water_activity = [
553
- 0.997,
554
- 0.992,
555
- 0.984,
556
- 0.975,
557
- 0.967,
558
- 0.932,
559
- 0.893,
560
- 0.851,
561
- 0.807,
562
- 0.759,
563
- ]
564
-
565
- for i in range(len(conc_list)):
566
- with self.subTest(conc=conc_list[i]):
567
- conc = str(conc_list[i]) + "mol/kg"
568
- sol = pyEQL.Solution()
569
- sol.add_solute("Na+", conc)
570
- sol.add_solute("Cl-", conc)
571
- result = sol.get_water_activity()
572
- expected = phreeqc_pitzer_water_activity[i]
573
-
574
- self.assertWithinExperimentalError(result, expected, self.tol)
575
-
576
-
577
- if __name__ == "__main__":
578
- unittest.main()
@@ -1,86 +0,0 @@
1
- """
2
- pyEQL test suite for bulk property calculations
3
- ===============================================
4
-
5
- This file contains tests for the bulk properties calculated by
6
- Solution class methods. Currently included methods are:
7
-
8
- - get_hardness()
9
-
10
- """
11
-
12
- import pyEQL
13
- import unittest
14
-
15
-
16
- class test_hardness(unittest.TestCase, pyEQL.CustomAssertions):
17
- """
18
- test the get_hardness() method
19
- ------------------------------
20
- """
21
-
22
- # an empty solution should have zero hardness
23
- def test_empty_solution(self):
24
- s1 = pyEQL.Solution()
25
- result = s1.get_hardness().magnitude
26
- expected = 0
27
-
28
- self.assertEqual(result, expected)
29
-
30
- # a solution with only monovalent ions should have zero hardness
31
- def test_hardness_1(self):
32
- s1 = pyEQL.Solution([["Na+", "0.2 mol/L"], ["Cl-", "0.2 mol/L"]])
33
- result = s1.get_hardness().magnitude
34
- expected = 0
35
-
36
- self.assertEqual(result, expected)
37
-
38
- # a solution with only multivalent anions should have zero hardness
39
- def test_hardness_2(self):
40
- s1 = pyEQL.Solution([["Na+", "0.4 mol/L"], ["SO4-2", "0.2 mol/L"]])
41
- result = s1.get_hardness().magnitude
42
- expected = 0
43
-
44
- self.assertEqual(result, expected)
45
-
46
- # the hardness should return the equivalent concentration, not just the
47
- # molar concentration (e.g. multiply by the charge)
48
- def test_hardness_3(self):
49
- s1 = pyEQL.Solution([["Fe+3", "0.1 mol/L"], ["Cl-", "0.3 mol/L"]])
50
- result = s1.get_hardness().magnitude
51
- expected = 15013.5
52
-
53
- self.assertAlmostEqual(result, expected)
54
-
55
- # the hardness should account for multiple cations but count only those
56
- # that are multivalent
57
- def test_hardness_4(self):
58
- s1 = pyEQL.Solution(
59
- [
60
- ["Na+", "0.1 mol/L"],
61
- ["K+", "0.1 mol/L"],
62
- ["Mg+2", "0.1 mol/L"],
63
- ["Ca+2", "0.1 mol/L"],
64
- ["Fe+3", "0.1 mol/L"],
65
- ["Cl-", "0.1 mol/L"],
66
- ["F-", "0.1 mol/L"],
67
- ["SO4-2", "0.2 mol/L"],
68
- ["PO4-3", "0.1 mol/L"],
69
- ]
70
- )
71
- result = s1.get_hardness().magnitude
72
- expected = 35031.5
73
-
74
- self.assertAlmostEqual(result, expected)
75
-
76
- # the hardness should return g/L units
77
- def test_hardness_5(self):
78
- s1 = pyEQL.Solution([["Fe+3", "0.1 mol/L"], ["Cl-", "0.3 mol/L"]])
79
- result = str(s1.get_hardness().dimensionality)
80
- expected = "[mass] / [length] ** 3"
81
-
82
- self.assertEqual(result, expected)
83
-
84
-
85
- if __name__ == "__main__":
86
- unittest.main()