pyEQL 1.1.1__tar.gz → 1.1.2__tar.gz
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-1.1.1 → pyeql-1.1.2}/CHANGELOG.md +8 -0
- {pyeql-1.1.1/src/pyEQL.egg-info → pyeql-1.1.2}/PKG-INFO +1 -1
- {pyeql-1.1.1 → pyeql-1.1.2}/docs/changelog.md +8 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/src/pyEQL/engines.py +5 -14
- {pyeql-1.1.1 → pyeql-1.1.2}/src/pyEQL/solution.py +31 -26
- {pyeql-1.1.1 → pyeql-1.1.2/src/pyEQL.egg-info}/PKG-INFO +1 -1
- {pyeql-1.1.1 → pyeql-1.1.2}/tests/test_solution.py +23 -4
- {pyeql-1.1.1 → pyeql-1.1.2}/.coveragerc +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/.gitattributes +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/.github/dependabot.yml +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/.github/pull_request_template.md +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/.github/release.yml +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/.github/workflows/post-process.yml +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/.github/workflows/release.yml +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/.github/workflows/testing.yaml +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/.github/workflows/upgrade_dependencies.yml +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/.gitignore +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/.pre-commit-config.yaml +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/.readthedocs.yml +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/.zenodo.json +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/AUTHORS.md +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/CITATION.cff +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/COPYING +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/LICENSE.txt +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/MANIFEST.in +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/README.md +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/docs/Makefile +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/docs/_static/.gitignore +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/docs/amounts.md +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/docs/arithmetic.md +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/docs/authors.md +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/docs/chemistry.md +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/docs/class_solution.md +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/docs/conf.py +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/docs/contributing.md +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/docs/creating.md +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/docs/database.md +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/docs/engines.md +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/docs/examples/.ipynb_checkpoints/pyEQL_demo_1-checkpoint.ipynb +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/docs/examples/.ipynb_checkpoints/pyeql_demo-checkpoint.ipynb +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/docs/examples/.ipynb_checkpoints/pyeql_tutorial_database-checkpoint.ipynb +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/docs/examples/.ipynb_checkpoints/pyeql_tutorial_osmotic_pressure-checkpoint.ipynb +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/docs/examples/.ipynb_checkpoints/speedup-checkpoint.ipynb +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/docs/examples/pyEQL_demo_1.ipynb +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/docs/examples/pyeql_demo.ipynb +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/docs/examples/pyeql_tutorial_database.ipynb +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/docs/examples/pyeql_tutorial_osmotic_pressure.ipynb +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/docs/examples/speedup.ipynb +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/docs/index.md +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/docs/installation.md +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/docs/internal.md +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/docs/license.md +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/docs/mixing.md +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/docs/quickstart.md +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/docs/readme.md +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/docs/requirements.txt +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/docs/serialization.md +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/docs/tutorials.md +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/docs/units.md +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/pyeql-logo.png +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/pyeql-logo.svg +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/pyproject.toml +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/requirements/macos-latest_py3.10.txt +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/requirements/macos-latest_py3.10_extras.txt +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/requirements/macos-latest_py3.11.txt +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/requirements/macos-latest_py3.11_extras.txt +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/requirements/macos-latest_py3.12.txt +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/requirements/macos-latest_py3.12_extras.txt +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/requirements/macos-latest_py3.9.txt +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/requirements/macos-latest_py3.9_extras.txt +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/requirements/ubuntu-latest_py3.10.txt +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/requirements/ubuntu-latest_py3.10_extras.txt +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/requirements/ubuntu-latest_py3.11.txt +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/requirements/ubuntu-latest_py3.11_extras.txt +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/requirements/ubuntu-latest_py3.12.txt +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/requirements/ubuntu-latest_py3.12_extras.txt +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/requirements/ubuntu-latest_py3.9.txt +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/requirements/ubuntu-latest_py3.9_extras.txt +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/requirements/windows-latest_py3.10.txt +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/requirements/windows-latest_py3.10_extras.txt +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/requirements/windows-latest_py3.11.txt +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/requirements/windows-latest_py3.11_extras.txt +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/requirements/windows-latest_py3.12.txt +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/requirements/windows-latest_py3.12_extras.txt +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/requirements/windows-latest_py3.9.txt +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/requirements/windows-latest_py3.9_extras.txt +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/setup.cfg +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/setup.py +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/src/pyEQL/__init__.py +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/src/pyEQL/activity_correction.py +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/src/pyEQL/database/geothermal.dat +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/src/pyEQL/database/llnl.dat +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/src/pyEQL/database/phreeqc_license.txt +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/src/pyEQL/database/pyeql_db.json +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/src/pyEQL/equilibrium.py +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/src/pyEQL/functions.py +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/src/pyEQL/presets/Ringers lactate.yaml +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/src/pyEQL/presets/normal saline.yaml +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/src/pyEQL/presets/rainwater.yaml +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/src/pyEQL/presets/seawater.yaml +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/src/pyEQL/presets/urine.yaml +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/src/pyEQL/presets/wastewater.yaml +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/src/pyEQL/salt_ion_match.py +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/src/pyEQL/solute.py +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/src/pyEQL/utils.py +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/src/pyEQL.egg-info/SOURCES.txt +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/src/pyEQL.egg-info/dependency_links.txt +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/src/pyEQL.egg-info/requires.txt +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/src/pyEQL.egg-info/top_level.txt +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/tests/conftest.py +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/tests/test_activity.py +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/tests/test_bulk_properties.py +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/tests/test_debye_length.py +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/tests/test_density.py +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/tests/test_dielectric.py +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/tests/test_effective_pitzer.py +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/tests/test_equilibrium.py +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/tests/test_functions.py +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/tests/test_logging.py +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/tests/test_mixed_electrolyte_activity.py +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/tests/test_osmotic_coeff.py +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/tests/test_phreeqc.py +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/tests/test_salt_matching.py +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/tests/test_solute.py +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/tests/test_solute_properties.py +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/tests/test_utils.py +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/tests/test_volume_concentration.py +0 -0
- {pyeql-1.1.1 → pyeql-1.1.2}/tox.ini +0 -0
|
@@ -5,6 +5,14 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [1.1.2] - 2024-07-28
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
|
|
12
|
+
- `Solution`: Fix a bug in which setting `balance_charge` to `auto` when the initial
|
|
13
|
+
composition was electroneutral would cause errors and/or improper charge balancing
|
|
14
|
+
after `equilibrate` was called.
|
|
15
|
+
|
|
8
16
|
## [1.1.1] - 2024-07-27
|
|
9
17
|
|
|
10
18
|
### Fixed
|
|
@@ -5,6 +5,14 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [1.1.2] - 2024-07-28
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
|
|
12
|
+
- `Solution`: Fix a bug in which setting `balance_charge` to `auto` when the initial
|
|
13
|
+
composition was electroneutral would cause errors and/or improper charge balancing
|
|
14
|
+
after `equilibrate` was called.
|
|
15
|
+
|
|
8
16
|
## [1.1.1] - 2024-07-27
|
|
9
17
|
|
|
10
18
|
### Fixed
|
|
@@ -229,10 +229,7 @@ class NativeEOS(EOS):
|
|
|
229
229
|
d[key] = str(mol / solv_mass)
|
|
230
230
|
|
|
231
231
|
# tell PHREEQC which species to use for charge balance
|
|
232
|
-
if (
|
|
233
|
-
solution.balance_charge is not None
|
|
234
|
-
and solution.balance_charge in solution.get_components_by_element()[el]
|
|
235
|
-
):
|
|
232
|
+
if solution.balance_charge is not None and solution._cb_species in solution.get_components_by_element()[el]:
|
|
236
233
|
d[key] += " charge"
|
|
237
234
|
|
|
238
235
|
# create the PHREEQC solution object
|
|
@@ -698,18 +695,12 @@ class NativeEOS(EOS):
|
|
|
698
695
|
if charge_adjust != 0:
|
|
699
696
|
logger.warning(
|
|
700
697
|
"After equilibration, the charge balance of the solution was not electroneutral."
|
|
701
|
-
f" {charge_adjust} eq of charge were added via {solution.
|
|
698
|
+
f" {charge_adjust} eq of charge were added via {solution._cb_species}"
|
|
702
699
|
)
|
|
703
700
|
|
|
704
|
-
if solution.balance_charge is None:
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
solution.components["H+"] += charge_adjust
|
|
708
|
-
elif solution.balance_charge == "pE":
|
|
709
|
-
raise NotImplementedError
|
|
710
|
-
else:
|
|
711
|
-
z = solution.get_property(solution.balance_charge, "charge")
|
|
712
|
-
solution.add_amount(solution.balance_charge, f"{charge_adjust/z} mol")
|
|
701
|
+
if solution.balance_charge is not None:
|
|
702
|
+
z = solution.get_property(solution._cb_species, "charge")
|
|
703
|
+
solution.add_amount(solution._cb_species, f"{charge_adjust/z} mol")
|
|
713
704
|
|
|
714
705
|
# rescale the solvent mass to ensure the total mass of solution does not change
|
|
715
706
|
# this is important because PHREEQC and the pyEQL database may use slightly different molecular
|
|
@@ -261,39 +261,44 @@ class Solution(MSONable):
|
|
|
261
261
|
for item in self._solutes:
|
|
262
262
|
self.add_solute(*item)
|
|
263
263
|
|
|
264
|
-
#
|
|
264
|
+
# determine the species that will be used for charge balancing, when needed.
|
|
265
|
+
# this is necessary to do even if the composition is already electroneutral,
|
|
266
|
+
# because the appropriate species also needs to be passed to equilibrate
|
|
267
|
+
# to keep from distorting the charge balance.
|
|
265
268
|
cb = self.charge_balance
|
|
269
|
+
if self.balance_charge is None:
|
|
270
|
+
self._cb_species = None
|
|
271
|
+
elif self.balance_charge == "pH":
|
|
272
|
+
self._cb_species = "H[+1]"
|
|
273
|
+
elif self.balance_charge == "pE":
|
|
274
|
+
raise NotImplementedError("Balancing charge via redox (pE) is not yet implemented!")
|
|
275
|
+
elif self.balance_charge == "auto":
|
|
276
|
+
# add the most abundant ion of the opposite charge
|
|
277
|
+
if cb <= 0:
|
|
278
|
+
self._cb_species = max(self.cations, key=self.cations.get)
|
|
279
|
+
elif cb > 0:
|
|
280
|
+
self._cb_species = max(self.anions, key=self.anions.get)
|
|
281
|
+
else:
|
|
282
|
+
ions = set().union(*[self.cations, self.anions]) # all ions
|
|
283
|
+
self._cb_species = self.balance_charge
|
|
284
|
+
if self._cb_species not in ions:
|
|
285
|
+
raise ValueError(
|
|
286
|
+
f"Charge balancing species {self._cb_species} was not found in the solution!. "
|
|
287
|
+
f"Species {ions} were found."
|
|
288
|
+
)
|
|
289
|
+
|
|
290
|
+
# adjust charge balance, if necessary
|
|
266
291
|
if not np.isclose(cb, 0, atol=1e-8) and self.balance_charge is not None:
|
|
267
292
|
balanced = False
|
|
268
293
|
self.logger.info(
|
|
269
|
-
f"Solution is not electroneutral (C.B. = {cb} eq/L). Adding {
|
|
294
|
+
f"Solution is not electroneutral (C.B. = {cb} eq/L). Adding {self._cb_species} to compensate."
|
|
270
295
|
)
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
) # if C.B. is negative, we need to add cations. H+ is 1 eq/mol
|
|
296
|
+
z = self.get_property(self._cb_species, "charge")
|
|
297
|
+
self.components[self._cb_species] += -1 * cb / z * self.volume.to("L").magnitude
|
|
298
|
+
if np.isclose(self.charge_balance, 0, atol=1e-8):
|
|
275
299
|
balanced = True
|
|
276
|
-
elif self.balance_charge == "pE":
|
|
277
|
-
raise NotImplementedError("Balancing charge via redox (pE) is not yet implemented!")
|
|
278
|
-
else:
|
|
279
|
-
ions = set().union(*[self.cations, self.anions]) # all ions
|
|
280
|
-
if self.balance_charge == "auto":
|
|
281
|
-
# add the most abundant ion of the opposite charge
|
|
282
|
-
if cb <= 0:
|
|
283
|
-
self.balance_charge = max(self.cations, key=self.cations.get)
|
|
284
|
-
elif cb > 0:
|
|
285
|
-
self.balance_charge = max(self.anions, key=self.anions.get)
|
|
286
|
-
if self.balance_charge not in ions:
|
|
287
|
-
raise ValueError(
|
|
288
|
-
f"Charge balancing species {self.balance_charge} was not found in the solution!. "
|
|
289
|
-
f"Species {ions} were found."
|
|
290
|
-
)
|
|
291
|
-
z = self.get_property(self.balance_charge, "charge")
|
|
292
|
-
self.components[self.balance_charge] += -1 * cb / z * self.volume.to("L").magnitude
|
|
293
|
-
balanced = True
|
|
294
|
-
|
|
295
300
|
if not balanced:
|
|
296
|
-
warnings.warn(f"Unable to balance charge using species {self.
|
|
301
|
+
warnings.warn(f"Unable to balance charge using species {self._cb_species}")
|
|
297
302
|
|
|
298
303
|
@property
|
|
299
304
|
def mass(self) -> Quantity:
|
|
@@ -268,16 +268,35 @@ def test_charge_balance(s3, s5, s5_pH, s6, s6_Ca):
|
|
|
268
268
|
volume="1 L",
|
|
269
269
|
balance_charge="auto",
|
|
270
270
|
)
|
|
271
|
-
assert s.balance_charge == "
|
|
271
|
+
assert s.balance_charge == "auto"
|
|
272
|
+
assert s._cb_species == "Na[+1]"
|
|
272
273
|
assert np.isclose(s.charge_balance, 0, atol=1e-8)
|
|
273
274
|
s.equilibrate()
|
|
274
|
-
assert s.balance_charge == "
|
|
275
|
+
assert s.balance_charge == "auto"
|
|
276
|
+
assert s._cb_species == "Na[+1]"
|
|
277
|
+
assert np.isclose(s.charge_balance, 0, atol=1e-8)
|
|
275
278
|
|
|
276
279
|
s = Solution({"Na+": "2 mM", "Cl-": "1 mM"}, balance_charge="auto")
|
|
277
|
-
assert s.balance_charge == "
|
|
280
|
+
assert s.balance_charge == "auto"
|
|
281
|
+
assert s._cb_species == "Cl[-1]"
|
|
278
282
|
assert np.isclose(s.charge_balance, 0, atol=1e-8)
|
|
279
283
|
s.equilibrate()
|
|
280
|
-
assert s.balance_charge == "
|
|
284
|
+
assert s.balance_charge == "auto"
|
|
285
|
+
assert s._cb_species == "Cl[-1]"
|
|
286
|
+
assert np.isclose(s.charge_balance, 0, atol=1e-8)
|
|
287
|
+
|
|
288
|
+
# check "auto" with an electroneutral solution
|
|
289
|
+
s = Solution({"Na+": "2 mM", "Cl-": "2 mM"}, balance_charge="auto")
|
|
290
|
+
assert s.balance_charge == "auto"
|
|
291
|
+
assert s._cb_species == "Na[+1]"
|
|
292
|
+
assert np.isclose(s.charge_balance, 0, atol=1e-8)
|
|
293
|
+
s.equilibrate()
|
|
294
|
+
assert s.balance_charge == "auto"
|
|
295
|
+
assert s._cb_species == "Na[+1]"
|
|
296
|
+
assert np.isclose(s.charge_balance, 0, atol=1e-8)
|
|
297
|
+
|
|
298
|
+
with pytest.raises(ValueError, match=r"Charge balancing species Zr\[\+4\] was not found"):
|
|
299
|
+
s = Solution({"Na+": "2 mM", "Cl-": "2 mM"}, balance_charge="Zr[+4]")
|
|
281
300
|
|
|
282
301
|
|
|
283
302
|
def test_alkalinity_hardness(s3, s5, s6):
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|