diff --git a/CHANGELOG.md b/CHANGELOG.md index b91574ad..214b7ef8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,14 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [1.3.2] - 2025-09-15 + +### Fixed + +- `Solution.get_viscosity_kinematic()`: A recent change to get_salt_dict (#258) created a problem with `get_viscosity_kinetmatic` + in which an empty solution would cause the method to return an error. This has been fixed, and unit tests added for both + `get_viscosity_kinematic` and `get_viscosity_dynamic`. + ## [1.3.1] - 2025-08-18 ### Fixed diff --git a/src/pyEQL/solution.py b/src/pyEQL/solution.py index d1bfaa58..0fc84ef9 100644 --- a/src/pyEQL/solution.py +++ b/src/pyEQL/solution.py @@ -651,7 +651,7 @@ def viscosity_kinematic(self) -> Quantity: a0 = a1 = b0 = b1 = 0 # retrieve the parameters for the delta G equations - params = self.get_property(salt.formula, "model_parameters.viscosity_eyring") + params = None if salt is None else self.get_property(salt.formula, "model_parameters.viscosity_eyring") if params is not None: a0 = ureg.Quantity(params["a0"]["value"]).magnitude a1 = ureg.Quantity(params["a1"]["value"]).magnitude @@ -662,11 +662,16 @@ def viscosity_kinematic(self) -> Quantity: temperature = self.temperature.to("degC").magnitude G_123 = a0 + a1 * (temperature) ** 0.75 G_23 = b0 + b1 * (temperature) ** 0.5 + + # calculate the cation mole fraction + # x_cat = self.get_amount(cation, "fraction") + x_cat = self.get_amount(salt.cation, "fraction").magnitude else: # TODO - fall back to the Jones-Dole model! There are currently no eyring parameters in the database! # proceed with the coefficients equal to zero and log a warning - self.logger.warning(f"Viscosity coefficients for {salt.formula} not found. Viscosity will be approximate.") + self.logger.warning(f"Appropriate viscosity coefficients werenot found. Viscosity will be approximate.") G_123 = G_23 = 0 + x_cat = 0 # get the kinematic viscosity of water, returned by IAPWS in m2/s nu_w = self.water_substance.nu @@ -678,10 +683,6 @@ def viscosity_kinematic(self) -> Quantity: # get the MW of water MW_w = self.get_property(self.solvent, "molecular_weight").magnitude - # calculate the cation mole fraction - # x_cat = self.get_amount(cation, "fraction") - x_cat = self.get_amount(salt.cation, "fraction").magnitude - # calculate the kinematic viscosity nu = np.log(nu_w * MW_w / MW) + 15 * x_cat**2 + x_cat**3 * G_123 + 3 * x_cat * G_23 * (1 - 0.05 * x_cat) diff --git a/tests/test_solution.py b/tests/test_solution.py index d4c7af65..9dede33c 100644 --- a/tests/test_solution.py +++ b/tests/test_solution.py @@ -97,7 +97,7 @@ def s6_Ca(): ) -def test_empty_solution_3(): +def test_empty_solution(): # create an empty solution s1 = Solution(database=None) # It should return type Solution @@ -118,6 +118,9 @@ def test_empty_solution_3(): assert np.isclose(s1.pE, 8.5) # it should contain H2O, H+, and OH- species assert set(s1.components.keys()) == {"H2O(aq)", "OH[-1]", "H[+1]"} + assert np.isclose(s1.density.to('kg/m**3').magnitude, 997.0479, atol=0.1) + assert np.isclose(s1.viscosity_kinematic.to('mm**2/s').magnitude, 0.8917, atol=1e-3) # 1 cSt = 1 mm2/s + assert np.isclose(s1.viscosity_dynamic, s1.viscosity_kinematic * s1.density, atol=1e-8) @pytest.mark.skipif(platform.machine() == "arm64" and platform.system() == "Darwin", reason="arm64 not supported")