From 63d138d3356a7e42965230c0599859058fdc8cdc Mon Sep 17 00:00:00 2001 From: Robert Timms <43040151+rtimms@users.noreply.github.com> Date: Mon, 2 Dec 2024 17:02:13 +0000 Subject: [PATCH] Fix BPX bug when activation energies not provided (#4634) * fix bpx bug when activation energies not provided * update BPX tests * Move function and rename variable --------- Co-authored-by: Eric G. Kratz Co-authored-by: kratman --- src/pybamm/parameters/bpx.py | 34 +++++++++++++++-------- src/pybamm/parameters/parameter_values.py | 4 +-- tests/unit/test_parameters/test_bpx.py | 19 ++++++++++++- 3 files changed, 43 insertions(+), 14 deletions(-) diff --git a/src/pybamm/parameters/bpx.py b/src/pybamm/parameters/bpx.py index df380ad627..92801c96ca 100644 --- a/src/pybamm/parameters/bpx.py +++ b/src/pybamm/parameters/bpx.py @@ -108,7 +108,7 @@ def _get_phase_names(domain): ) -def _bpx_to_param_dict(bpx: BPX) -> dict: +def bpx_to_param_dict(bpx: BPX) -> dict: """ Turns a BPX object in to a dictionary of parameters for PyBaMM """ @@ -222,6 +222,9 @@ def _bpx_to_param_dict(bpx: BPX) -> dict: domain.pre_name + "transport efficiency" ] ** (1.0 / 1.5) + def _get_activation_energy(var_name): + return pybamm_dict.get(var_name) or 0.0 + # define functional forms for pybamm parameters that depend on more than one # variable @@ -294,11 +297,15 @@ def _conductivity(c_e, T, Ea, sigma_ref, constant=False): k_norm = pybamm_dict[ phase_domain_pre_name + "reaction rate constant [mol.m-2.s-1]" ] - Ea_k = pybamm_dict.get( + Ea_k = _get_activation_energy( phase_domain_pre_name - + "reaction rate constant activation energy [J.mol-1]", - 0.0, + + "reaction rate constant activation energy [J.mol-1]" ) + pybamm_dict[ + phase_domain_pre_name + + "reaction rate constant activation energy [J.mol-1]" + ] = Ea_k + # Note that in BPX j = 2*F*k_norm*sqrt((ce/ce0)*(c/c_max)*(1-c/c_max))... # *sinh(), # and in PyBaMM j = 2*k*sqrt(ce*c*(c_max - c))*sinh() @@ -308,9 +315,8 @@ def _conductivity(c_e, T, Ea, sigma_ref, constant=False): ) # diffusivity - Ea_D = pybamm_dict.get( - phase_domain_pre_name + "diffusivity activation energy [J.mol-1]", - 0.0, + Ea_D = _get_activation_energy( + phase_domain_pre_name + "diffusivity activation energy [J.mol-1]" ) pybamm_dict[ phase_domain_pre_name + "diffusivity activation energy [J.mol-1]" @@ -335,8 +341,11 @@ def _conductivity(c_e, T, Ea, sigma_ref, constant=False): ) # electrolyte - Ea_D_e = pybamm_dict.get( - electrolyte.pre_name + "diffusivity activation energy [J.mol-1]", 0.0 + Ea_D_e = _get_activation_energy( + electrolyte.pre_name + "diffusivity activation energy [J.mol-1]" + ) + pybamm_dict[electrolyte.pre_name + "diffusivity activation energy [J.mol-1]"] = ( + Ea_D_e ) D_e_ref = pybamm_dict[electrolyte.pre_name + "diffusivity [m2.s-1]"] @@ -358,8 +367,11 @@ def _conductivity(c_e, T, Ea, sigma_ref, constant=False): ) # conductivity - Ea_sigma_e = pybamm_dict.get( - electrolyte.pre_name + "conductivity activation energy [J.mol-1]", 0.0 + Ea_sigma_e = _get_activation_energy( + electrolyte.pre_name + "conductivity activation energy [J.mol-1]" + ) + pybamm_dict[electrolyte.pre_name + "conductivity activation energy [J.mol-1]"] = ( + Ea_sigma_e ) sigma_e_ref = pybamm_dict[electrolyte.pre_name + "conductivity [S.m-1]"] diff --git a/src/pybamm/parameters/parameter_values.py b/src/pybamm/parameters/parameter_values.py index bb30f24836..72065b4dfe 100644 --- a/src/pybamm/parameters/parameter_values.py +++ b/src/pybamm/parameters/parameter_values.py @@ -88,11 +88,11 @@ def create_from_bpx(filename, target_soc: float = 1): from bpx import parse_bpx_file, get_electrode_concentrations from bpx.schema import ElectrodeBlended, ElectrodeBlendedSPM - from .bpx import _bpx_to_param_dict + from .bpx import bpx_to_param_dict # parse bpx bpx = parse_bpx_file(filename) - pybamm_dict = _bpx_to_param_dict(bpx) + pybamm_dict = bpx_to_param_dict(bpx) if "Open-circuit voltage at 0% SOC [V]" not in pybamm_dict: pybamm_dict["Open-circuit voltage at 0% SOC [V]"] = pybamm_dict[ diff --git a/tests/unit/test_parameters/test_bpx.py b/tests/unit/test_parameters/test_bpx.py index 3e0e32d1fd..3d4b65afcf 100644 --- a/tests/unit/test_parameters/test_bpx.py +++ b/tests/unit/test_parameters/test_bpx.py @@ -475,7 +475,9 @@ def test_bpx_user_defined(self): param = pybamm.ParameterValues.create_from_bpx(tmp.name) - assert param["User-defined scalar parameter"] == 1.0 + assert param["User-defined scalar parameter"] == pytest.approx( + 1.0, rel=1e-12 + ) var = pybamm.Variable("var") assert isinstance( param["User-defined parameter data"](var), pybamm.Interpolant @@ -483,3 +485,18 @@ def test_bpx_user_defined(self): assert isinstance( param["User-defined parameter data function"](var), pybamm.Power ) + + def test_bpx_activation_energy_default(self): + bpx_obj = copy.copy(self.base) + bpx_obj["Parameterisation"]["Negative electrode"][ + "Diffusivity activation energy [J.mol-1]" + ] = None + with tempfile.NamedTemporaryFile( + suffix="test.json", delete=False, mode="w" + ) as test_file: + json.dump(copy.copy(bpx_obj), test_file) + test_file.flush() + param = pybamm.ParameterValues.create_from_bpx(test_file.name) + assert param[ + "Negative electrode diffusivity activation energy [J.mol-1]" + ] == pytest.approx(0.0, rel=1e-12)