From b0433de7343326f12e41bf1ca257efa0530974f7 Mon Sep 17 00:00:00 2001 From: Ivan Korotkin Date: Fri, 16 Jun 2023 13:16:22 +0100 Subject: [PATCH 01/47] Fixed maximum concentration in positive electrode in test file --- tests/test_utilities.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_utilities.py b/tests/test_utilities.py index aa82f0f..5dfb29a 100644 --- a/tests/test_utilities.py +++ b/tests/test_utilities.py @@ -57,7 +57,7 @@ def setUp(self): "Porosity": 0.335, "Transport efficiency": 0.1939, "Reaction rate constant [mol.m-2.s-1]": 1e-10, - "Maximum concentration [mol.m-3]": 631040, + "Maximum concentration [mol.m-3]": 63104.0, "Minimum stoichiometry": 0.1, "Maximum stoichiometry": 0.9, }, @@ -81,7 +81,7 @@ def test_get_init_conc(self): obj = parse_obj_as(BPX, test) x, y = get_electrode_concentrations(0.7, obj) self.assertAlmostEqual(x, 23060.568) - self.assertAlmostEqual(y, 214553.6) + self.assertAlmostEqual(y, 21455.36) if __name__ == "__main__": From 3f831501f03c4b030a56a6cd2593bd8d7d859557 Mon Sep 17 00:00:00 2001 From: Ivan Korotkin Date: Fri, 16 Jun 2023 14:32:42 +0100 Subject: [PATCH 02/47] Fixed maximum concentration in test_schema.py according to issue #30 --- tests/test_schema.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_schema.py b/tests/test_schema.py index db1702e..797910e 100644 --- a/tests/test_schema.py +++ b/tests/test_schema.py @@ -57,7 +57,7 @@ def setUp(self): "Porosity": 0.335, "Transport efficiency": 0.1939, "Reaction rate constant [mol.m-2.s-1]": 1e-10, - "Maximum concentration [mol.m-3]": 631040, + "Maximum concentration [mol.m-3]": 63104.0, "Minimum stoichiometry": 0.1, "Maximum stoichiometry": 0.9, }, From 7411768e90231fe26486023291a6b7eb77de8ded Mon Sep 17 00:00:00 2001 From: Ivan Korotkin Date: Mon, 19 Jun 2023 14:02:32 +0100 Subject: [PATCH 03/47] Validate the sto limits according to issue #8 --- bpx/schema.py | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/bpx/schema.py b/bpx/schema.py index 07c76f6..7e3bc77 100644 --- a/bpx/schema.py +++ b/bpx/schema.py @@ -1,6 +1,6 @@ from typing import List, Literal, Union, Dict -from pydantic import BaseModel, Field, Extra +from pydantic import BaseModel, Field, Extra, root_validator from bpx import Function, InterpolatedTable @@ -289,6 +289,38 @@ class Parameterisation(ExtraBaseModel): alias="Separator", ) + # Validates that the STO limits subbed into the OCPs give + # the correct voltage limits. + # https://docs.pydantic.dev/latest/usage/validators/#root-validators + @root_validator + def check_sto_limits(cls, values): + sto_n_min = values.get("negative_electrode").minimum_stoichiometry + sto_n_max = values.get("negative_electrode").maximum_stoichiometry + sto_p_min = values.get("positive_electrode").minimum_stoichiometry + sto_p_max = values.get("positive_electrode").maximum_stoichiometry + V_min = values.get("cell").lower_voltage_cutoff + V_max = values.get("cell").upper_voltage_cutoff + ocp_n = values.get("negative_electrode").ocp.to_python_function() + ocp_p = values.get("positive_electrode").ocp.to_python_function() + + # Checks the maximum voltage estimated from STO + V_max_sto = ocp_p(sto_p_min) - ocp_n(sto_n_max) + if V_max_sto > V_max: + raise ValueError( + "The maximum voltage computed from the STO limits is higher " + "than the maximum allowed voltage" + ) + + # Checks the minimum voltage estimated from STO + V_min_sto = ocp_p(sto_p_max) - ocp_n(sto_n_min) + if V_min_sto < V_min: + raise ValueError( + "The minimum voltage computed from the STO limits is lower " + "than the minimum allowed voltage" + ) + + return values + class BPX(ExtraBaseModel): header: Header = Field( From e836bbe2c597a03c238ea978bbd68d0436167fa4 Mon Sep 17 00:00:00 2001 From: Ivan Korotkin Date: Mon, 19 Jun 2023 14:43:01 +0100 Subject: [PATCH 04/47] Fixed tests, added target_soc tests --- bpx/schema.py | 10 ++++++++-- bpx/utilities.py | 3 +++ tests/test_utilities.py | 36 ++++++++++++++++++++++++++++++++++++ 3 files changed, 47 insertions(+), 2 deletions(-) diff --git a/bpx/schema.py b/bpx/schema.py index 7e3bc77..74f776b 100644 --- a/bpx/schema.py +++ b/bpx/schema.py @@ -291,17 +291,23 @@ class Parameterisation(ExtraBaseModel): # Validates that the STO limits subbed into the OCPs give # the correct voltage limits. + # Works if both OCPs are defined as functions. # https://docs.pydantic.dev/latest/usage/validators/#root-validators @root_validator def check_sto_limits(cls, values): + try: + ocp_n = values.get("negative_electrode").ocp.to_python_function() + ocp_p = values.get("positive_electrode").ocp.to_python_function() + except AttributeError: + # OCPs defined as interpolated tables; do nothing + return values + sto_n_min = values.get("negative_electrode").minimum_stoichiometry sto_n_max = values.get("negative_electrode").maximum_stoichiometry sto_p_min = values.get("positive_electrode").minimum_stoichiometry sto_p_max = values.get("positive_electrode").maximum_stoichiometry V_min = values.get("cell").lower_voltage_cutoff V_max = values.get("cell").upper_voltage_cutoff - ocp_n = values.get("negative_electrode").ocp.to_python_function() - ocp_p = values.get("positive_electrode").ocp.to_python_function() # Checks the maximum voltage estimated from STO V_max_sto = ocp_p(sto_p_min) - ocp_n(sto_n_max) diff --git a/bpx/utilities.py b/bpx/utilities.py index eb30345..dcb011e 100644 --- a/bpx/utilities.py +++ b/bpx/utilities.py @@ -47,6 +47,9 @@ def get_electrode_concentrations(target_soc, bpx): c_n, c_p The electrode concentrations that give the target state of charge """ + if target_soc < 0 or target_soc > 1: + raise ValueError("Target SOC should be between 0 and 1") + c_n_max = bpx.parameterisation.negative_electrode.maximum_concentration c_p_max = bpx.parameterisation.positive_electrode.maximum_concentration diff --git a/tests/test_utilities.py b/tests/test_utilities.py index 5dfb29a..d4e3086 100644 --- a/tests/test_utilities.py +++ b/tests/test_utilities.py @@ -83,6 +83,42 @@ def test_get_init_conc(self): self.assertAlmostEqual(x, 23060.568) self.assertAlmostEqual(y, 21455.36) + def test_get_init_sto_negative_target_soc(self): + test = copy.copy(self.base) + obj = parse_obj_as(BPX, test) + with self.assertRaisesRegex( + ValueError, + "Target SOC should be between 0 and 1", + ): + get_electrode_stoichiometries(-0.1, obj) + + def test_get_init_sto_bad_target_soc(self): + test = copy.copy(self.base) + obj = parse_obj_as(BPX, test) + with self.assertRaisesRegex( + ValueError, + "Target SOC should be between 0 and 1", + ): + get_electrode_stoichiometries(1.1, obj) + + def test_get_init_conc_negative_target_soc(self): + test = copy.copy(self.base) + obj = parse_obj_as(BPX, test) + with self.assertRaisesRegex( + ValueError, + "Target SOC should be between 0 and 1", + ): + get_electrode_concentrations(-0.5, obj) + + def test_get_init_conc_bad_target_soc(self): + test = copy.copy(self.base) + obj = parse_obj_as(BPX, test) + with self.assertRaisesRegex( + ValueError, + "Target SOC should be between 0 and 1", + ): + get_electrode_concentrations(1.05, obj) + if __name__ == "__main__": unittest.main() From 233f4db8508d6da926c0204bf1e8cba19c46794a Mon Sep 17 00:00:00 2001 From: Ivan Korotkin Date: Mon, 19 Jun 2023 14:44:39 +0100 Subject: [PATCH 05/47] Fix too big maximum concentration in the example --- bpx/schema.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bpx/schema.py b/bpx/schema.py index 74f776b..184e045 100644 --- a/bpx/schema.py +++ b/bpx/schema.py @@ -189,7 +189,7 @@ class Electrode(Contact): ) maximum_concentration: float = Field( alias="Maximum concentration [mol.m-3]", - example=631040, + example=63104.0, description="Maximum concentration of lithium ions in particles", ) particle_radius: float = Field( From 6ca9e7bac98d56ec126e2c33ee7f854128660d41 Mon Sep 17 00:00:00 2001 From: Ivan Korotkin Date: Mon, 19 Jun 2023 15:34:51 +0100 Subject: [PATCH 06/47] Added tests for the STO limit validator --- tests/test_schema.py | 51 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 44 insertions(+), 7 deletions(-) diff --git a/tests/test_schema.py b/tests/test_schema.py index 797910e..a104bc5 100644 --- a/tests/test_schema.py +++ b/tests/test_schema.py @@ -23,7 +23,7 @@ def setUp(self): "Number of electrode pairs connected in parallel to make a cell": 1, "Nominal cell capacity [A.h]": 5.0, "Lower voltage cut-off [V]": 2.0, - "Upper voltage cut-off [V]": 4.0, + "Upper voltage cut-off [V]": 4.5, }, "Electrolyte": { "Initial concentration [mol.m-3]": 1000, @@ -37,29 +37,40 @@ def setUp(self): "Particle radius [m]": 5.86e-6, "Thickness [m]": 85.2e-6, "Diffusivity [m2.s-1]": 3.3e-14, - "OCP [V]": {"x": [0, 0.1, 1], "y": [1.72, 1.2, 0.06]}, + "OCP [V]": ( + "9.47057878e-01 * exp(-1.59418743e+02 * x) - 3.50928033e+04 + " + "1.64230269e-01 * tanh(-4.55509094e+01 * (x - 3.24116012e-02 )) + " + "3.69968491e-02 * tanh(-1.96718868e+01 * (x - 1.68334476e-01)) + " + "1.91517003e+04 * tanh(3.19648312e+00 * (x - 1.85139824e+00)) + " + "5.42448511e+04 * tanh(-3.19009848e+00 * (x - 2.01660395e+00))" + ), "Conductivity [S.m-1]": 215.0, "Surface area per unit volume [m-1]": 383959, "Porosity": 0.25, "Transport efficiency": 0.125, "Reaction rate constant [mol.m-2.s-1]": 1e-10, "Maximum concentration [mol.m-3]": 33133, - "Minimum stoichiometry": 0.01, - "Maximum stoichiometry": 0.99, + "Minimum stoichiometry": 0.005504, + "Maximum stoichiometry": 0.75668, }, "Positive electrode": { "Particle radius [m]": 5.22e-6, "Thickness [m]": 75.6e-6, "Diffusivity [m2.s-1]": 4.0e-15, - "OCP [V]": {"x": [0, 0.1, 1], "y": [1.72, 1.2, 0.06]}, + "OCP [V]": ( + "-3.04420906 * x + 10.04892207 - " + "0.65637536 * tanh(-4.02134095 * (x - 0.80063948)) + " + "4.24678547 * tanh(12.17805062 * (x - 7.57659337)) - " + "0.3757068 * tanh(59.33067782 * (x - 0.99784492))" + ), "Conductivity [S.m-1]": 0.18, "Surface area per unit volume [m-1]": 382184, "Porosity": 0.335, "Transport efficiency": 0.1939, "Reaction rate constant [mol.m-2.s-1]": 1e-10, "Maximum concentration [mol.m-3]": 63104.0, - "Minimum stoichiometry": 0.1, - "Maximum stoichiometry": 0.9, + "Minimum stoichiometry": 0.42424, + "Maximum stoichiometry": 0.96210, }, "Separator": { "Thickness [m]": 1.2e-5, @@ -144,6 +155,32 @@ def test_validation_data(self): }, } + def test_check_sto_limits_validator(self): + test = copy.copy(self.base) + test["Parameterisation"]["Cell"]["Upper voltage cut-off [V]"] = 4.3 + test["Parameterisation"]["Cell"]["Lower voltage cut-off [V]"] = 2.5 + parse_obj_as(BPX, test) + + def test_check_sto_limits_validator_high_voltage(self): + test = copy.copy(self.base) + test["Parameterisation"]["Cell"]["Upper voltage cut-off [V]"] = 4.0 + with self.assertRaisesRegex( + ValidationError, + "The maximum voltage computed from the STO limits is higher " + "than the maximum allowed voltage" + ): + parse_obj_as(BPX, test) + + def test_check_sto_limits_validator_low_voltage(self): + test = copy.copy(self.base) + test["Parameterisation"]["Cell"]["Lower voltage cut-off [V]"] = 3.0 + with self.assertRaisesRegex( + ValidationError, + "The minimum voltage computed from the STO limits is lower " + "than the minimum allowed voltage" + ): + parse_obj_as(BPX, test) + if __name__ == "__main__": unittest.main() From 13397112cde46bbe16773dbc4f3e8de2b3013bf3 Mon Sep 17 00:00:00 2001 From: Ivan Korotkin Date: Mon, 19 Jun 2023 23:21:17 +0100 Subject: [PATCH 07/47] Improved error messages for the STO limits validator --- bpx/schema.py | 8 ++++---- tests/test_schema.py | 12 ++---------- 2 files changed, 6 insertions(+), 14 deletions(-) diff --git a/bpx/schema.py b/bpx/schema.py index 184e045..f5c5723 100644 --- a/bpx/schema.py +++ b/bpx/schema.py @@ -313,16 +313,16 @@ def check_sto_limits(cls, values): V_max_sto = ocp_p(sto_p_min) - ocp_n(sto_n_max) if V_max_sto > V_max: raise ValueError( - "The maximum voltage computed from the STO limits is higher " - "than the maximum allowed voltage" + f"The maximum voltage computed from the STO limits ({V_max_sto} V) " + f"is higher than the maximum allowed voltage ({V_max} V)" ) # Checks the minimum voltage estimated from STO V_min_sto = ocp_p(sto_p_max) - ocp_n(sto_n_min) if V_min_sto < V_min: raise ValueError( - "The minimum voltage computed from the STO limits is lower " - "than the minimum allowed voltage" + f"The minimum voltage computed from the STO limits ({V_min_sto} V) " + f"is lower than the minimum allowed voltage ({V_min} V)" ) return values diff --git a/tests/test_schema.py b/tests/test_schema.py index a104bc5..d2c49a6 100644 --- a/tests/test_schema.py +++ b/tests/test_schema.py @@ -164,21 +164,13 @@ def test_check_sto_limits_validator(self): def test_check_sto_limits_validator_high_voltage(self): test = copy.copy(self.base) test["Parameterisation"]["Cell"]["Upper voltage cut-off [V]"] = 4.0 - with self.assertRaisesRegex( - ValidationError, - "The maximum voltage computed from the STO limits is higher " - "than the maximum allowed voltage" - ): + with self.assertRaises(ValidationError): parse_obj_as(BPX, test) def test_check_sto_limits_validator_low_voltage(self): test = copy.copy(self.base) test["Parameterisation"]["Cell"]["Lower voltage cut-off [V]"] = 3.0 - with self.assertRaisesRegex( - ValidationError, - "The minimum voltage computed from the STO limits is lower " - "than the minimum allowed voltage" - ): + with self.assertRaises(ValidationError): parse_obj_as(BPX, test) From 3a848d759e5e4c0ebbe8a21281a21b107db02579 Mon Sep 17 00:00:00 2001 From: Ivan Korotkin Date: Tue, 20 Jun 2023 09:57:20 +0100 Subject: [PATCH 08/47] Added dict of electrodes for well-mixed blended electrode support --- bpx/schema.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bpx/schema.py b/bpx/schema.py index 07c76f6..4c83e83 100644 --- a/bpx/schema.py +++ b/bpx/schema.py @@ -279,10 +279,10 @@ class Parameterisation(ExtraBaseModel): electrolyte: Electrolyte = Field( alias="Electrolyte", ) - negative_electrode: Electrode = Field( + negative_electrode: Union[Electrode, Dict[str, Electrode]] = Field( alias="Negative electrode", ) - positive_electrode: Electrode = Field( + positive_electrode: Union[Electrode, Dict[str, Electrode]] = Field( alias="Positive electrode", ) separator: Contact = Field( From d03c39ae87dd001910639aeb377a834259060cf5 Mon Sep 17 00:00:00 2001 From: Ivan Korotkin Date: Tue, 20 Jun 2023 11:01:33 +0100 Subject: [PATCH 09/47] Added blended electrode example to the test --- tests/test_schema.py | 40 ++++++++++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/tests/test_schema.py b/tests/test_schema.py index 797910e..551e586 100644 --- a/tests/test_schema.py +++ b/tests/test_schema.py @@ -48,18 +48,34 @@ def setUp(self): "Maximum stoichiometry": 0.99, }, "Positive electrode": { - "Particle radius [m]": 5.22e-6, - "Thickness [m]": 75.6e-6, - "Diffusivity [m2.s-1]": 4.0e-15, - "OCP [V]": {"x": [0, 0.1, 1], "y": [1.72, 1.2, 0.06]}, - "Conductivity [S.m-1]": 0.18, - "Surface area per unit volume [m-1]": 382184, - "Porosity": 0.335, - "Transport efficiency": 0.1939, - "Reaction rate constant [mol.m-2.s-1]": 1e-10, - "Maximum concentration [mol.m-3]": 63104.0, - "Minimum stoichiometry": 0.1, - "Maximum stoichiometry": 0.9, + "Primary": { + "Particle radius [m]": 5.22e-6, + "Thickness [m]": 75.6e-6, + "Diffusivity [m2.s-1]": 4.0e-15, + "OCP [V]": {"x": [0, 0.1, 1], "y": [1.72, 1.2, 0.06]}, + "Conductivity [S.m-1]": 0.18, + "Surface area per unit volume [m-1]": 382184, + "Porosity": 0.335, + "Transport efficiency": 0.1939, + "Reaction rate constant [mol.m-2.s-1]": 1e-10, + "Maximum concentration [mol.m-3]": 63104.0, + "Minimum stoichiometry": 0.1, + "Maximum stoichiometry": 0.9, + }, + "Secondary": { + "Particle radius [m]": 5.22e-6, + "Thickness [m]": 50.0e-6, + "Diffusivity [m2.s-1]": 4.0e-15, + "OCP [V]": {"x": [0, 0.1, 1], "y": [1.72, 1.2, 0.06]}, + "Conductivity [S.m-1]": 0.18, + "Surface area per unit volume [m-1]": 382184, + "Porosity": 0.335, + "Transport efficiency": 0.1939, + "Reaction rate constant [mol.m-2.s-1]": 1e-10, + "Maximum concentration [mol.m-3]": 63104.0, + "Minimum stoichiometry": 0.1, + "Maximum stoichiometry": 0.9, + }, }, "Separator": { "Thickness [m]": 1.2e-5, From 8dc406bb6df6c63e0c7079d0300f2a30998b3d61 Mon Sep 17 00:00:00 2001 From: Ivan Korotkin Date: Tue, 20 Jun 2023 15:22:57 +0100 Subject: [PATCH 10/47] Split electrode properties into chemistry and other, update test --- bpx/schema.py | 27 ++++++++++++++++------- tests/test_schema.py | 52 +++++++++++++++++++++----------------------- 2 files changed, 44 insertions(+), 35 deletions(-) diff --git a/bpx/schema.py b/bpx/schema.py index 4c83e83..7b1719d 100644 --- a/bpx/schema.py +++ b/bpx/schema.py @@ -176,7 +176,7 @@ class Contact(ExtraBaseModel): ) -class Electrode(Contact): +class ElectrodeChemistry(ExtraBaseModel): minimum_stoichiometry: float = Field( alias="Minimum stoichiometry", example=0.1, @@ -216,11 +216,6 @@ class Electrode(Contact): example=17800, description="Activation energy for diffusivity in particles", ) - conductivity: float = Field( - alias="Conductivity [S.m-1]", - example=0.18, - description=("Electrolyte conductivity (constant)"), - ) ocp: FloatFunctionTable = Field( alias="OCP [V]", example={"x": [0, 0.1, 1], "y": [1.72, 1.2, 0.06]}, @@ -248,6 +243,22 @@ class Electrode(Contact): ) +class ElectrodeOther(Contact): + conductivity: float = Field( + alias="Conductivity [S.m-1]", + example=0.18, + description=("Electrolyte conductivity (constant)"), + ) + + +class Electrode(ElectrodeOther, ElectrodeChemistry): + pass + + +class ElectrodeBlended(ElectrodeOther): + chemistry: Dict[str, ElectrodeChemistry] = Field(alias="Chemistry") + + class Experiment(ExtraBaseModel): time: List[float] = Field( alias="Time [s]", @@ -279,10 +290,10 @@ class Parameterisation(ExtraBaseModel): electrolyte: Electrolyte = Field( alias="Electrolyte", ) - negative_electrode: Union[Electrode, Dict[str, Electrode]] = Field( + negative_electrode: Union[Electrode, ElectrodeBlended] = Field( alias="Negative electrode", ) - positive_electrode: Union[Electrode, Dict[str, Electrode]] = Field( + positive_electrode: Union[Electrode, ElectrodeBlended] = Field( alias="Positive electrode", ) separator: Contact = Field( diff --git a/tests/test_schema.py b/tests/test_schema.py index 551e586..63275f6 100644 --- a/tests/test_schema.py +++ b/tests/test_schema.py @@ -48,33 +48,31 @@ def setUp(self): "Maximum stoichiometry": 0.99, }, "Positive electrode": { - "Primary": { - "Particle radius [m]": 5.22e-6, - "Thickness [m]": 75.6e-6, - "Diffusivity [m2.s-1]": 4.0e-15, - "OCP [V]": {"x": [0, 0.1, 1], "y": [1.72, 1.2, 0.06]}, - "Conductivity [S.m-1]": 0.18, - "Surface area per unit volume [m-1]": 382184, - "Porosity": 0.335, - "Transport efficiency": 0.1939, - "Reaction rate constant [mol.m-2.s-1]": 1e-10, - "Maximum concentration [mol.m-3]": 63104.0, - "Minimum stoichiometry": 0.1, - "Maximum stoichiometry": 0.9, - }, - "Secondary": { - "Particle radius [m]": 5.22e-6, - "Thickness [m]": 50.0e-6, - "Diffusivity [m2.s-1]": 4.0e-15, - "OCP [V]": {"x": [0, 0.1, 1], "y": [1.72, 1.2, 0.06]}, - "Conductivity [S.m-1]": 0.18, - "Surface area per unit volume [m-1]": 382184, - "Porosity": 0.335, - "Transport efficiency": 0.1939, - "Reaction rate constant [mol.m-2.s-1]": 1e-10, - "Maximum concentration [mol.m-3]": 63104.0, - "Minimum stoichiometry": 0.1, - "Maximum stoichiometry": 0.9, + "Thickness [m]": 75.6e-6, + "Conductivity [S.m-1]": 0.18, + "Porosity": 0.335, + "Transport efficiency": 0.1939, + "Chemistry": { + "Primary": { + "Particle radius [m]": 5.22e-6, + "Diffusivity [m2.s-1]": 4.0e-15, + "OCP [V]": {"x": [0, 0.1, 1], "y": [1.72, 1.2, 0.06]}, + "Surface area per unit volume [m-1]": 382184, + "Reaction rate constant [mol.m-2.s-1]": 1e-10, + "Maximum concentration [mol.m-3]": 63104.0, + "Minimum stoichiometry": 0.1, + "Maximum stoichiometry": 0.9, + }, + "Secondary": { + "Particle radius [m]": 10.0e-6, + "Diffusivity [m2.s-1]": 4.0e-15, + "OCP [V]": {"x": [0, 0.1, 1], "y": [1.72, 1.2, 0.06]}, + "Surface area per unit volume [m-1]": 382184, + "Reaction rate constant [mol.m-2.s-1]": 1e-10, + "Maximum concentration [mol.m-3]": 63104.0, + "Minimum stoichiometry": 0.1, + "Maximum stoichiometry": 0.9, + }, }, }, "Separator": { From 4a36ec61b98456064d08e33661a59297d41d6ab7 Mon Sep 17 00:00:00 2001 From: Ivan Korotkin Date: Wed, 21 Jun 2023 10:21:57 +0100 Subject: [PATCH 11/47] Renamed classes ElectrodeChemistry and ElectrodeOther to Particle and Electrode, renamed Chemistry field to Particle --- bpx/schema.py | 14 +++++++------- tests/test_schema.py | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/bpx/schema.py b/bpx/schema.py index 7b1719d..9225087 100644 --- a/bpx/schema.py +++ b/bpx/schema.py @@ -176,7 +176,7 @@ class Contact(ExtraBaseModel): ) -class ElectrodeChemistry(ExtraBaseModel): +class Particle(ExtraBaseModel): minimum_stoichiometry: float = Field( alias="Minimum stoichiometry", example=0.1, @@ -243,7 +243,7 @@ class ElectrodeChemistry(ExtraBaseModel): ) -class ElectrodeOther(Contact): +class Electrode(Contact): conductivity: float = Field( alias="Conductivity [S.m-1]", example=0.18, @@ -251,12 +251,12 @@ class ElectrodeOther(Contact): ) -class Electrode(ElectrodeOther, ElectrodeChemistry): +class ElectrodeSingle(Electrode, Particle): pass -class ElectrodeBlended(ElectrodeOther): - chemistry: Dict[str, ElectrodeChemistry] = Field(alias="Chemistry") +class ElectrodeBlended(Electrode): + particle: Dict[str, Particle] = Field(alias="Particle") class Experiment(ExtraBaseModel): @@ -290,10 +290,10 @@ class Parameterisation(ExtraBaseModel): electrolyte: Electrolyte = Field( alias="Electrolyte", ) - negative_electrode: Union[Electrode, ElectrodeBlended] = Field( + negative_electrode: Union[ElectrodeSingle, ElectrodeBlended] = Field( alias="Negative electrode", ) - positive_electrode: Union[Electrode, ElectrodeBlended] = Field( + positive_electrode: Union[ElectrodeSingle, ElectrodeBlended] = Field( alias="Positive electrode", ) separator: Contact = Field( diff --git a/tests/test_schema.py b/tests/test_schema.py index 63275f6..5fae2cf 100644 --- a/tests/test_schema.py +++ b/tests/test_schema.py @@ -52,7 +52,7 @@ def setUp(self): "Conductivity [S.m-1]": 0.18, "Porosity": 0.335, "Transport efficiency": 0.1939, - "Chemistry": { + "Particle": { "Primary": { "Particle radius [m]": 5.22e-6, "Diffusivity [m2.s-1]": 4.0e-15, From bed16f895ff879b29db3b6cd72b24a5e34f5037d Mon Sep 17 00:00:00 2001 From: Ivan Korotkin Date: Wed, 21 Jun 2023 17:30:26 +0100 Subject: [PATCH 12/47] First attempt to add validation based on models according to issue #29 --- bpx/schema.py | 47 ++++++++++++++++++-- tests/test_schema.py | 100 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 144 insertions(+), 3 deletions(-) diff --git a/bpx/schema.py b/bpx/schema.py index 9225087..b0e0e15 100644 --- a/bpx/schema.py +++ b/bpx/schema.py @@ -1,6 +1,6 @@ from typing import List, Literal, Union, Dict -from pydantic import BaseModel, Field, Extra +from pydantic import BaseModel, Field, Extra, root_validator from bpx import Function, InterpolatedTable @@ -158,12 +158,15 @@ class Electrolyte(ExtraBaseModel): ) -class Contact(ExtraBaseModel): +class ContactBase(ExtraBaseModel): thickness: float = Field( alias="Thickness [m]", example=85.2e-6, description="Contact thickness", ) + + +class Contact(ContactBase): porosity: float = Field( alias="Porosity", example=0.47, @@ -259,6 +262,14 @@ class ElectrodeBlended(Electrode): particle: Dict[str, Particle] = Field(alias="Particle") +class ElectrodeSingleSPM(ContactBase, Particle): + pass + + +class ElectrodeBlendedSPM(ContactBase): + particle: Dict[str, Particle] = Field(alias="Particle") + + class Experiment(ExtraBaseModel): time: List[float] = Field( alias="Time [s]", @@ -301,9 +312,39 @@ class Parameterisation(ExtraBaseModel): ) +class ParameterisationSPM(ExtraBaseModel): + cell: Cell = Field( + alias="Cell", + ) + negative_electrode: Union[ElectrodeSingleSPM, ElectrodeBlendedSPM] = Field( + alias="Negative electrode", + ) + positive_electrode: Union[ElectrodeSingleSPM, ElectrodeBlendedSPM] = Field( + alias="Positive electrode", + ) + + class BPX(ExtraBaseModel): header: Header = Field( alias="Header", ) - parameterisation: Parameterisation = Field(alias="Parameterisation") + parameterisation: Union[ParameterisationSPM, Parameterisation] = Field( + alias="Parameterisation" + ) validation: Dict[str, Experiment] = Field(None, alias="Validation") + + @root_validator(skip_on_failure=True) + def model_based_validation(cls, values): + model = values.get("header").model + parameter_class_name = values.get("parameterisation").__class__.__name__ + allowed_combinations = [ + ("Parameterisation", "DFN"), + ("Parameterisation", "SPMe"), + ("ParameterisationSPM", "SPM"), + ] + if (parameter_class_name, model) in allowed_combinations: + return values + else: + raise ValueError( + f"The model type {model} does not correspond to the parameter set" + ) diff --git a/tests/test_schema.py b/tests/test_schema.py index 5fae2cf..034e412 100644 --- a/tests/test_schema.py +++ b/tests/test_schema.py @@ -83,10 +83,110 @@ def setUp(self): }, } + # SPM parameter set + self.base_spm = { + "Header": { + "BPX": 1.0, + "Model": "SPM", + }, + "Parameterisation": { + "Cell": { + "Ambient temperature [K]": 299.0, + "Initial temperature [K]": 299.0, + "Reference temperature [K]": 299.0, + "Electrode area [m2]": 2.0, + "External surface area [m2]": 2.2, + "Volume [m3]": 1.0, + "Number of electrode pairs connected in parallel to make a cell": 1, + "Nominal cell capacity [A.h]": 5.0, + "Lower voltage cut-off [V]": 2.0, + "Upper voltage cut-off [V]": 4.0, + }, + "Negative electrode": { + "Particle radius [m]": 5.86e-6, + "Thickness [m]": 85.2e-6, + "Diffusivity [m2.s-1]": 3.3e-14, + "OCP [V]": {"x": [0, 0.1, 1], "y": [1.72, 1.2, 0.06]}, + "Surface area per unit volume [m-1]": 383959, + "Reaction rate constant [mol.m-2.s-1]": 1e-10, + "Maximum concentration [mol.m-3]": 33133, + "Minimum stoichiometry": 0.01, + "Maximum stoichiometry": 0.99, + }, + "Positive electrode": { + "Thickness [m]": 75.6e-6, + "Particle": { + "Primary": { + "Particle radius [m]": 5.22e-6, + "Diffusivity [m2.s-1]": 4.0e-15, + "OCP [V]": {"x": [0, 0.1, 1], "y": [1.72, 1.2, 0.06]}, + "Surface area per unit volume [m-1]": 382184, + "Reaction rate constant [mol.m-2.s-1]": 1e-10, + "Maximum concentration [mol.m-3]": 63104.0, + "Minimum stoichiometry": 0.1, + "Maximum stoichiometry": 0.9, + }, + "Secondary": { + "Particle radius [m]": 10.0e-6, + "Diffusivity [m2.s-1]": 4.0e-15, + "OCP [V]": {"x": [0, 0.1, 1], "y": [1.72, 1.2, 0.06]}, + "Surface area per unit volume [m-1]": 382184, + "Reaction rate constant [mol.m-2.s-1]": 1e-10, + "Maximum concentration [mol.m-3]": 63104.0, + "Minimum stoichiometry": 0.1, + "Maximum stoichiometry": 0.9, + }, + }, + }, + }, + } + def test_simple(self): test = copy.copy(self.base) parse_obj_as(BPX, test) + def test_simple_spme(self): + test = copy.copy(self.base) + test["Header"]["Model"] = "SPMe" + parse_obj_as(BPX, test) + + def test_simple_spm(self): + test = copy.copy(self.base_spm) + parse_obj_as(BPX, test) + + def test_bad_model(self): + test = copy.copy(self.base) + test["Header"]["Model"] = "Wrong model type" + with self.assertRaises(ValidationError): + parse_obj_as(BPX, test) + + def test_bad_dfn(self): + test = copy.copy(self.base_spm) + test["Header"]["Model"] = "DFN" + with self.assertRaisesRegex( + ValidationError, + "The model type DFN does not correspond to the parameter set", + ): + parse_obj_as(BPX, test) + + def test_bad_spme(self): + test = copy.copy(self.base_spm) + test["Header"]["Model"] = "SPMe" + with self.assertRaisesRegex( + ValidationError, + "The model type SPMe does not correspond to the parameter set", + ): + parse_obj_as(BPX, test) + + def test_bad_spm(self): + test = copy.copy(self.base) + test["Header"]["Model"] = "SPM" + with self.assertRaisesRegex( + ValidationError, + "The model type SPM does not correspond to the parameter set", + ): + parse_obj_as(BPX, test) + def test_table(self): test = copy.copy(self.base) test["Parameterisation"]["Electrolyte"]["Conductivity [S.m-1]"] = { From 5eeb7e929fae90483624f2bba8ee8d11a51ba20d Mon Sep 17 00:00:00 2001 From: Ivan Korotkin Date: Wed, 21 Jun 2023 17:52:56 +0100 Subject: [PATCH 13/47] Add skip_on_failure for the sto limit validator (no need to check the sto limits if basic checks are not successful) --- bpx/schema.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/bpx/schema.py b/bpx/schema.py index f5c5723..312bf92 100644 --- a/bpx/schema.py +++ b/bpx/schema.py @@ -289,11 +289,10 @@ class Parameterisation(ExtraBaseModel): alias="Separator", ) - # Validates that the STO limits subbed into the OCPs give - # the correct voltage limits. + # Validates that the STO limits subbed into the OCPs give the correct voltage limits. # Works if both OCPs are defined as functions. # https://docs.pydantic.dev/latest/usage/validators/#root-validators - @root_validator + @root_validator(skip_on_failure=True) def check_sto_limits(cls, values): try: ocp_n = values.get("negative_electrode").ocp.to_python_function() From 8ad4272d9a545066a217ec5cf540690796709c9d Mon Sep 17 00:00:00 2001 From: Robert Timms Date: Thu, 31 Aug 2023 22:17:28 +0100 Subject: [PATCH 14/47] #26 allow user-defined params --- bpx/schema.py | 22 +++++++++++++++++++--- tests/test_schema.py | 20 ++++++++++++++++++++ 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/bpx/schema.py b/bpx/schema.py index 07c76f6..bd13ed8 100644 --- a/bpx/schema.py +++ b/bpx/schema.py @@ -1,10 +1,10 @@ -from typing import List, Literal, Union, Dict +from typing import List, Literal, Union, Dict, get_args -from pydantic import BaseModel, Field, Extra +from pydantic import BaseModel, Field, Extra, root_validator from bpx import Function, InterpolatedTable -FloatFunctionTable = Union[float, Function, InterpolatedTable] +FloatFunctionTable = Union[int, float, Function, InterpolatedTable] class ExtraBaseModel(BaseModel): @@ -248,6 +248,18 @@ class Electrode(Contact): ) +class UserDefined(BaseModel): + class Config: + extra = Extra.allow + + @root_validator(pre=True) + def validate_extra_fields(cls, values): + for k, v in values.items(): + if not isinstance(v, get_args(FloatFunctionTable)): + raise TypeError(f"{k} must be of type 'FloatFunctionTable'") + return values + + class Experiment(ExtraBaseModel): time: List[float] = Field( alias="Time [s]", @@ -288,6 +300,10 @@ class Parameterisation(ExtraBaseModel): separator: Contact = Field( alias="Separator", ) + user_defined: UserDefined = Field( + None, + alias="User defined", + ) class BPX(ExtraBaseModel): diff --git a/tests/test_schema.py b/tests/test_schema.py index 797910e..e03488e 100644 --- a/tests/test_schema.py +++ b/tests/test_schema.py @@ -144,6 +144,26 @@ def test_validation_data(self): }, } + def test_user_defined(self): + test = copy.copy(self.base) + test["Parameterisation"]["User defined"] = { + "a": 1, + "b": 2.0, + "c": 3.0, + } + obj = parse_obj_as(BPX, test) + self.assertEqual(obj.parameterisation.user_defined.a, 1) + self.assertEqual(obj.parameterisation.user_defined.b, 2) + self.assertEqual(obj.parameterisation.user_defined.c, 3) + + def test_bad_user_defined(self): + test = copy.copy(self.base) + test["Parameterisation"]["User defined"] = { + "bad": "strings aren't allowed", + } + with self.assertRaises(ValidationError): + parse_obj_as(BPX, test) + if __name__ == "__main__": unittest.main() From 274dc79a37d1497d515eddb5c849776454e88f63 Mon Sep 17 00:00:00 2001 From: Robert Timms Date: Thu, 31 Aug 2023 22:20:23 +0100 Subject: [PATCH 15/47] #26 changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 31b32cf..7993cc5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# Unreleased +- Allow user-defined parameters to be added using the field ["Parameterisation"]["User-Defined"] ([#44](https://github.com/pybamm-team/BPX/pull/44)) + + # [v0.3.0](https://github.com/pybamm-team/BPX/releases/tag/v0.3.1) - Temporarily pin Pydantic version ([#35](https://github.com/pybamm-team/BPX/pull/35)) # [v0.3.0](https://github.com/pybamm-team/BPX/releases/tag/v0.3.0) From f933a1538bff789bf8e22e210270d6367bd20f70 Mon Sep 17 00:00:00 2001 From: Robert Timms Date: Thu, 31 Aug 2023 21:32:02 +0100 Subject: [PATCH 16/47] update docs and README.md --- CHANGELOG.md | 2 +- docs/CONTRIBUTING.md => CONTRIBUTING.md | 0 README.md | 46 ++-- docs/Makefile | 19 ++ docs/_static/main.css | 144 ++++++++++++ docs/conf.py | 254 ++++++++++++++++++++++ docs/index.rst | 24 ++ docs/make.bat | 35 +++ docs/source/api/expression_parser.rst | 5 + docs/source/api/function.rst | 5 + docs/source/api/index.rst | 24 ++ docs/source/api/interpolated_table.rst | 5 + docs/source/api/parsers.rst | 8 + docs/source/api/schema.rst | 5 + docs/source/api/utilities.rst | 6 + docs/source/user_guide/getting_started.md | 47 ++++ docs/source/user_guide/index.md | 16 ++ docs/source/user_guide/installation.md | 50 +++++ pyproject.toml | 8 + 19 files changed, 678 insertions(+), 25 deletions(-) rename docs/CONTRIBUTING.md => CONTRIBUTING.md (100%) create mode 100644 docs/Makefile create mode 100644 docs/_static/main.css create mode 100644 docs/conf.py create mode 100644 docs/index.rst create mode 100644 docs/make.bat create mode 100644 docs/source/api/expression_parser.rst create mode 100644 docs/source/api/function.rst create mode 100644 docs/source/api/index.rst create mode 100644 docs/source/api/interpolated_table.rst create mode 100644 docs/source/api/parsers.rst create mode 100644 docs/source/api/schema.rst create mode 100644 docs/source/api/utilities.rst create mode 100644 docs/source/user_guide/getting_started.md create mode 100644 docs/source/user_guide/index.md create mode 100644 docs/source/user_guide/installation.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 31b32cf..59b644b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -# [v0.3.0](https://github.com/pybamm-team/BPX/releases/tag/v0.3.1) +# [v0.3.1](https://github.com/pybamm-team/BPX/releases/tag/v0.3.1) - Temporarily pin Pydantic version ([#35](https://github.com/pybamm-team/BPX/pull/35)) # [v0.3.0](https://github.com/pybamm-team/BPX/releases/tag/v0.3.0) diff --git a/docs/CONTRIBUTING.md b/CONTRIBUTING.md similarity index 100% rename from docs/CONTRIBUTING.md rename to CONTRIBUTING.md diff --git a/README.md b/README.md index cab36bd..14f40e4 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# BPX +# 🔋 BPX ![tests](https://github.com/pybamm-team/BPX/actions/workflows/test.yml/badge.svg) [![codecov](https://codecov.io/gh/pybamm-team/BPX/branch/main/graph/badge.svg?token=Krv0JW3gYZ)](https://codecov.io/gh/pybamm-team/BPX) @@ -9,38 +9,26 @@ This repository features a Pydantic-based parser for JSON files in the BPX forma To support the new open standard, [About:Energy](https://www.aboutenergy.io/) have supplied two parameters sets for an NMC and LFP cell. The BPX files and associated examples and information can be found on the [A:E BPX Parameterisation repository](https://github.com/About-Energy-OpenSource/About-Energy-BPX-Parameterisation/). To see how to use BPX with [PyBaMM](https://www.pybamm.org/), check out the [BPX example repository](https://github.com/pybamm-team/bpx-example). -## Prerequisites - -- Python 3+ - -## Installation - -Create a new virtual environment, or activate an existing one (this example uses the python `venv` module, but you could use Anaconda and a `conda` environment) - -```bash -python3 -m venv env -source env/bin/activate -``` - -Install the `BPX` module using pip +## 🚀 Installation +The BPX package can be installed using pip ```bash pip install bpx ``` -## Usage - -Create a python script similar to that below +BPX is available on GNU/Linux, MacOS and Windows. We strongly recommend to install PyBaMM within a python [virtual environment](https://docs.python.org/3/tutorial/venv.html), in order not to alter any distribution python files. +## 💻 Usage +To create a BPX object from a JSON file, you can use the `parse_bpx_file` function ```python import bpx filename = 'path/to/my/file.json' my_params = bpx.parse_bpx_file(filename) ``` +`my_params` will now be of type `BPX`, which acts like a python dataclass with the same attributes as the BPX format. To obatin example files, see the [A:E BPX Parameterisation repository](https://github.com/About-Energy-OpenSource/About-Energy-BPX-Parameterisation/) or [BPX example repository](https://github.com/pybamm-team/bpx-example). -`my_params` will now be of type `BPX`, which acts like a python dataclass with the same attributes as the BPX format. For example, you can print out the initial temperature of the cell using - +Attributes of the class can be printed out using the standard Python dot notation, for example, you can print out the initial temperature of the cell using ```python print('Initial temperature of cell:', my_params.parameterisation.cell.initial_temperature) ``` @@ -51,15 +39,13 @@ my_params_dict = my_params.dict(by_alias=True) print('Initial temperature of cell:', my_params_dict["Parameterisation"]["Cell"]["Initial temperature [K]"]) ``` -If you want to pretty print the entire object, you can use the `devtools` package to do this (remember to `pip install devtools`) - +The entire BPX object can be pretty printed using the `devtools` package ```python from devtools import pprint pprint(my_params) ``` You can convert any `Function` objects in `BPX` to regular callable Python functions, for example: - ```python positive_electrode_diffusivity = my_params.parameterisation.positive_electrode.diffusivity.to_python_function() diff_at_one = positive_electrode_diffusivity(1.0) @@ -67,9 +53,21 @@ print('positive electrode diffusivity at x = 1.0:', diff_at_one) ``` If you want to output the complete JSON schema in order to build a custom tool yourself, you can do so: - ```python print(bpx.BPX.schema_json(indent=2)) ``` According to the `pydantic` docs, the generated schemas are compliant with the specifications: JSON Schema Core, JSON Schema Validation and OpenAPI. + +## 📖 Documentation +API documentation for the `bpx` package can be built locally using [Sphinx](https://www.sphinx-doc.org/en/master/). To build the documentation first [clone the repository](https://github.com/git-guides/git-clone), then run the following command: +```bash +sphinx-build docs docs/_build/html +``` +This will generate a number of html files in the `docs/_build/html` directory. To view the documentation, open the file `docs/_build/html/index.html` in a web browser, e.g. by running +```bash +open docs/_build/html/index.html +``` + +## 📫 Get in touch +If you have any questions please get in touch via email . diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 0000000..46d9ea6 --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,19 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = -j auto +SPHINXBUILD = sphinx-build +SOURCEDIR = . +BUILDDIR = _build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/docs/_static/main.css b/docs/_static/main.css new file mode 100644 index 0000000..9705ee5 --- /dev/null +++ b/docs/_static/main.css @@ -0,0 +1,144 @@ +@import url("https://fonts.googleapis.com/css2?family=Lato:ital,wght@0,400;0,700;0,900;1,400;1,700;1,900&family=Open+Sans:ital,wght@0,400;0,600;1,400;1,600&display=swap"); + +.navbar-brand img { + height: 50px; +} + +.navbar-brand { + height: 50px; +} + +body { + font-family: "Open Sans", sans-serif; +} + +pre, +code { + font-size: 100%; + line-height: 155%; +} + +h1 { + font-family: "Lato", sans-serif; + color: #013243; + /* warm black */ +} + +h2 { + color: #4d77cf; + /* han blue */ + letter-spacing: -0.03em; +} + +h3 { + color: #013243; + /* warm black */ + letter-spacing: -0.03em; +} + +/* Style the active version button. + +- latest: orange +- stable: green +- old, PR: red + +Colors from: + +Wong, B. Points of view: Color blindness. +Nat Methods 8, 441 (2011). https://doi.org/10.1038/nmeth.1618 +*/ + +/* If the active version has the name "latest", style it orange */ +.version-switcher__button[data-active-version-name*="latest"] { + background-color: #e69f00; + border-color: #e69f00; + color: #000000; +} + +/* green for `stable` */ +.version-switcher__button[data-active-version-name*="stable"] { + background-color: #009e73; + border-color: #009e73; +} + +/* red for `old` */ +.version-switcher__button:not([data-active-version-name*="latest"], + [data-active-version-name*="stable"]) { + background-color: #980f0f; + border-color: #980f0f; +} + +/* Main page overview cards */ + +.sd-card { + background: #fff; + border-radius: 0; + padding: 30px 10px 20px 10px; + margin: 10px 0px; +} + +.sd-card .sd-card-header { + text-align: center; +} + +.sd-card .sd-card-header .sd-card-text { + margin: 0px; +} + +.sd-card .sd-card-img-top { + height: 52px; + width: 52px; + margin-left: auto; + margin-right: auto; +} + +.sd-card .sd-card-header { + border: none; + background-color: white; + color: #150458 !important; + font-size: var(--pst-font-size-h5); + font-weight: bold; + padding: 2.5rem 0rem 0.5rem 0rem; +} + +.sd-card .sd-card-footer { + border: none; + background-color: white; +} + +.sd-card .sd-card-footer .sd-card-text { + max-width: 220px; + margin-left: auto; + margin-right: auto; +} + +/* Dark theme tweaking */ +html[data-theme="dark"] .sd-card img[src*=".svg"] { + filter: invert(0.82) brightness(0.8) contrast(1.2); +} + +/* Main index page overview cards */ +html[data-theme="dark"] .sd-card { + background-color: var(--pst-color-background); +} + +html[data-theme="dark"] .sd-shadow-sm { + box-shadow: 0 0.1rem 1rem rgba(250, 250, 250, 0.6) !important; +} + +html[data-theme="dark"] .sd-card .sd-card-header { + background-color: var(--pst-color-background); + color: #150458 !important; +} + +html[data-theme="dark"] .sd-card .sd-card-footer { + background-color: var(--pst-color-background); +} + +html[data-theme="dark"] h1 { + color: var(--pst-color-primary); +} + +html[data-theme="dark"] h3 { + color: #0a6774; +} diff --git a/docs/conf.py b/docs/conf.py new file mode 100644 index 0000000..15ca9c6 --- /dev/null +++ b/docs/conf.py @@ -0,0 +1,254 @@ +# -*- coding: utf-8 -*- +# +# Configuration file for the Sphinx documentation builder. +# +# This file does only contain a selection of the most common options. For a +# full list see the documentation: +# http://www.sphinx-doc.org/en/master/config + +# -- Path setup -------------------------------------------------------------- + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +import os +import sys +import bpx + +# Path for repository root +sys.path.insert(0, os.path.abspath("../")) + +# Path for local Sphinx extensions +sys.path.append(os.path.abspath("./sphinxext/")) + + +# -- Project information ----------------------------------------------------- + +project = "BPX" +copyright = "2022, University of Oxford" +author = "Martin Robinson" + +# The short X.Y version +version = bpx.__version__ +# The full version, including alpha/beta/rc tags +release = version + + +# -- General configuration --------------------------------------------------- + +# If your documentation needs a minimal Sphinx version, state it here. +# +# needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + "sphinx.ext.autodoc", + "sphinx.ext.autosummary", + "sphinx.ext.doctest", + "sphinx.ext.intersphinx", + "sphinx.ext.mathjax", + "sphinx.ext.viewcode", + "sphinx.ext.napoleon", + "sphinx_design", + "sphinx_copybutton", + "myst_parser", + "sphinx_inline_tabs", +] + + +napoleon_use_rtype = True +napoleon_google_docstring = False + +doctest_global_setup = """ +from docs import * +""" + +# Add any paths that contain templates here, relative to this directory. +templates_path = ["_templates"] + +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: +# +# source_suffix = ['.rst', '.md'] +source_suffix = ".rst" + +# The master toctree document. +master_doc = "index" + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +language = "en" + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This pattern also affects html_static_path and html_extra_path. +exclude_patterns = ["_build", "Thumbs.db", ".DS_Store", ".ipynb_checkpoints"] + +# Suppress warnings generated by Sphinx and/or by Sphinx extensions +suppress_warnings = ["git.too_shallow"] + +# -- Options for HTML output ------------------------------------------------- + +html_theme = "pydata_sphinx_theme" + +html_static_path = ["_static"] + +# Theme + +# pydata theme options (see +# https://pydata-sphinx-theme.readthedocs.io/en/latest/index.html# for more information) +# mostly copied from numpy, scipy, pandas +# html_logo = "_static/logo.png" +# html_favicon = "_static/favicon/favicon.png" + +html_theme_options = { + "icon_links": [ + { + "name": "GitHub", + "url": "https://github.com/pybamm-team/bpx", + "icon": "fa-brands fa-square-github", + }, + { + "name": "PyPI", + "url": "https://pypi.org/project/bpx/", + "icon": "fa-solid fa-box", + }, + ], + "collapse_navigation": True, + "external_links": [ + { + "name": "Contributing", + "url": "https://github.com/pybamm-team/bpx/tree/develop/CONTRIBUTING.md", + }, + ], + "footer_start": [ + "copyright", + "sphinx-version", + ], + "footer_end": [ + "theme-version", + "last-updated", + ], +} + +html_title = "%s v%s Manual" % (project, version) +html_last_updated_fmt = "%Y-%m-%d" +html_css_files = ["main.css"] +html_context = {"default_mode": "light"} +html_use_modindex = True +html_copy_source = False +html_domain_indices = False +html_file_suffix = ".html" + +htmlhelp_basename = "bpx" + +html_sidebars = {"**": ["sidebar-nav-bs.html"]} + +# For edit button +html_context = { + "github_user": "pybamm-team", + "github_repo": "bpx", + "github_version": "main", + "doc_path": "docs/", +} + + +# -- Options for HTMLHelp output --------------------------------------------- + +# Output file base name for HTML help builder. +htmlhelp_basename = "BPXdoc" + + +# -- Options for LaTeX output ------------------------------------------------ + +# Note: we exclude the examples directory from the LaTeX build because it has +# problems with the creation of PDFs on Read the Docs +# https://github.com/readthedocs/readthedocs.org/issues/2045 + +# Detect if we are building LaTeX output through the invocation of the build commands +if any("latex" in arg for arg in sys.argv) or any("latexmk" in arg for arg in sys.argv): + exclude_patterns.append("source/examples/*") + print("Skipping compilation of .ipynb files for LaTeX build.") + +latex_elements = { + # The paper size ('letterpaper' or 'a4paper'). + # + # 'papersize': 'letterpaper', + # The font size ('10pt', '11pt' or '12pt'). + # + # 'pointsize': '10pt', + # Additional stuff for the LaTeX preamble. + # + # 'preamble': '', + # Latex figure (float) alignment + # + # 'figure_align': 'htbp', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [(master_doc, "BPX.tex", "BPX Documentation", author, "manual")] + + +# -- Options for manual page output ------------------------------------------ + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [(master_doc, "bpx", "BPX Documentation", [author], 1)] + + +# -- Options for Texinfo output ---------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + ( + master_doc, + "BPX", + "BPX Documentation", + author, + "BPX", + "One line description of project.", + "Miscellaneous", + ) +] + + +# -- Options for Epub output ------------------------------------------------- + +# Bibliographic Dublin Core info. +epub_title = project + +# The unique identifier of the text. This can be a ISBN number +# or the project homepage. +# +# epub_identifier = '' + +# A unique identification for the text. +# +# epub_uid = '' + +# A list of files that should not be packed into the epub file. +epub_exclude_files = ["search.html"] + + +# -- Extension configuration ------------------------------------------------- + +# -- Options for intersphinx extension --------------------------------------- + +# Example configuration for intersphinx: refer to the Python standard library. +intersphinx_mapping = { + "python": ("https://docs.python.org/3/", None), + "sphinx": ("https://www.sphinx-doc.org/en/master/", None), + "numpy": ("https://numpy.org/doc/stable", None), + "scipy": ("https://docs.scipy.org/doc/scipy", None), + "matplotlib": ("https://matplotlib.org/stable/", None), +} diff --git a/docs/index.rst b/docs/index.rst new file mode 100644 index 0000000..47685f4 --- /dev/null +++ b/docs/index.rst @@ -0,0 +1,24 @@ +.. Root of all bpx docs + +################# +BPX documentation +################# + +.. This TOC defines what goes in the top navbar +.. toctree:: + :maxdepth: 1 + :hidden: + + User Guide + source/api/index + +**Version**: |version| + +**Useful links**: +`Project Home Page `_ | +`Installation `_ | +`Source Repository `_ | +`Issue Tracker `_ | +`Discussions `_ + +BPX, an outcome of the Faraday Institution Multi-scale Modelling project, is an open standard for physics-based Li-ion battery models that has been developed to reduce costs and time-to-market through a common definition of physics-based battery models that can be used widely across industry. diff --git a/docs/make.bat b/docs/make.bat new file mode 100644 index 0000000..27f573b --- /dev/null +++ b/docs/make.bat @@ -0,0 +1,35 @@ +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set SOURCEDIR=. +set BUILDDIR=_build + +if "%1" == "" goto help + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.http://sphinx-doc.org/ + exit /b 1 +) + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% + +:end +popd diff --git a/docs/source/api/expression_parser.rst b/docs/source/api/expression_parser.rst new file mode 100644 index 0000000..5f74e22 --- /dev/null +++ b/docs/source/api/expression_parser.rst @@ -0,0 +1,5 @@ +Expression Parser +================= + +.. autoclass:: bpx.ExpressionParser + :members: diff --git a/docs/source/api/function.rst b/docs/source/api/function.rst new file mode 100644 index 0000000..0ceb1cb --- /dev/null +++ b/docs/source/api/function.rst @@ -0,0 +1,5 @@ +Function +======== + +.. autoclass:: bpx.Function + :members: diff --git a/docs/source/api/index.rst b/docs/source/api/index.rst new file mode 100644 index 0000000..19e8b61 --- /dev/null +++ b/docs/source/api/index.rst @@ -0,0 +1,24 @@ +.. module:: bpx + +.. _api_docs: + +################# +API documentation +################# + +:Release: |version| +:Date: |today| + +This reference manual details functions, modules, and objects +included in BPX, describing what they are and what they do. +For a high-level introduction to BPX, see the :ref:`user guide `. + +.. toctree:: + :maxdepth: 2 + + expression_parser + function + interpolated_table + parsers + schema + utilities diff --git a/docs/source/api/interpolated_table.rst b/docs/source/api/interpolated_table.rst new file mode 100644 index 0000000..c6dcdcf --- /dev/null +++ b/docs/source/api/interpolated_table.rst @@ -0,0 +1,5 @@ +Interpolated Table +================== + +.. autoclass:: bpx.InterpolatedTable + :members: diff --git a/docs/source/api/parsers.rst b/docs/source/api/parsers.rst new file mode 100644 index 0000000..d5ece0b --- /dev/null +++ b/docs/source/api/parsers.rst @@ -0,0 +1,8 @@ +Parsers +======= + +.. autofunction:: bpx.parse_bpx_str + +.. autofunction:: bpx.parse_bpx_obj + +.. autofunction:: bpx.parse_bpx_file diff --git a/docs/source/api/schema.rst b/docs/source/api/schema.rst new file mode 100644 index 0000000..991f184 --- /dev/null +++ b/docs/source/api/schema.rst @@ -0,0 +1,5 @@ +Schema +====== + +.. autoclass:: bpx.BPX + :members: diff --git a/docs/source/api/utilities.rst b/docs/source/api/utilities.rst new file mode 100644 index 0000000..be4f5bf --- /dev/null +++ b/docs/source/api/utilities.rst @@ -0,0 +1,6 @@ +Utilities +========= + +.. autofunction:: bpx.get_electrode_stoichiometries + +.. autofunction:: bpx.get_electrode_concentrations diff --git a/docs/source/user_guide/getting_started.md b/docs/source/user_guide/getting_started.md new file mode 100644 index 0000000..ee8f3c2 --- /dev/null +++ b/docs/source/user_guide/getting_started.md @@ -0,0 +1,47 @@ +# Getting Started + +To get started, first install the `BPX` module using pip +```bash +pip install bpx +``` +For more detailed installation instructions, see [](installation). + +To create a BPX object from a JSON file, you can use the `parse_bpx_file` function +```python +import bpx + +filename = 'path/to/my/file.json' +my_params = bpx.parse_bpx_file(filename) +``` +`my_params` will now be of type `BPX`, which acts like a python dataclass with the same attributes as the BPX format. To obatin example files, see the [A:E BPX Parameterisation repository](https://github.com/About-Energy-OpenSource/About-Energy-BPX-Parameterisation/) or [BPX example repository](https://github.com/pybamm-team/bpx-example). + +Attributes of the class can be printed out using the standard Python dot notation, for example, you can print out the initial temperature of the cell using +```python +print('Initial temperature of cell:', my_params.parameterisation.cell.initial_temperature) +``` + +Alternatively, you can export the `BPX` object as a dictionary and use the string names (aliases) of the parameters from the standard +```python +my_params_dict = my_params.dict(by_alias=True) +print('Initial temperature of cell:', my_params_dict["Parameterisation"]["Cell"]["Initial temperature [K]"]) +``` + +The entire BPX object can be pretty printed using the `devtools` package +```python +from devtools import pprint +pprint(my_params) +``` + +You can convert any `Function` objects in `BPX` to regular callable Python functions, for example: +```python +positive_electrode_diffusivity = my_params.parameterisation.positive_electrode.diffusivity.to_python_function() +diff_at_one = positive_electrode_diffusivity(1.0) +print('positive electrode diffusivity at x = 1.0:', diff_at_one) +``` + +If you want to output the complete JSON schema in order to build a custom tool yourself, you can do so: +```python +print(bpx.BPX.schema_json(indent=2)) +``` + +According to the `pydantic` docs, the generated schemas are compliant with the specifications: JSON Schema Core, JSON Schema Validation and OpenAPI. diff --git a/docs/source/user_guide/index.md b/docs/source/user_guide/index.md new file mode 100644 index 0000000..f6981f2 --- /dev/null +++ b/docs/source/user_guide/index.md @@ -0,0 +1,16 @@ +(user_guide)= + +# BPX user guide + +This guide is an overview and explains the important features; +details are found in [](api_docs). + +```{toctree} +--- +caption: Contributing +maxdepth: 1 +--- + +installation +getting_started +``` diff --git a/docs/source/user_guide/installation.md b/docs/source/user_guide/installation.md new file mode 100644 index 0000000..97e1921 --- /dev/null +++ b/docs/source/user_guide/installation.md @@ -0,0 +1,50 @@ +# Installation +We recommend installing within a [virtual environment](https://docs.python.org/3/tutorial/venv.html) in order to not alter any python distribution files on your machine. + +## Linux/Mac OS + +To install BPX on Linux/Mac OS use the following terminal commands: + +1. Create a virtual environment + +```bash +virtualenv env +``` + +2. Activate the virtual environment + +```bash +source env/bin/activate +``` + +3. Install the `bpx` package + +```bash +pip install bpx +``` + +## Windows + +To install BPX on Windows use the following commands: + +1. Create a virtual environment + +```bash +python -m virtualenv env +``` + +2. Activate the virtual environment + +```bash +env\Scripts\activate +``` + +where `env` is the path to the environment created in step 3 (e.g. `C:\Users\'Username'\env\Scripts\activate.bat`). + +3. Install the `bpx` package + +```bash +pip install bpx +``` + +As an alternative, you can set up [Windows Subsystem for Linux](https://docs.microsoft.com/en-us/windows/wsl/about). This allows you to run a full Linux distribution within Windows. diff --git a/pyproject.toml b/pyproject.toml index a1da97c..584f1b2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,6 +8,7 @@ authors = [{name = "Martin Robinson", email = "martin.robinson@dtc.ox.ac.uk"}] readme = "README.md" dynamic = ["version", "description"] dependencies = [ + "devtools", "pydantic<2", "pyparsing", ] @@ -16,4 +17,11 @@ dependencies = [ dev = [ 'coverage', # Coverage checking 'flake8>=3', # Style checking + "sphinx>=6", + "sphinx_rtd_theme>=0.5", + "pydata-sphinx-theme", + "sphinx_design", + "sphinx-copybutton", + "myst-parser", + "sphinx-inline-tabs", ] From acb236fb6221f6083fe7f1a47b1db3efde21a510 Mon Sep 17 00:00:00 2001 From: Robert Timms Date: Fri, 1 Sep 2023 09:31:10 +0100 Subject: [PATCH 17/47] update docstrings --- bpx/expression_parser.py | 4 ++++ bpx/function.py | 10 ++++++++++ bpx/interpolated_table.py | 5 +++++ bpx/parsers.py | 14 +++++++++----- bpx/schema.py | 40 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 68 insertions(+), 5 deletions(-) diff --git a/bpx/expression_parser.py b/bpx/expression_parser.py index 8994ce8..746e2d9 100644 --- a/bpx/expression_parser.py +++ b/bpx/expression_parser.py @@ -8,6 +8,10 @@ class ExpressionParser: + """ + An expression parser for mathematical expressions. + """ + ParseException = pp.ParseException def __init__(self): diff --git a/bpx/function.py b/bpx/function.py index e913d58..44ad7ae 100644 --- a/bpx/function.py +++ b/bpx/function.py @@ -41,6 +41,16 @@ def __repr__(self): return f"Function({super().__repr__()})" def to_python_function(self, preamble: str = None) -> Callable: + """ + Return a python function that can be called with a single argument 'x' + + Parameters + ---------- + preamble: ste, options + a string of python code to be prepended to the function + definition. This can be used to import modules or define + helper functions. + """ if preamble is None: preamble = copy.copy(self.default_preamble) preamble += "\n\n" diff --git a/bpx/interpolated_table.py b/bpx/interpolated_table.py index 9647ef3..a8c3a7b 100644 --- a/bpx/interpolated_table.py +++ b/bpx/interpolated_table.py @@ -4,6 +4,11 @@ class InterpolatedTable(BaseModel): + """ + A table of values that can be interpolated to give a function. The table is defined + by two lists of floats, x and y. The function is defined by interpolation. + """ + x: List[float] y: List[float] diff --git a/bpx/parsers.py b/bpx/parsers.py index 251af10..d771865 100644 --- a/bpx/parsers.py +++ b/bpx/parsers.py @@ -3,15 +3,16 @@ def parse_bpx_file(filename: str) -> BPX: """ + A convenience function to parse a bpx file into a BPX model. + Parameters ---------- - filename: str a filepath to a bpx file Returns ------- - BPX: + BPX: :class:`bpx.BPX` a parsed BPX model """ return BPX.parse_file(filename) @@ -19,15 +20,16 @@ def parse_bpx_file(filename: str) -> BPX: def parse_bpx_obj(bpx: dict) -> BPX: """ + A convenience function to parse a bpx dict into a BPX model. + Parameters ---------- - bpx: dict a dict object in bpx format Returns ------- - BPX: + BPX: :class:`bpx.BPX` a parsed BPX model """ return BPX.parse_obj(bpx) @@ -35,9 +37,11 @@ def parse_bpx_obj(bpx: dict) -> BPX: def parse_bpx_str(bpx: str) -> BPX: """ + A convenience function to parse a json formatted string in bpx format into a BPX + model. + Parameters ---------- - bpx: str a json formatted string in bpx format diff --git a/bpx/schema.py b/bpx/schema.py index 07c76f6..5719f22 100644 --- a/bpx/schema.py +++ b/bpx/schema.py @@ -8,11 +8,20 @@ class ExtraBaseModel(BaseModel): + """ + A base model that forbids extra fields + """ + class Config: extra = Extra.forbid class Header(ExtraBaseModel): + """ + The header of a BPX file. Contains metadata about the file (e.g. BPX version, + title, description). + """ + bpx: float = Field( alias="BPX", example=1.0, @@ -44,6 +53,11 @@ class Header(ExtraBaseModel): class Cell(ExtraBaseModel): + """ + Cell-level parameters that are not specific to any individual component (electrode, + separator, or electrolyte). + """ + electrode_area: float = Field( alias="Electrode area [m2]", description="Electrode cross-sectional area", @@ -119,6 +133,10 @@ class Cell(ExtraBaseModel): class Electrolyte(ExtraBaseModel): + """ + Electrolyte parameters. + """ + initial_concentration: float = Field( alias="Initial concentration [mol.m-3]", example=1000, @@ -159,6 +177,10 @@ class Electrolyte(ExtraBaseModel): class Contact(ExtraBaseModel): + """ + Base class for parameters that are common to electrode and separator components. + """ + thickness: float = Field( alias="Thickness [m]", example=85.2e-6, @@ -177,6 +199,10 @@ class Contact(ExtraBaseModel): class Electrode(Contact): + """ + Electrode parameters. + """ + minimum_stoichiometry: float = Field( alias="Minimum stoichiometry", example=0.1, @@ -249,6 +275,10 @@ class Electrode(Contact): class Experiment(ExtraBaseModel): + """ + A class to store experimental data (time, current, voltage, temperature). + """ + time: List[float] = Field( alias="Time [s]", example=[0, 0.1, 0.2, 0.3, 0.4], @@ -273,6 +303,11 @@ class Experiment(ExtraBaseModel): class Parameterisation(ExtraBaseModel): + """ + A class to store parameterisation data for a cell. Consists of parameters for the + cell, electrolyte, negative electrode, positive electrode, and separator. + """ + cell: Cell = Field( alias="Cell", ) @@ -291,6 +326,11 @@ class Parameterisation(ExtraBaseModel): class BPX(ExtraBaseModel): + """ + A class to store a BPX model. Consists of a header, parameterisation, and optional + validation data. + """ + header: Header = Field( alias="Header", ) From eb9579db1289d9e3d415a67f185b46e2994253e8 Mon Sep 17 00:00:00 2001 From: Ivan Korotkin Date: Mon, 4 Sep 2023 19:12:34 +0100 Subject: [PATCH 18/47] Updated CHANGELOG --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3d01b26..b4b6fea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# Unreleased + +- Added support for well-mixed, blended electrodes that contain more than one active material ([#33](https://github.com/pybamm-team/BPX/pull/33)) + # [v0.3.0](https://github.com/pybamm-team/BPX/releases/tag/v0.3.0) - Added a missing factor of 2 in the definition of the interfacial current, see the Butler-Volmer equation (2a) in the associated BPX standard document. The interfacial current is now given by $j=2j_0\sinh(F\eta/2/R/T)$ instead of $j=j_0\sinh(F\eta/2/R/T)$. From e286492c21568166a789dfacd073fda80c13cbe2 Mon Sep 17 00:00:00 2001 From: Ivan Korotkin Date: Mon, 4 Sep 2023 20:53:52 +0100 Subject: [PATCH 19/47] Updated CHANGELOG --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 31b32cf..056d034 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ +# Unreleased + +- Added validation based on models: SPM, SPMe, DFN ([#34](https://github.com/pybamm-team/BPX/pull/34)) + # [v0.3.0](https://github.com/pybamm-team/BPX/releases/tag/v0.3.1) + - Temporarily pin Pydantic version ([#35](https://github.com/pybamm-team/BPX/pull/35)) + # [v0.3.0](https://github.com/pybamm-team/BPX/releases/tag/v0.3.0) - Added a missing factor of 2 in the definition of the interfacial current, see the Butler-Volmer equation (2a) in the associated BPX standard document. The interfacial current is now given by $j=2j_0\sinh(F\eta/2/R/T)$ instead of $j=j_0\sinh(F\eta/2/R/T)$. From f88c6f4f55b922acdc1ece909933c23c62ee9c22 Mon Sep 17 00:00:00 2001 From: Ivan Korotkin Date: Wed, 6 Sep 2023 16:04:45 +0100 Subject: [PATCH 20/47] Raise a warning instead of an error --- bpx/schema.py | 11 +++++------ tests/test_schema.py | 12 ++++++------ 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/bpx/schema.py b/bpx/schema.py index b0e0e15..cc16ce6 100644 --- a/bpx/schema.py +++ b/bpx/schema.py @@ -4,6 +4,8 @@ from bpx import Function, InterpolatedTable +from warnings import warn + FloatFunctionTable = Union[float, Function, InterpolatedTable] @@ -342,9 +344,6 @@ def model_based_validation(cls, values): ("Parameterisation", "SPMe"), ("ParameterisationSPM", "SPM"), ] - if (parameter_class_name, model) in allowed_combinations: - return values - else: - raise ValueError( - f"The model type {model} does not correspond to the parameter set" - ) + if (parameter_class_name, model) not in allowed_combinations: + warn(f"The model type {model} does not correspond to the parameter set") + return values diff --git a/tests/test_schema.py b/tests/test_schema.py index 034e412..f412ceb 100644 --- a/tests/test_schema.py +++ b/tests/test_schema.py @@ -163,8 +163,8 @@ def test_bad_model(self): def test_bad_dfn(self): test = copy.copy(self.base_spm) test["Header"]["Model"] = "DFN" - with self.assertRaisesRegex( - ValidationError, + with self.assertWarnsRegex( + UserWarning, "The model type DFN does not correspond to the parameter set", ): parse_obj_as(BPX, test) @@ -172,8 +172,8 @@ def test_bad_dfn(self): def test_bad_spme(self): test = copy.copy(self.base_spm) test["Header"]["Model"] = "SPMe" - with self.assertRaisesRegex( - ValidationError, + with self.assertWarnsRegex( + UserWarning, "The model type SPMe does not correspond to the parameter set", ): parse_obj_as(BPX, test) @@ -181,8 +181,8 @@ def test_bad_spme(self): def test_bad_spm(self): test = copy.copy(self.base) test["Header"]["Model"] = "SPM" - with self.assertRaisesRegex( - ValidationError, + with self.assertWarnsRegex( + UserWarning, "The model type SPM does not correspond to the parameter set", ): parse_obj_as(BPX, test) From bca53cec569fada712cf578fd5055e67e90064dc Mon Sep 17 00:00:00 2001 From: Ivan Korotkin Date: Wed, 6 Sep 2023 16:09:56 +0100 Subject: [PATCH 21/47] Updated CHANGELOG --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 056d034..650bfef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,8 @@ # Unreleased -- Added validation based on models: SPM, SPMe, DFN ([#34](https://github.com/pybamm-team/BPX/pull/34)) +- Added validation based on models: SPM, SPMe, DFN ([#34](https://github.com/pybamm-team/BPX/pull/34)). A warning will be produced if the user-defined model type does not match the parameter set (e.g., if the model is `SPM`, but the full DFN model parameters are provided). -# [v0.3.0](https://github.com/pybamm-team/BPX/releases/tag/v0.3.1) +# [v0.3.1](https://github.com/pybamm-team/BPX/releases/tag/v0.3.1) - Temporarily pin Pydantic version ([#35](https://github.com/pybamm-team/BPX/pull/35)) From 14f2c11b091538d006f9a88d16c9c3a9c4f67057 Mon Sep 17 00:00:00 2001 From: Ivan Korotkin Date: Mon, 11 Sep 2023 17:12:41 +0100 Subject: [PATCH 22/47] Added STO limit check for all parameter sets (including SPM) --- bpx/schema.py | 84 +++++++++++++++++++++++++------------------- tests/test_schema.py | 61 ++++++++++++++++++++++++++++++-- 2 files changed, 106 insertions(+), 39 deletions(-) diff --git a/bpx/schema.py b/bpx/schema.py index 72f0d54..15afcaf 100644 --- a/bpx/schema.py +++ b/bpx/schema.py @@ -296,6 +296,45 @@ class Experiment(ExtraBaseModel): ) +# Validates that the STO limits subbed into the OCPs give the correct voltage limits. +# Works if both OCPs are defined as functions. +# Blended electrodes are not supported. +# This is a reusable validator to be used for both DFN/SPMe and SPM parameter sets. +# https://docs.pydantic.dev/latest/usage/validators/#root-validators +def check_sto_limits(cls, values): + try: + ocp_n = values.get("negative_electrode").ocp.to_python_function() + ocp_p = values.get("positive_electrode").ocp.to_python_function() + except AttributeError: + # OCPs defined as interpolated tables; do nothing + return values + + sto_n_min = values.get("negative_electrode").minimum_stoichiometry + sto_n_max = values.get("negative_electrode").maximum_stoichiometry + sto_p_min = values.get("positive_electrode").minimum_stoichiometry + sto_p_max = values.get("positive_electrode").maximum_stoichiometry + V_min = values.get("cell").lower_voltage_cutoff + V_max = values.get("cell").upper_voltage_cutoff + + # Checks the maximum voltage estimated from STO + V_max_sto = ocp_p(sto_p_min) - ocp_n(sto_n_max) + if V_max_sto > V_max: + raise ValueError( + f"The maximum voltage computed from the STO limits ({V_max_sto} V) " + f"is higher than the maximum allowed voltage ({V_max} V)" + ) + + # Checks the minimum voltage estimated from STO + V_min_sto = ocp_p(sto_p_max) - ocp_n(sto_n_min) + if V_min_sto < V_min: + raise ValueError( + f"The minimum voltage computed from the STO limits ({V_min_sto} V) " + f"is lower than the minimum allowed voltage ({V_min} V)" + ) + + return values + + class Parameterisation(ExtraBaseModel): cell: Cell = Field( alias="Cell", @@ -313,42 +352,10 @@ class Parameterisation(ExtraBaseModel): alias="Separator", ) - # Validates that the STO limits subbed into the OCPs give the correct voltage limits. - # Works if both OCPs are defined as functions. - # https://docs.pydantic.dev/latest/usage/validators/#root-validators - @root_validator(skip_on_failure=True) - def check_sto_limits(cls, values): - try: - ocp_n = values.get("negative_electrode").ocp.to_python_function() - ocp_p = values.get("positive_electrode").ocp.to_python_function() - except AttributeError: - # OCPs defined as interpolated tables; do nothing - return values - - sto_n_min = values.get("negative_electrode").minimum_stoichiometry - sto_n_max = values.get("negative_electrode").maximum_stoichiometry - sto_p_min = values.get("positive_electrode").minimum_stoichiometry - sto_p_max = values.get("positive_electrode").maximum_stoichiometry - V_min = values.get("cell").lower_voltage_cutoff - V_max = values.get("cell").upper_voltage_cutoff - - # Checks the maximum voltage estimated from STO - V_max_sto = ocp_p(sto_p_min) - ocp_n(sto_n_max) - if V_max_sto > V_max: - raise ValueError( - f"The maximum voltage computed from the STO limits ({V_max_sto} V) " - f"is higher than the maximum allowed voltage ({V_max} V)" - ) - - # Checks the minimum voltage estimated from STO - V_min_sto = ocp_p(sto_p_max) - ocp_n(sto_n_min) - if V_min_sto < V_min: - raise ValueError( - f"The minimum voltage computed from the STO limits ({V_min_sto} V) " - f"is lower than the minimum allowed voltage ({V_min} V)" - ) - - return values + # Reusable validators + _sto_limit_validation = root_validator(skip_on_failure=True, allow_reuse=True)( + check_sto_limits + ) class ParameterisationSPM(ExtraBaseModel): @@ -362,6 +369,11 @@ class ParameterisationSPM(ExtraBaseModel): alias="Positive electrode", ) + # Reusable validators + _sto_limit_validation = root_validator(skip_on_failure=True, allow_reuse=True)( + check_sto_limits + ) + class BPX(ExtraBaseModel): header: Header = Field( diff --git a/tests/test_schema.py b/tests/test_schema.py index e1e97f2..7876cc0 100644 --- a/tests/test_schema.py +++ b/tests/test_schema.py @@ -147,6 +147,61 @@ def setUp(self): }, } + # Non-blended electrodes + self.base_non_blended = { + "Header": { + "BPX": 1.0, + "Model": "SPM", + }, + "Parameterisation": { + "Cell": { + "Ambient temperature [K]": 299.0, + "Initial temperature [K]": 299.0, + "Reference temperature [K]": 299.0, + "Electrode area [m2]": 2.0, + "External surface area [m2]": 2.2, + "Volume [m3]": 1.0, + "Number of electrode pairs connected in parallel to make a cell": 1, + "Nominal cell capacity [A.h]": 5.0, + "Lower voltage cut-off [V]": 2.0, + "Upper voltage cut-off [V]": 4.0, + }, + "Negative electrode": { + "Particle radius [m]": 5.86e-6, + "Thickness [m]": 85.2e-6, + "Diffusivity [m2.s-1]": 3.3e-14, + "OCP [V]": ( + "9.47057878e-01 * exp(-1.59418743e+02 * x) - 3.50928033e+04 + " + "1.64230269e-01 * tanh(-4.55509094e+01 * (x - 3.24116012e-02 )) + " + "3.69968491e-02 * tanh(-1.96718868e+01 * (x - 1.68334476e-01)) + " + "1.91517003e+04 * tanh(3.19648312e+00 * (x - 1.85139824e+00)) + " + "5.42448511e+04 * tanh(-3.19009848e+00 * (x - 2.01660395e+00))" + ), + "Surface area per unit volume [m-1]": 383959, + "Reaction rate constant [mol.m-2.s-1]": 1e-10, + "Maximum concentration [mol.m-3]": 33133, + "Minimum stoichiometry": 0.005504, + "Maximum stoichiometry": 0.75668, + }, + "Positive electrode": { + "Particle radius [m]": 5.22e-6, + "Thickness [m]": 75.6e-6, + "Diffusivity [m2.s-1]": 4.0e-15, + "OCP [V]": ( + "-3.04420906 * x + 10.04892207 - " + "0.65637536 * tanh(-4.02134095 * (x - 0.80063948)) + " + "4.24678547 * tanh(12.17805062 * (x - 7.57659337)) - " + "0.3757068 * tanh(59.33067782 * (x - 0.99784492))" + ), + "Surface area per unit volume [m-1]": 382184, + "Reaction rate constant [mol.m-2.s-1]": 1e-10, + "Maximum concentration [mol.m-3]": 63104.0, + "Minimum stoichiometry": 0.42424, + "Maximum stoichiometry": 0.96210, + }, + }, + } + def test_simple(self): test = copy.copy(self.base) parse_obj_as(BPX, test) @@ -265,19 +320,19 @@ def test_validation_data(self): } def test_check_sto_limits_validator(self): - test = copy.copy(self.base) + test = copy.copy(self.base_non_blended) test["Parameterisation"]["Cell"]["Upper voltage cut-off [V]"] = 4.3 test["Parameterisation"]["Cell"]["Lower voltage cut-off [V]"] = 2.5 parse_obj_as(BPX, test) def test_check_sto_limits_validator_high_voltage(self): - test = copy.copy(self.base) + test = copy.copy(self.base_non_blended) test["Parameterisation"]["Cell"]["Upper voltage cut-off [V]"] = 4.0 with self.assertRaises(ValidationError): parse_obj_as(BPX, test) def test_check_sto_limits_validator_low_voltage(self): - test = copy.copy(self.base) + test = copy.copy(self.base_non_blended) test["Parameterisation"]["Cell"]["Lower voltage cut-off [V]"] = 3.0 with self.assertRaises(ValidationError): parse_obj_as(BPX, test) From b9200d1752bb3d4ed92ef0b0d1c5205b7bfd816b Mon Sep 17 00:00:00 2001 From: Ivan Korotkin Date: Mon, 11 Sep 2023 17:36:32 +0100 Subject: [PATCH 23/47] Changed error to a warning if initial SOC is outside of [0,1] --- bpx/utilities.py | 7 +++++-- tests/test_schema.py | 14 ++++---------- tests/test_utilities.py | 16 ++++++++-------- 3 files changed, 17 insertions(+), 20 deletions(-) diff --git a/bpx/utilities.py b/bpx/utilities.py index dcb011e..6e01e63 100644 --- a/bpx/utilities.py +++ b/bpx/utilities.py @@ -1,3 +1,6 @@ +from warnings import warn + + def get_electrode_stoichiometries(target_soc, bpx): """ Calculate individual electrode stoichiometries at a particular target @@ -16,7 +19,7 @@ def get_electrode_stoichiometries(target_soc, bpx): The electrode stoichiometries that give the target state of charge """ if target_soc < 0 or target_soc > 1: - raise ValueError("Target SOC should be between 0 and 1") + warn("Target SOC should be between 0 and 1") sto_n_min = bpx.parameterisation.negative_electrode.minimum_stoichiometry sto_n_max = bpx.parameterisation.negative_electrode.maximum_stoichiometry @@ -48,7 +51,7 @@ def get_electrode_concentrations(target_soc, bpx): The electrode concentrations that give the target state of charge """ if target_soc < 0 or target_soc > 1: - raise ValueError("Target SOC should be between 0 and 1") + warn("Target SOC should be between 0 and 1") c_n_max = bpx.parameterisation.negative_electrode.maximum_concentration c_p_max = bpx.parameterisation.positive_electrode.maximum_concentration diff --git a/tests/test_schema.py b/tests/test_schema.py index 7876cc0..380b269 100644 --- a/tests/test_schema.py +++ b/tests/test_schema.py @@ -23,7 +23,7 @@ def setUp(self): "Number of electrode pairs connected in parallel to make a cell": 1, "Nominal cell capacity [A.h]": 5.0, "Lower voltage cut-off [V]": 2.0, - "Upper voltage cut-off [V]": 4.5, + "Upper voltage cut-off [V]": 4.0, }, "Electrolyte": { "Initial concentration [mol.m-3]": 1000, @@ -37,21 +37,15 @@ def setUp(self): "Particle radius [m]": 5.86e-6, "Thickness [m]": 85.2e-6, "Diffusivity [m2.s-1]": 3.3e-14, - "OCP [V]": ( - "9.47057878e-01 * exp(-1.59418743e+02 * x) - 3.50928033e+04 + " - "1.64230269e-01 * tanh(-4.55509094e+01 * (x - 3.24116012e-02 )) + " - "3.69968491e-02 * tanh(-1.96718868e+01 * (x - 1.68334476e-01)) + " - "1.91517003e+04 * tanh(3.19648312e+00 * (x - 1.85139824e+00)) + " - "5.42448511e+04 * tanh(-3.19009848e+00 * (x - 2.01660395e+00))" - ), + "OCP [V]": {"x": [0, 0.1, 1], "y": [1.72, 1.2, 0.06]}, "Conductivity [S.m-1]": 215.0, "Surface area per unit volume [m-1]": 383959, "Porosity": 0.25, "Transport efficiency": 0.125, "Reaction rate constant [mol.m-2.s-1]": 1e-10, "Maximum concentration [mol.m-3]": 33133, - "Minimum stoichiometry": 0.005504, - "Maximum stoichiometry": 0.75668, + "Minimum stoichiometry": 0.01, + "Maximum stoichiometry": 0.99, }, "Positive electrode": { "Thickness [m]": 75.6e-6, diff --git a/tests/test_utilities.py b/tests/test_utilities.py index d4e3086..e530549 100644 --- a/tests/test_utilities.py +++ b/tests/test_utilities.py @@ -86,8 +86,8 @@ def test_get_init_conc(self): def test_get_init_sto_negative_target_soc(self): test = copy.copy(self.base) obj = parse_obj_as(BPX, test) - with self.assertRaisesRegex( - ValueError, + with self.assertWarnsRegex( + UserWarning, "Target SOC should be between 0 and 1", ): get_electrode_stoichiometries(-0.1, obj) @@ -95,8 +95,8 @@ def test_get_init_sto_negative_target_soc(self): def test_get_init_sto_bad_target_soc(self): test = copy.copy(self.base) obj = parse_obj_as(BPX, test) - with self.assertRaisesRegex( - ValueError, + with self.assertWarnsRegex( + UserWarning, "Target SOC should be between 0 and 1", ): get_electrode_stoichiometries(1.1, obj) @@ -104,8 +104,8 @@ def test_get_init_sto_bad_target_soc(self): def test_get_init_conc_negative_target_soc(self): test = copy.copy(self.base) obj = parse_obj_as(BPX, test) - with self.assertRaisesRegex( - ValueError, + with self.assertWarnsRegex( + UserWarning, "Target SOC should be between 0 and 1", ): get_electrode_concentrations(-0.5, obj) @@ -113,8 +113,8 @@ def test_get_init_conc_negative_target_soc(self): def test_get_init_conc_bad_target_soc(self): test = copy.copy(self.base) obj = parse_obj_as(BPX, test) - with self.assertRaisesRegex( - ValueError, + with self.assertWarnsRegex( + UserWarning, "Target SOC should be between 0 and 1", ): get_electrode_concentrations(1.05, obj) From 7a54d449c7690f46553b6d8fe357e9c7b8353c81 Mon Sep 17 00:00:00 2001 From: Ivan Korotkin Date: Mon, 11 Sep 2023 18:47:06 +0100 Subject: [PATCH 24/47] Changed error to a warning for STO limits validator --- bpx/schema.py | 4 ++-- tests/test_schema.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bpx/schema.py b/bpx/schema.py index 15afcaf..8fbb235 100644 --- a/bpx/schema.py +++ b/bpx/schema.py @@ -319,7 +319,7 @@ def check_sto_limits(cls, values): # Checks the maximum voltage estimated from STO V_max_sto = ocp_p(sto_p_min) - ocp_n(sto_n_max) if V_max_sto > V_max: - raise ValueError( + warn( f"The maximum voltage computed from the STO limits ({V_max_sto} V) " f"is higher than the maximum allowed voltage ({V_max} V)" ) @@ -327,7 +327,7 @@ def check_sto_limits(cls, values): # Checks the minimum voltage estimated from STO V_min_sto = ocp_p(sto_p_max) - ocp_n(sto_n_min) if V_min_sto < V_min: - raise ValueError( + warn( f"The minimum voltage computed from the STO limits ({V_min_sto} V) " f"is lower than the minimum allowed voltage ({V_min} V)" ) diff --git a/tests/test_schema.py b/tests/test_schema.py index 380b269..29ea66b 100644 --- a/tests/test_schema.py +++ b/tests/test_schema.py @@ -322,13 +322,13 @@ def test_check_sto_limits_validator(self): def test_check_sto_limits_validator_high_voltage(self): test = copy.copy(self.base_non_blended) test["Parameterisation"]["Cell"]["Upper voltage cut-off [V]"] = 4.0 - with self.assertRaises(ValidationError): + with self.assertWarns(UserWarning): parse_obj_as(BPX, test) def test_check_sto_limits_validator_low_voltage(self): test = copy.copy(self.base_non_blended) test["Parameterisation"]["Cell"]["Lower voltage cut-off [V]"] = 3.0 - with self.assertRaises(ValidationError): + with self.assertWarns(UserWarning): parse_obj_as(BPX, test) From 19d3dcf85174ae514290bd43983c1fbb8322f9a9 Mon Sep 17 00:00:00 2001 From: Ivan Korotkin Date: Tue, 12 Sep 2023 10:05:24 +0100 Subject: [PATCH 25/47] Moved STO validator from schema to new file validators.py --- bpx/__init__.py | 1 + bpx/schema.py | 41 +---------------------------------------- bpx/validators.py | 42 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 44 insertions(+), 40 deletions(-) create mode 100644 bpx/validators.py diff --git a/bpx/__init__.py b/bpx/__init__.py index a4b6ea2..e7d9f3b 100644 --- a/bpx/__init__.py +++ b/bpx/__init__.py @@ -6,6 +6,7 @@ from .interpolated_table import InterpolatedTable from .expression_parser import ExpressionParser from .function import Function +from .validators import check_sto_limits from .schema import BPX from .parsers import parse_bpx_str, parse_bpx_obj, parse_bpx_file from .utilities import get_electrode_stoichiometries, get_electrode_concentrations diff --git a/bpx/schema.py b/bpx/schema.py index 8fbb235..e12b4d2 100644 --- a/bpx/schema.py +++ b/bpx/schema.py @@ -2,7 +2,7 @@ from pydantic import BaseModel, Field, Extra, root_validator -from bpx import Function, InterpolatedTable +from bpx import Function, InterpolatedTable, check_sto_limits from warnings import warn @@ -296,45 +296,6 @@ class Experiment(ExtraBaseModel): ) -# Validates that the STO limits subbed into the OCPs give the correct voltage limits. -# Works if both OCPs are defined as functions. -# Blended electrodes are not supported. -# This is a reusable validator to be used for both DFN/SPMe and SPM parameter sets. -# https://docs.pydantic.dev/latest/usage/validators/#root-validators -def check_sto_limits(cls, values): - try: - ocp_n = values.get("negative_electrode").ocp.to_python_function() - ocp_p = values.get("positive_electrode").ocp.to_python_function() - except AttributeError: - # OCPs defined as interpolated tables; do nothing - return values - - sto_n_min = values.get("negative_electrode").minimum_stoichiometry - sto_n_max = values.get("negative_electrode").maximum_stoichiometry - sto_p_min = values.get("positive_electrode").minimum_stoichiometry - sto_p_max = values.get("positive_electrode").maximum_stoichiometry - V_min = values.get("cell").lower_voltage_cutoff - V_max = values.get("cell").upper_voltage_cutoff - - # Checks the maximum voltage estimated from STO - V_max_sto = ocp_p(sto_p_min) - ocp_n(sto_n_max) - if V_max_sto > V_max: - warn( - f"The maximum voltage computed from the STO limits ({V_max_sto} V) " - f"is higher than the maximum allowed voltage ({V_max} V)" - ) - - # Checks the minimum voltage estimated from STO - V_min_sto = ocp_p(sto_p_max) - ocp_n(sto_n_min) - if V_min_sto < V_min: - warn( - f"The minimum voltage computed from the STO limits ({V_min_sto} V) " - f"is lower than the minimum allowed voltage ({V_min} V)" - ) - - return values - - class Parameterisation(ExtraBaseModel): cell: Cell = Field( alias="Cell", diff --git a/bpx/validators.py b/bpx/validators.py new file mode 100644 index 0000000..b7a8aa5 --- /dev/null +++ b/bpx/validators.py @@ -0,0 +1,42 @@ +from warnings import warn + + +def check_sto_limits(cls, values): + """ + Validates that the STO limits subbed into the OCPs give the correct voltage limits. + Works if both OCPs are defined as functions. + Blended electrodes are not supported. + This is a reusable validator to be used for both DFN/SPMe and SPM parameter sets. + """ + + try: + ocp_n = values.get("negative_electrode").ocp.to_python_function() + ocp_p = values.get("positive_electrode").ocp.to_python_function() + except AttributeError: + # OCPs defined as interpolated tables or one of the electrodes is blended; do nothing + return values + + sto_n_min = values.get("negative_electrode").minimum_stoichiometry + sto_n_max = values.get("negative_electrode").maximum_stoichiometry + sto_p_min = values.get("positive_electrode").minimum_stoichiometry + sto_p_max = values.get("positive_electrode").maximum_stoichiometry + V_min = values.get("cell").lower_voltage_cutoff + V_max = values.get("cell").upper_voltage_cutoff + + # Checks the maximum voltage estimated from STO + V_max_sto = ocp_p(sto_p_min) - ocp_n(sto_n_max) + if V_max_sto > V_max: + warn( + f"The maximum voltage computed from the STO limits ({V_max_sto} V) " + f"is higher than the upper voltage cut-off ({V_max} V)" + ) + + # Checks the minimum voltage estimated from STO + V_min_sto = ocp_p(sto_p_max) - ocp_n(sto_n_min) + if V_min_sto < V_min: + warn( + f"The minimum voltage computed from the STO limits ({V_min_sto} V) " + f"is less than the lower voltage cut-off ({V_min} V)" + ) + + return values From 755ccfd2b820a740b5c23dc40425275417a69f17 Mon Sep 17 00:00:00 2001 From: Ivan Korotkin Date: Tue, 12 Sep 2023 14:55:32 +0100 Subject: [PATCH 26/47] Added user-defined tolerance to check minimum/maximum voltage limits. Added tests. --- bpx/parsers.py | 9 +++++++-- bpx/schema.py | 10 ++++++++++ bpx/validators.py | 13 +++++++++---- tests/test_parsers.py | 12 ++++++++++++ tests/test_schema.py | 15 +++++++++++++++ 5 files changed, 53 insertions(+), 6 deletions(-) create mode 100644 tests/test_parsers.py diff --git a/bpx/parsers.py b/bpx/parsers.py index 251af10..6b13a7f 100644 --- a/bpx/parsers.py +++ b/bpx/parsers.py @@ -1,20 +1,25 @@ from bpx import BPX -def parse_bpx_file(filename: str) -> BPX: +def parse_bpx_file(filename: str, v_tol: float = 0.001) -> BPX: """ Parameters ---------- filename: str a filepath to a bpx file + v_tol: float + absolute tolerance in [V] to validate the voltage limits, 1 mV by default Returns ------- BPX: a parsed BPX model """ - return BPX.parse_file(filename) + if v_tol < 0: + raise ValueError("v_tol should not be negative") + + return BPX.parse_file(BPX, filename, v_tol=v_tol) def parse_bpx_obj(bpx: dict) -> BPX: diff --git a/bpx/schema.py b/bpx/schema.py index e12b4d2..aabfa16 100644 --- a/bpx/schema.py +++ b/bpx/schema.py @@ -1,5 +1,7 @@ from typing import List, Literal, Union, Dict +from dataclasses import dataclass + from pydantic import BaseModel, Field, Extra, root_validator from bpx import Function, InterpolatedTable, check_sto_limits @@ -13,6 +15,14 @@ class ExtraBaseModel(BaseModel): class Config: extra = Extra.forbid + @dataclass + class settings: + v_tol: float = 0.001 # Absolute tolerance in [V] to validate the voltage limits + + def parse_file(self, filename, v_tol): + self.settings.v_tol = v_tol + return super().parse_file(filename) + class Header(ExtraBaseModel): bpx: float = Field( diff --git a/bpx/validators.py b/bpx/validators.py index b7a8aa5..ed113cb 100644 --- a/bpx/validators.py +++ b/bpx/validators.py @@ -23,20 +23,25 @@ def check_sto_limits(cls, values): V_min = values.get("cell").lower_voltage_cutoff V_max = values.get("cell").upper_voltage_cutoff + # Voltage tolerance from `settings` data class + tol = cls.settings.v_tol + # Checks the maximum voltage estimated from STO V_max_sto = ocp_p(sto_p_min) - ocp_n(sto_n_max) - if V_max_sto > V_max: + if V_max_sto - V_max > tol: warn( f"The maximum voltage computed from the STO limits ({V_max_sto} V) " - f"is higher than the upper voltage cut-off ({V_max} V)" + f"is higher than the upper voltage cut-off ({V_max} V) " + f"with the absolute tolerance v_tol = {tol} V" ) # Checks the minimum voltage estimated from STO V_min_sto = ocp_p(sto_p_max) - ocp_n(sto_n_min) - if V_min_sto < V_min: + if V_min_sto - V_min < -tol: warn( f"The minimum voltage computed from the STO limits ({V_min_sto} V) " - f"is less than the lower voltage cut-off ({V_min} V)" + f"is less than the lower voltage cut-off ({V_min} V) " + f"with the absolute tolerance v_tol = {tol} V" ) return values diff --git a/tests/test_parsers.py b/tests/test_parsers.py new file mode 100644 index 0000000..506cdda --- /dev/null +++ b/tests/test_parsers.py @@ -0,0 +1,12 @@ +import unittest + +from bpx import parse_bpx_file + + +class TestParsers(unittest.TestCase): + def test_negative_v_tol(self): + with self.assertRaisesRegex( + ValueError, + "v_tol should not be negative", + ): + parse_bpx_file("filename", -0.001) diff --git a/tests/test_schema.py b/tests/test_schema.py index 29ea66b..bdb4451 100644 --- a/tests/test_schema.py +++ b/tests/test_schema.py @@ -1,4 +1,5 @@ import unittest +import warnings import copy from pydantic import parse_obj_as, ValidationError @@ -325,12 +326,26 @@ def test_check_sto_limits_validator_high_voltage(self): with self.assertWarns(UserWarning): parse_obj_as(BPX, test) + def test_check_sto_limits_validator_high_voltage_tolerance(self): + warnings.filterwarnings("error") # Treat warnings as errors + test = copy.copy(self.base_non_blended) + test["Parameterisation"]["Cell"]["Upper voltage cut-off [V]"] = 4.0 + BPX.settings.v_tol = 0.25 + parse_obj_as(BPX, test) + def test_check_sto_limits_validator_low_voltage(self): test = copy.copy(self.base_non_blended) test["Parameterisation"]["Cell"]["Lower voltage cut-off [V]"] = 3.0 with self.assertWarns(UserWarning): parse_obj_as(BPX, test) + def test_check_sto_limits_validator_low_voltage_tolerance(self): + warnings.filterwarnings("error") # Treat warnings as errors + test = copy.copy(self.base_non_blended) + test["Parameterisation"]["Cell"]["Lower voltage cut-off [V]"] = 3.0 + BPX.settings.v_tol = 0.35 + parse_obj_as(BPX, test) + if __name__ == "__main__": unittest.main() From d18380df4cf5d3c9b4271b2a1122ed7d087d52a3 Mon Sep 17 00:00:00 2001 From: Ivan Korotkin Date: Tue, 12 Sep 2023 14:59:36 +0100 Subject: [PATCH 27/47] Treat more warnings as errors for testing --- tests/test_schema.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test_schema.py b/tests/test_schema.py index bdb4451..d0fe17c 100644 --- a/tests/test_schema.py +++ b/tests/test_schema.py @@ -315,6 +315,7 @@ def test_validation_data(self): } def test_check_sto_limits_validator(self): + warnings.filterwarnings("error") # Treat warnings as errors test = copy.copy(self.base_non_blended) test["Parameterisation"]["Cell"]["Upper voltage cut-off [V]"] = 4.3 test["Parameterisation"]["Cell"]["Lower voltage cut-off [V]"] = 2.5 From 3524977f82d6f2362413214991e88f3c9047ee55 Mon Sep 17 00:00:00 2001 From: Ivan Korotkin Date: Wed, 13 Sep 2023 10:47:56 +0100 Subject: [PATCH 28/47] Updated CHANGELOG --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 281f6a9..4b6f943 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ - Added validation based on models: SPM, SPMe, DFN ([#34](https://github.com/pybamm-team/BPX/pull/34)). A warning will be produced if the user-defined model type does not match the parameter set (e.g., if the model is `SPM`, but the full DFN model parameters are provided). - Added support for well-mixed, blended electrodes that contain more than one active material ([#33](https://github.com/pybamm-team/BPX/pull/33)) +- Added validation of the STO limits subbed into the OCPs vs the upper/lower cut-off voltage limits for non-blended electrodes with the OCPs defined as functions ([#32](https://github.com/FaradayInstitution/BPX/pull/32)). The user can provide a tolerance by updating the settings variable `BPX.settings.v_tol` or by passing extra option `v_tol` to `parse_bpx_file()` function. Default value of the tolerance is 1 mV. The tolerance cannot be negative. +- Added the target SOC check in `get_electrode_concentrations()` function. Raise a warning if the SOC is outside of [0,1] interval. +- In `get_electrode_stoichiometries()` function, raise a warning instead of an error if the SOC is outside of [0,1] interval. # [v0.3.1](https://github.com/pybamm-team/BPX/releases/tag/v0.3.1) From 1fa5ba0b69458007e716758f56cfb900e7e1f23b Mon Sep 17 00:00:00 2001 From: Ivan Korotkin Date: Mon, 25 Sep 2023 11:41:12 +0100 Subject: [PATCH 29/47] Added example JSON files --- examples/lfp_18650_cell_BPX.json | 75 ++++++++++++++++ examples/nmc_pouch_cell_BPX.json | 86 ++++++++++++++++++ examples/nmc_pouch_cell_BPX_SPM.json | 67 ++++++++++++++ .../nmc_pouch_cell_BPX_blended_electrode.json | 88 +++++++++++++++++++ ...ouch_cell_BPX_user-defined_hysteresis.json | 81 +++++++++++++++++ 5 files changed, 397 insertions(+) create mode 100644 examples/lfp_18650_cell_BPX.json create mode 100644 examples/nmc_pouch_cell_BPX.json create mode 100644 examples/nmc_pouch_cell_BPX_SPM.json create mode 100644 examples/nmc_pouch_cell_BPX_blended_electrode.json create mode 100644 examples/nmc_pouch_cell_BPX_user-defined_hysteresis.json diff --git a/examples/lfp_18650_cell_BPX.json b/examples/lfp_18650_cell_BPX.json new file mode 100644 index 0000000..bc4aa47 --- /dev/null +++ b/examples/lfp_18650_cell_BPX.json @@ -0,0 +1,75 @@ +{ + "Header": { + "BPX": 0.1, + "Title": "Parameterisation example of an LFP|graphite 2 Ah cylindrical 18650 cell.", + "Description": "LFP|graphite 2 Ah cylindrical 18650 cell. Parameterisation by About:Energy Limited (aboutenergy.io), December 2022, based on cell cycling data, and electrode data gathered after cell teardown. Electrolyte properties from Nyman et al. 2008 (doi:10.1016/j.electacta.2008.04.023). Negative electrode entropic coefficient data are from O'Regan et al. 2022 (doi:10.1016/j.electacta.2022.140700). Positive electrode entropic coefficient data are from Gerver and Meyers 2011 (doi:10.1149/1.3591799). Other thermal properties are estimated.", + "Model": "DFN" + }, + "Parameterisation": { + "Cell": { + "Ambient temperature [K]": 298.15, + "Initial temperature [K]": 298.15, + "Reference temperature [K]": 298.15, + "Lower voltage cut-off [V]": 2.0, + "Upper voltage cut-off [V]": 3.65, + "Nominal cell capacity [A.h]": 2, + "Specific heat capacity [J.K-1.kg-1]": 999, + "Thermal conductivity [W.m-1.K-1]": 1.89, + "Density [kg.m-3]": 1940, + "Electrode area [m2]": 0.08959998, + "Number of electrode pairs connected in parallel to make a cell": 1, + "External surface area [m2]": 0.00431, + "Volume [m3]": 1.7e-05 + }, + "Electrolyte": { + "Initial concentration [mol.m-3]": 1000, + "Cation transference number": 0.259, + "Conductivity [S.m-1]": "0.1297 * (x / 1000) ** 3 - 2.51 * (x / 1000) ** 1.5 + 3.329 * (x / 1000)", + "Diffusivity [m2.s-1]": "8.794e-11 * (x / 1000) ** 2 - 3.972e-10 * (x / 1000) + 4.862e-10", + "Conductivity activation energy [J.mol-1]": 17100, + "Diffusivity activation energy [J.mol-1]": 17100 + }, + "Negative electrode": { + "Particle radius [m]": 4.8e-06, + "Thickness [m]": 4.44e-05, + "Diffusivity [m2.s-1]": 9.6e-15, + "OCP [V]": "5.29210878e+01 * exp(-1.72699386e+02 * x) - 1.17963399e+03 + 1.20956356e+03 * tanh(6.72033948e+01 * (x + 2.44746396e-02)) + 4.52430314e-02 * tanh(-1.47542326e+01 * (x - 1.62746053e-01)) + 2.01855800e+01 * tanh(-2.46666302e+01 * (x - 1.12986136e+00)) + 2.01708039e-02 * tanh(-1.19900231e+01 * (x - 5.49773440e-01)) + 4.99616805e+01 * tanh(-6.11370883e+01 * (x + 4.69382558e-03))", + "Entropic change coefficient [V.K-1]": "(-0.1112 * x + 0.02914 + 0.3561 * exp(-((x - 0.08309) ** 2) / 0.004616)) / 1000", + "Conductivity [S.m-1]": 7.46, + "Surface area per unit volume [m-1]": 473004, + "Porosity": 0.20666, + "Transport efficiency": 0.09395, + "Reaction rate constant [mol.m-2.s-1]": 6.872e-06, + "Minimum stoichiometry": 0.0016261, + "Maximum stoichiometry": 0.82258, + "Maximum concentration [mol.m-3]": 31400, + "Diffusivity activation energy [J.mol-1]": 30000, + "Reaction rate constant activation energy [J.mol-1]": 55000 + }, + "Positive electrode": { + "Particle radius [m]": 5e-07, + "Thickness [m]": 6.43e-05, + "Diffusivity [m2.s-1]": 6.873e-17, + "OCP [V]": "3.41285712e+00 - 1.49721852e-02 * x + 3.54866018e+14 * exp(-3.95729493e+02 * x) - 1.45998465e+00 * exp(-1.10108622e+02 * (1 - x))", + "Entropic change coefficient [V.K-1]": { + "x": [0, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 1], + "y": [0.0001, 4.7145e-05, 3.7666e-05, 2.0299e-05, 5.9833e-06, -4.6859e-06, -1.3966e-05, -2.3528e-05, -3.3593e-05, -4.3433e-05, -5.2311e-05, -6.0211e-05, -6.8006e-05, -7.6939e-05, -8.7641e-05, -9.913e-05, -0.00010855, -0.00011266, -0.00011238, -0.00010921, -0.00022539] + }, + "Conductivity [S.m-1]": 0.80, + "Surface area per unit volume [m-1]": 4418460, + "Porosity": 0.20359, + "Transport efficiency": 0.09186, + "Reaction rate constant [mol.m-2.s-1]": 9.736e-07, + "Minimum stoichiometry": 0.0875, + "Maximum stoichiometry": 0.95038, + "Maximum concentration [mol.m-3]": 21200, + "Diffusivity activation energy [J.mol-1]": 80000, + "Reaction rate constant activation energy [J.mol-1]": 35000 + }, + "Separator": { + "Thickness [m]": 2e-05, + "Porosity": 0.47, + "Transport efficiency": 0.3222 + } + } +} diff --git a/examples/nmc_pouch_cell_BPX.json b/examples/nmc_pouch_cell_BPX.json new file mode 100644 index 0000000..bb26edb --- /dev/null +++ b/examples/nmc_pouch_cell_BPX.json @@ -0,0 +1,86 @@ +{ + "Header": { + "BPX": 0.1, + "Title": "Parameterisation example of an NMC111|graphite 12.5 Ah pouch cell", + "Description": "NMC111|graphite 12.5 Ah pouch cell. Parameterisation by About:Energy Limited (aboutenergy.io), December 2022, based on cell cycling data, and electrode data gathered after cell teardown. Electrolyte properties from Nyman et al. 2008 (doi:10.1016/j.electacta.2008.04.023). Negative electrode entropic coefficient data are from O'Regan et al. 2022 (doi:10.1016/j.electacta.2022.140700). Positive electrode entropic coefficient data are from Viswanathan et al. 2010 (doi:10.1016/j.jpowsour.2009.11.103). Other thermal properties are estimated.", + "Model": "DFN" + }, + "Parameterisation": { + "Cell": { + "Ambient temperature [K]": 298.15, + "Initial temperature [K]": 298.15, + "Reference temperature [K]": 298.15, + "Lower voltage cut-off [V]": 2.7, + "Upper voltage cut-off [V]": 4.2, + "Nominal cell capacity [A.h]": 12.5, + "Specific heat capacity [J.K-1.kg-1]": 913, + "Thermal conductivity [W.m-1.K-1]": 2.04, + "Density [kg.m-3]": 1847, + "Electrode area [m2]": 0.016808, + "Number of electrode pairs connected in parallel to make a cell": 34, + "External surface area [m2]": 0.0379, + "Volume [m3]": 0.000128 + }, + "Electrolyte": { + "Initial concentration [mol.m-3]": 1000, + "Cation transference number": 0.2594, + "Conductivity [S.m-1]": "0.1297 * (x / 1000) ** 3 - 2.51 * (x / 1000) ** 1.5 + 3.329 * (x / 1000)", + "Diffusivity [m2.s-1]": "8.794e-11 * (x / 1000) ** 2 - 3.972e-10 * (x / 1000) + 4.862e-10", + "Conductivity activation energy [J.mol-1]": 17100, + "Diffusivity activation energy [J.mol-1]": 17100 + }, + "Negative electrode": { + "Particle radius [m]": 4.12e-06, + "Thickness [m]": 5.62e-05, + "Diffusivity [m2.s-1]": 2.728e-14, + "OCP [V]": "9.47057878e-01 * exp(-1.59418743e+02 * x) - 3.50928033e+04 + 1.64230269e-01 * tanh(-4.55509094e+01 * (x - 3.24116012e-02 )) + 3.69968491e-02 * tanh(-1.96718868e+01 * (x - 1.68334476e-01)) + 1.91517003e+04 * tanh(3.19648312e+00 * (x - 1.85139824e+00)) + 5.42448511e+04 * tanh(-3.19009848e+00 * (x - 2.01660395e+00))", + "Entropic change coefficient [V.K-1]": "(-0.1112 * x + 0.02914 + 0.3561 * exp(-((x - 0.08309) ** 2) / 0.004616)) / 1000", + "Conductivity [S.m-1]": 0.222, + "Surface area per unit volume [m-1]": 499522, + "Porosity": 0.253991, + "Transport efficiency": 0.128, + "Reaction rate constant [mol.m-2.s-1]": 5.199e-06, + "Minimum stoichiometry": 0.005504, + "Maximum stoichiometry": 0.75668, + "Maximum concentration [mol.m-3]": 29730, + "Diffusivity activation energy [J.mol-1]": 30000, + "Reaction rate constant activation energy [J.mol-1]": 55000 + }, + "Positive electrode": { + "Particle radius [m]": 4.6e-06, + "Thickness [m]": 5.23e-05, + "Diffusivity [m2.s-1]": 3.2e-14, + "OCP [V]": "-3.04420906 * x + 10.04892207 - 0.65637536 * tanh(-4.02134095 * (x - 0.80063948)) + 4.24678547 * tanh(12.17805062 * (x - 7.57659337)) - 0.3757068 * tanh(59.33067782 * (x - 0.99784492))", + "Entropic change coefficient [V.K-1]": -1e-4, + "Conductivity [S.m-1]": 0.789, + "Surface area per unit volume [m-1]": 432072, + "Porosity": 0.277493, + "Transport efficiency": 0.1462, + "Reaction rate constant [mol.m-2.s-1]": 2.305e-05, + "Minimum stoichiometry": 0.42424, + "Maximum stoichiometry": 0.96210, + "Maximum concentration [mol.m-3]": 46200, + "Diffusivity activation energy [J.mol-1]": 15000, + "Reaction rate constant activation energy [J.mol-1]": 35000 + }, + "Separator": { + "Thickness [m]": 2e-05, + "Porosity": 0.47, + "Transport efficiency": 0.3222 + } + }, + "Validation": { + "C/20 discharge": { + "Time [s]": [0, 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000, 10000, 11000, 12000, 13000, 14000, 15000, 16000, 17000, 18000, 19000, 20000, 21000, 22000, 23000, 24000, 25000, 26000, 27000, 28000, 29000, 30000, 31000, 32000, 33000, 34000, 35000, 36000, 37000, 38000, 39000, 40000, 41000, 42000, 43000, 44000, 45000, 46000, 47000, 48000, 49000, 50000, 51000, 52000, 53000, 54000, 55000, 56000, 57000, 58000, 59000, 60000, 61000, 62000, 63000, 64000, 65000, 66000, 67000, 68000, 69000, 70000, 71000, 72000, 73000, 74000, 75000], + "Current [A]": [-0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625], + "Voltage [V]": [4.19367569, 4.1677888, 4.14976386, 4.13250593, 4.11582327, 4.09952412, 4.08360848, 4.06788459, 4.05254422, 4.03720384, 4.02186346, 4.00690659, 3.99194973, 3.97699286, 3.96222774, 3.94727088, 3.93250576, 3.9173572, 3.90240027, 3.8874434, 3.87191127, 3.85637914, 3.8404635, 3.82493136, 3.80978274, 3.79482587, 3.78082778, 3.76740495, 3.75455738, 3.74286035, 3.73173857, 3.72176733, 3.71237135, 3.70393414, 3.69607219, 3.68859376, 3.68169059, 3.67517093, 3.66922653, 3.66309038, 3.65752958, 3.65235212, 3.64717474, 3.64257263, 3.637587, 3.63298489, 3.62819102, 3.62339716, 3.61879504, 3.61380942, 3.6088238, 3.60345467, 3.59770202, 3.59175763, 3.58542972, 3.57891014, 3.57200689, 3.56472021, 3.55685827, 3.54822931, 3.53864157, 3.52828682, 3.5173568, 3.5071938, 3.49894834, 3.49204517, 3.48590902, 3.47938936, 3.47152742, 3.4605974, 3.44218895, 3.39981122, 3.33749094, 3.25407757, 3.13308034, 2.89472934], + "Temperature [K]": [298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15] + }, + "1C discharge": { + "Time [s]": [0, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200, 1300, 1400, 1500, 1600, 1700, 1800, 1900, 2000, 2100, 2200, 2300, 2400, 2500, 2600, 2700, 2800, 2900, 3000, 3100, 3200, 3300, 3400, 3500, 3600, 3700], + "Current [A]": [-12.5, -12.5, -12.5, -12.5, -12.5, -12.5, -12.5, -12.5, -12.5, -12.5, -12.5, -12.5, -12.5, -12.5, -12.5, -12.5, -12.5, -12.5, -12.5, -12.5, -12.5, -12.5, -12.5, -12.5, -12.5, -12.5, -12.5, -12.5, -12.5, -12.5, -12.5, -12.5, -12.5, -12.5, -12.5, -12.5, -12.5, -12.5], + "Voltage [V]": [4.1936757, 4.0487091, 4.0107418, 3.9762259, 3.9426688, 3.9094952, 3.8763218, 3.8433398, 3.8113168, 3.7802525, 3.7505305, 3.7221509, 3.695497, 3.6703771, 3.6467912, 3.6247394, 3.6042217, 3.5858132, 3.5685555, 3.5532149, 3.5382581, 3.5238765, 3.5102619, 3.4974143, 3.4849502, 3.4728697, 3.4609809, 3.4485169, 3.4352858, 3.4216712, 3.4070979, 3.3907987, 3.3720067, 3.3474621, 3.3121793, 3.2569541, 3.1589672, 2.9047014], + "Temperature [K]": [298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15] + } + } +} diff --git a/examples/nmc_pouch_cell_BPX_SPM.json b/examples/nmc_pouch_cell_BPX_SPM.json new file mode 100644 index 0000000..666416b --- /dev/null +++ b/examples/nmc_pouch_cell_BPX_SPM.json @@ -0,0 +1,67 @@ +{ + "Header": { + "BPX": 0.4, + "Title": "Test case: Single Particle Model (SPM) parameterisation example based on nmc_pouch_cell_BPX.json from About:Energy open-source release.", + "Description": "NMC111|graphite 12.5 Ah pouch cell. Parameterisation by About:Energy Limited (aboutenergy.io), December 2022, based on cell cycling data, and electrode data gathered after cell teardown. Negative electrode entropic coefficient data are from O'Regan et al. 2022 (doi:10.1016/j.electacta.2022.140700). Positive electrode entropic coefficient data are from Viswanathan et al. 2010 (doi:10.1016/j.jpowsour.2009.11.103). Other thermal properties are estimated.", + "Model": "SPM" + }, + "Parameterisation": { + "Cell": { + "Ambient temperature [K]": 298.15, + "Initial temperature [K]": 298.15, + "Reference temperature [K]": 298.15, + "Lower voltage cut-off [V]": 2.7, + "Upper voltage cut-off [V]": 4.2, + "Nominal cell capacity [A.h]": 12.5, + "Specific heat capacity [J.K-1.kg-1]": 913, + "Thermal conductivity [W.m-1.K-1]": 2.04, + "Density [kg.m-3]": 1847, + "Electrode area [m2]": 0.016808, + "Number of electrode pairs connected in parallel to make a cell": 34, + "External surface area [m2]": 0.0379, + "Volume [m3]": 0.000128 + }, + "Negative electrode": { + "Particle radius [m]": 4.12e-06, + "Thickness [m]": 5.62e-05, + "Diffusivity [m2.s-1]": 2.728e-14, + "OCP [V]": "9.47057878e-01 * exp(-1.59418743e+02 * x) - 3.50928033e+04 + 1.64230269e-01 * tanh(-4.55509094e+01 * (x - 3.24116012e-02 )) + 3.69968491e-02 * tanh(-1.96718868e+01 * (x - 1.68334476e-01)) + 1.91517003e+04 * tanh(3.19648312e+00 * (x - 1.85139824e+00)) + 5.42448511e+04 * tanh(-3.19009848e+00 * (x - 2.01660395e+00))", + "Entropic change coefficient [V.K-1]": "(-0.1112 * x + 0.02914 + 0.3561 * exp(-((x - 0.08309) ** 2) / 0.004616)) / 1000", + "Surface area per unit volume [m-1]": 499522, + "Reaction rate constant [mol.m-2.s-1]": 5.199e-06, + "Minimum stoichiometry": 0.005504, + "Maximum stoichiometry": 0.75668, + "Maximum concentration [mol.m-3]": 29730, + "Diffusivity activation energy [J.mol-1]": 30000, + "Reaction rate constant activation energy [J.mol-1]": 55000 + }, + "Positive electrode": { + "Particle radius [m]": 4.6e-06, + "Thickness [m]": 5.23e-05, + "Diffusivity [m2.s-1]": 3.2e-14, + "OCP [V]": "-3.04420906 * x + 10.04892207 - 0.65637536 * tanh(-4.02134095 * (x - 0.80063948)) + 4.24678547 * tanh(12.17805062 * (x - 7.57659337)) - 0.3757068 * tanh(59.33067782 * (x - 0.99784492))", + "Entropic change coefficient [V.K-1]": -1e-4, + "Surface area per unit volume [m-1]": 432072, + "Reaction rate constant [mol.m-2.s-1]": 2.305e-05, + "Minimum stoichiometry": 0.42424, + "Maximum stoichiometry": 0.96210, + "Maximum concentration [mol.m-3]": 46200, + "Diffusivity activation energy [J.mol-1]": 15000, + "Reaction rate constant activation energy [J.mol-1]": 35000 + } + }, + "Validation": { + "C/20 discharge": { + "Time [s]": [0, 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000, 10000, 11000, 12000, 13000, 14000, 15000, 16000, 17000, 18000, 19000, 20000, 21000, 22000, 23000, 24000, 25000, 26000, 27000, 28000, 29000, 30000, 31000, 32000, 33000, 34000, 35000, 36000, 37000, 38000, 39000, 40000, 41000, 42000, 43000, 44000, 45000, 46000, 47000, 48000, 49000, 50000, 51000, 52000, 53000, 54000, 55000, 56000, 57000, 58000, 59000, 60000, 61000, 62000, 63000, 64000, 65000, 66000, 67000, 68000, 69000, 70000, 71000, 72000, 73000, 74000, 75000], + "Current [A]": [-0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625], + "Voltage [V]": [4.19367569, 4.1677888, 4.14976386, 4.13250593, 4.11582327, 4.09952412, 4.08360848, 4.06788459, 4.05254422, 4.03720384, 4.02186346, 4.00690659, 3.99194973, 3.97699286, 3.96222774, 3.94727088, 3.93250576, 3.9173572, 3.90240027, 3.8874434, 3.87191127, 3.85637914, 3.8404635, 3.82493136, 3.80978274, 3.79482587, 3.78082778, 3.76740495, 3.75455738, 3.74286035, 3.73173857, 3.72176733, 3.71237135, 3.70393414, 3.69607219, 3.68859376, 3.68169059, 3.67517093, 3.66922653, 3.66309038, 3.65752958, 3.65235212, 3.64717474, 3.64257263, 3.637587, 3.63298489, 3.62819102, 3.62339716, 3.61879504, 3.61380942, 3.6088238, 3.60345467, 3.59770202, 3.59175763, 3.58542972, 3.57891014, 3.57200689, 3.56472021, 3.55685827, 3.54822931, 3.53864157, 3.52828682, 3.5173568, 3.5071938, 3.49894834, 3.49204517, 3.48590902, 3.47938936, 3.47152742, 3.4605974, 3.44218895, 3.39981122, 3.33749094, 3.25407757, 3.13308034, 2.89472934], + "Temperature [K]": [298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15] + }, + "1C discharge": { + "Time [s]": [0, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200, 1300, 1400, 1500, 1600, 1700, 1800, 1900, 2000, 2100, 2200, 2300, 2400, 2500, 2600, 2700, 2800, 2900, 3000, 3100, 3200, 3300, 3400, 3500, 3600, 3700], + "Current [A]": [-12.5, -12.5, -12.5, -12.5, -12.5, -12.5, -12.5, -12.5, -12.5, -12.5, -12.5, -12.5, -12.5, -12.5, -12.5, -12.5, -12.5, -12.5, -12.5, -12.5, -12.5, -12.5, -12.5, -12.5, -12.5, -12.5, -12.5, -12.5, -12.5, -12.5, -12.5, -12.5, -12.5, -12.5, -12.5, -12.5, -12.5, -12.5], + "Voltage [V]": [4.1936757, 4.0487091, 4.0107418, 3.9762259, 3.9426688, 3.9094952, 3.8763218, 3.8433398, 3.8113168, 3.7802525, 3.7505305, 3.7221509, 3.695497, 3.6703771, 3.6467912, 3.6247394, 3.6042217, 3.5858132, 3.5685555, 3.5532149, 3.5382581, 3.5238765, 3.5102619, 3.4974143, 3.4849502, 3.4728697, 3.4609809, 3.4485169, 3.4352858, 3.4216712, 3.4070979, 3.3907987, 3.3720067, 3.3474621, 3.3121793, 3.2569541, 3.1589672, 2.9047014], + "Temperature [K]": [298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15, 298.15] + } + } +} diff --git a/examples/nmc_pouch_cell_BPX_blended_electrode.json b/examples/nmc_pouch_cell_BPX_blended_electrode.json new file mode 100644 index 0000000..c3dc590 --- /dev/null +++ b/examples/nmc_pouch_cell_BPX_blended_electrode.json @@ -0,0 +1,88 @@ +{ + "Header": { + "BPX": 0.4, + "Title": "Test case: blended electrode definition with two particle sizes but equivalent chemistry. Compare to nmc_pouch_cell_BPX.json in About:Energy open-source release.", + "Model": "DFN" + }, + "Parameterisation": { + "Cell": { + "Ambient temperature [K]": 298.15, + "Initial temperature [K]": 298.15, + "Reference temperature [K]": 298.15, + "Lower voltage cut-off [V]": 2.7, + "Upper voltage cut-off [V]": 4.2, + "Nominal cell capacity [A.h]": 12.5, + "Specific heat capacity [J.K-1.kg-1]": 913, + "Thermal conductivity [W.m-1.K-1]": 2.04, + "Density [kg.m-3]": 1847, + "Electrode area [m2]": 0.016808, + "Number of electrode pairs connected in parallel to make a cell": 34, + "External surface area [m2]": 0.0379, + "Volume [m3]": 0.000128 + }, + "Electrolyte": { + "Initial concentration [mol.m-3]": 1000, + "Cation transference number": 0.2594, + "Conductivity [S.m-1]": "0.1297 * (x / 1000) ** 3 - 2.51 * (x / 1000) ** 1.5 + 3.329 * (x / 1000)", + "Diffusivity [m2.s-1]": "8.794e-11 * (x / 1000) ** 2 - 3.972e-10 * (x / 1000) + 4.862e-10", + "Conductivity activation energy [J.mol-1]": 17100, + "Diffusivity activation energy [J.mol-1]": 17100 + }, + "Negative electrode": { + "Particle radius [m]": 4.12e-06, + "Thickness [m]": 5.62e-05, + "Diffusivity [m2.s-1]": 2.728e-14, + "OCP [V]": "9.47057878e-01 * exp(-1.59418743e+02 * x) - 3.50928033e+04 + 1.64230269e-01 * tanh(-4.55509094e+01 * (x - 3.24116012e-02 )) + 3.69968491e-02 * tanh(-1.96718868e+01 * (x - 1.68334476e-01)) + 1.91517003e+04 * tanh(3.19648312e+00 * (x - 1.85139824e+00)) + 5.42448511e+04 * tanh(-3.19009848e+00 * (x - 2.01660395e+00))", + "Entropic change coefficient [V.K-1]": "(-0.1112 * x + 0.02914 + 0.3561 * exp(-((x - 0.08309) ** 2) / 0.004616)) / 1000", + "Conductivity [S.m-1]": 0.222, + "Surface area per unit volume [m-1]": 499522, + "Porosity": 0.253991, + "Transport efficiency": 0.128, + "Reaction rate constant [mol.m-2.s-1]": 5.199e-06, + "Minimum stoichiometry": 0.005504, + "Maximum stoichiometry": 0.75668, + "Maximum concentration [mol.m-3]": 29730, + "Diffusivity activation energy [J.mol-1]": 30000, + "Reaction rate constant activation energy [J.mol-1]": 55000 + }, + "Positive electrode": { + "Thickness [m]": 5.23e-05, + "Conductivity [S.m-1]": 0.789, + "Porosity": 0.277493, + "Transport efficiency": 0.1462, + "Particle": { + "Large Particles": { + "Diffusivity [m2.s-1]": 3.2e-14, + "Particle radius [m]": 8e-06, + "OCP [V]": "-3.04420906 * x + 10.04892207 - 0.65637536 * tanh(-4.02134095 * (x - 0.80063948)) + 4.24678547 * tanh(12.17805062 * (x - 7.57659337)) - 0.3757068 * tanh(59.33067782 * (x - 0.99784492))", + "Entropic change coefficient [V.K-1]": -1e-4, + "Surface area per unit volume [m-1]": 186331, + "Reaction rate constant [mol.m-2.s-1]": 2.305e-05, + "Minimum stoichiometry": 0.42424, + "Maximum stoichiometry": 0.96210, + "Maximum concentration [mol.m-3]": 46200, + "Diffusivity activation energy [J.mol-1]": 15000, + "Reaction rate constant activation energy [J.mol-1]": 3500 + }, + "Small Particles": { + "Diffusivity [m2.s-1]": 3.2e-14, + "Particle radius [m]": 1e-06, + "OCP [V]": "-3.04420906 * x + 10.04892207 - 0.65637536 * tanh(-4.02134095 * (x - 0.80063948)) + 4.24678547 * tanh(12.17805062 * (x - 7.57659337)) - 0.3757068 * tanh(59.33067782 * (x - 0.99784492))", + "Entropic change coefficient [V.K-1]": -1e-4, + "Surface area per unit volume [m-1]": 496883, + "Reaction rate constant [mol.m-2.s-1]": 2.305e-05, + "Minimum stoichiometry": 0.42424, + "Maximum stoichiometry": 0.96210, + "Maximum concentration [mol.m-3]": 46200, + "Diffusivity activation energy [J.mol-1]": 15000, + "Reaction rate constant activation energy [J.mol-1]": 3500 + } + } + }, + "Separator": { + "Thickness [m]": 2e-05, + "Porosity": 0.47, + "Transport efficiency": 0.3222 + } + } +} diff --git a/examples/nmc_pouch_cell_BPX_user-defined_hysteresis.json b/examples/nmc_pouch_cell_BPX_user-defined_hysteresis.json new file mode 100644 index 0000000..9802051 --- /dev/null +++ b/examples/nmc_pouch_cell_BPX_user-defined_hysteresis.json @@ -0,0 +1,81 @@ +{ + "Header": { + "BPX": 0.4, + "Title": "Test case: user-defined 0th-order hysteresis for graphite-Si blend in negative electrode. Compare to nmc_pouch_cell_BPX.json in About:Energy open-source release.", + "Model": "DFN" + }, + "Parameterisation": { + "Cell": { + "Ambient temperature [K]": 298.15, + "Initial temperature [K]": 298.15, + "Reference temperature [K]": 298.15, + "Lower voltage cut-off [V]": 2.7, + "Upper voltage cut-off [V]": 4.2, + "Nominal cell capacity [A.h]": 12.5, + "Specific heat capacity [J.K-1.kg-1]": 913, + "Thermal conductivity [W.m-1.K-1]": 2.04, + "Density [kg.m-3]": 1847, + "Electrode area [m2]": 0.016808, + "Number of electrode pairs connected in parallel to make a cell": 34, + "External surface area [m2]": 0.0379, + "Volume [m3]": 0.000128 + }, + "Electrolyte": { + "Initial concentration [mol.m-3]": 1000, + "Cation transference number": 0.2594, + "Conductivity [S.m-1]": "0.1297 * (x / 1000) ** 3 - 2.51 * (x / 1000) ** 1.5 + 3.329 * (x / 1000)", + "Diffusivity [m2.s-1]": "8.794e-11 * (x / 1000) ** 2 - 3.972e-10 * (x / 1000) + 4.862e-10", + "Conductivity activation energy [J.mol-1]": 17100, + "Diffusivity activation energy [J.mol-1]": 17100 + }, + "Negative electrode": { + "Particle radius [m]": 4.12e-06, + "Thickness [m]": 5.62e-05, + "Diffusivity [m2.s-1]": 2.728e-14, + "OCP [V]": 0, + "Entropic change coefficient [V.K-1]": "(-0.1112 * x + 0.02914 + 0.3561 * exp(-((x - 0.08309) ** 2) / 0.004616)) / 1000", + "Conductivity [S.m-1]": 0.222, + "Surface area per unit volume [m-1]": 499522, + "Porosity": 0.253991, + "Transport efficiency": 0.128, + "Reaction rate constant [mol.m-2.s-1]": 5.199e-06, + "Minimum stoichiometry": 0.005504, + "Maximum stoichiometry": 0.75668, + "Maximum concentration [mol.m-3]": 29730, + "Diffusivity activation energy [J.mol-1]": 30000, + "Reaction rate constant activation energy [J.mol-1]": 55000 + }, + "User-defined": { + "Negative electrode delithiation OCP [V]": { + "x": [ 0.985031126220534, 0.9848751912658575, 0.9847163088798689, 0.984554392619813, 0.9843893533702854, 0.9842210992899517, 0.9840495357602426, 0.9838745653363619, 0.9836960877009673, 0.9835139996209118, 0.9833281949074524, 0.983138564380359, 0.9829449958363778, 0.9827473740225319, 0.9825455806147461, 0.9823394942023334, 0.9821289902788667, 0.9819139412399993, 0.9816942163888024, 0.9814696819492049, 0.9812402010881165, 0.9810056339468387, 0.9807658376823487, 0.980520666519043, 0.980269971811518, 0.9800136021189332, 0.9797514032914907, 0.9794832185695097, 0.9792088886955472, 0.9789282520399407, 0.9786411447400943, 0.9783474008537402, 0.9780468525263117, 0.9777393301724651, 0.97742466267164, 0.9771026775774303, 0.9767732013403572, 0.9764360595434552, 0.9760910771498819, 0.975738078761514, 0.9753768888872231, 0.9750073322192029, 0.9746292339153253, 0.9742424198850256, 0.9738467170755867, 0.973441953754865, 0.9730279597853304, 0.9726045668826342, 0.9721716088494632, 0.9717289217717503, 0.971276344158682, 0.9708137169992754, 0.9703408836948231, 0.9698576898055115, 0.9693639825166644, 0.9688596096785802, 0.968344418193156, 0.9678182513936614, 0.9672809448648025, 0.9667323198372331, 0.9661721727988709, 0.9656002591926595, 0.9650162678562694, 0.9644197809518007, 0.963810211137346, 0.9631867030272424, 0.9625479786024728, 0.9618920946479476, 0.9612160621406463, 0.960515249115452, 0.9597824442293293, 0.9590063894049982, 0.9581694836912424, 0.9572441982713142, 0.9561874992919275, 0.9549322212934084, 0.9533738465724599, 0.9513505440467306, 0.9486137609356399, 0.9447866567634884, 0.9393095556487799, 0.931378281524549, 0.9198978453844432, 0.9035059680653823, 0.8807635908261366, 0.8506211850517577, 0.813150281146812, 0.7702073311612423, 0.7253986665561324, 0.683002234874024, 0.6464218402788892, 0.6172431845172213, 0.5953331390420274, 0.5795477764245716, 0.5684376295963898, 0.56067114599772, 0.5551947139811684, 0.5512415211001872, 0.548280727101532, 0.5459559681769217, 0.5440325041416996, 0.5423574787978446, 0.5408320036342119, 0.5393922820409097, 0.5379971262280863, 0.5366198019738009, 0.5352427229045736, 0.5338539780693153, 0.5324450030630892, 0.5310089186683636, 0.5295391873477027, 0.5280282949721382, 0.5264661608985077, 0.5248379112332806, 0.523120504094927, 0.5212774476444999, 0.5192504723317455, 0.5169464963012924, 0.5142176320778147, 0.510831670461746, 0.5064314947132273, 0.5004868004121131, 0.4922553585777285, 0.48080005841630813, 0.465148288202575, 0.4446870990151646, 0.4197528972050259, 0.39205014412648737, 0.3643481475958486, 0.3394039033556392, 0.31889480841328677, 0.3031333494683175, 0.29149486967591504, 0.2830056980840342, 0.27673318709279876, 0.27194119761762875, 0.2681052966574141, 0.26487348948344197, 0.2620179803533529, 0.25939479238159896, 0.25691445935156376, 0.2545221994946993, 0.252185010926707, 0.2498834559198092, 0.2476064971096835, 0.24534827561874423, 0.2431061085022121, 0.2408792458280017, 0.23866809886839815, 0.23647375977441834, 0.23429770145237594, 0.23214158891787628, 0.230007159768039, 0.2278961476963598, 0.2258102330100734, 0.22375101028454492, 0.2217199670827591, 0.21971846999489306, 0.21774775567748367, 0.21580892544162705, 0.21390294246921998, 0.21203063105739625, 0.21019267748523618, 0.20838963221348056, 0.2066219131980726, 0.20488981014069688, 0.20319348952559, 0.2015330003087471, 0.19990828013742523, 0.19831916198701988, 0.1967653811103582, 0.1952465822019522, 0.19376232668711832, 0.1923121000531638, 0.19089531914697047, 0.18951133937004197, 0.18815946170808792, 0.1868389395370215, 0.18554898515020551, 0.18428877595197918, 0.18305746025864025, 0.18185416263823123, 0.18067798870186114, 0.17952802922767122, 0.17840336344758279, 0.1773030612471295, 0.17622618390561595, 0.1751717828159429, 0.1741388953381352, 0.1731265365088799, 0.17213368467756657, 0.17115925815686361, 0.1702020784973715, 0.16926081377496613, 0.16833389195143955, 0.1674193693998646, 0.1665147323062416, 0.16561659778927224, 0.16472026577642435, 0.16381905016984027, 0.16290328687853484, 0.16195887624597716, 0.16096517161310914, 0.15989198825881104, 0.15869551667373374, 0.15731307169093137, 0.15565707828036268, 0.15360979889293808, 0.15102242295026214, 0.14772527659996326, 0.1435585127655312, 0.13842983563486927, 0.13239023382843723, 0.1256904702185245, 0.11876426152696785, 0.11211656321452143, 0.1061694857566795, 0.10115724524234043, 0.09711682675707234, 0.09394800931566061, 0.09148862521591132, 0.08957014389569694, 0.0880463826080373, 0.08680249987194655, 0.08575353231137156, 0.08483896434365226, 0.08401673904311013, 0.08325809406496834, 0.08254356751313462, 0.08186008482906848, 0.0811989064682654, 0.08055421261408091, 0.07992214031133174, 0.0793001340414965, 0.07868651012226556, 0.07808016554440694, 0.0774803837579893, 0.07688670526661827, 0.07629884143020493, 0.07571661702829902, 0.07513993194901128, 0.07456873559103236, 0.07400300971655752, 0.07344275692459853, 0.07288799286596037, 0.07233874095329981, 0.07179502873923144, 0.07125688541376235, 0.07072434005689218, 0.07019742040455727, 0.06967615196717328, 0.06916055739374162, 0.06865065601005502, 0.06814646348308356, 0.06764799157920205, 0.06715524799422362, 0.06666823624001568, 0.06618695557697611, 0.06571140098462433, 0.06524156316453131, 0.06477742857112075, 0.06431897946674725, 0.06386619399804663, 0.06341904629095953, 0.06297750656211562, 0.06254154124447729, 0.06211111312530417, 0.061686181494634465, 0.061266702302594706, 0.06085262832395493, 0.06044390932844655, 0.06004049225545553, 0.05964232139179901, 0.059249338551385505, 0.0588614832556518, 0.058478692913759754, 0.05810090300162617, 0.05772804723894567, 0.05736005776345213, 0.0569968653017464, 0.05663839933609757, 0.05628458826670063, 0.05593535956894649, 0.0555906399453282, 0.05525035547167193, 0.054914431737441705, 0.054582793979923286, 0.05425536721214419, 0.05393207634443517, 0.053612846299581934, 0.05329760212155589, 0.05298626907784849, 0.05267877275546558, 0.05237503915066742, 0.05207499475256429, 0.05177856662070014, 0.05148568245677529, 0.05119627067067519, 0.05091026044098559, 0.050627581770185504, 0.050348165534717715, 0.05007194353014324, 0.04979884851159092, 0.04952881422971617, 0.04926177546238397, 0.048997668042292275, 0.04873642888074929, 0.048477995987817296, 0.04822230848903141, 0.04796930663889834, 0.047718931831375114, 0.04747112660752263, 0.04722583466052297, 0.04698300083824353, 0.046742571143524106, 0.04650449273235677, 0.04626871391012118, 0.0460351841260313, 0.045803853965941964, 0.045574675143657324, 0.04534760049087556, 0.04512258394589782, 0.04489958054122211, 0.04467854639013655, 0.04445943867241933, 0.04424221561924714, 0.044026836497406595, 0.04381326159289839, 0.04360145219401696, 0.04339137057398398, 0.04318297997320772, 0.042976244581236056, 0.042771129518465296, 0.04256760081766293, 0.04236562540535761, 0.042165171083145714, 0.041966206508959644, 0.04176870117833943, 0.04157262540574566, 0.04137795030594815, 0.04118464777552203, 0.04099269047447945, 0.040802051808062845, 0.04061270590872274, 0.04042462761830062, 0.04023779247043549, 0.04005217667321016, 0.03986775709205148, 0.03968451123289722, 0.03950241722564005, 0.039321453807857835, 0.03914160030883797, 0.038962836633902063, 0.038785143249036036, 0.0386085011658296, 0.038432891926728024, 0.03825829759059805, 0.03808470071860915, 0.037912084360430275, 0.037740432040741664, 0.03756972774606063, 0.037399955911879466, 0.03723110141011346, 0.037063149536855994, 0.03689608600043777, 0.036729896909786564, 0.0365645687630835, 0.0364000884367119, 0.03623644317449403, 0.03607362057721117, 0.03591160859240224, 0.03575039550443579, 0.035589969924850265, 0.03543032078295741, 0.03527143731670318, 0.03511330906378102, 0.034955925852991926, 0.03479927779584564, 0.034643355278397875, 0.03448814895331754, 0.03433364973217891, 0.034179848777973, 0.03402673749783287, 0.03387430753596736, 0.03372255076679792, 0.03357145928829343, 0.03342102541549752, 0.033271241674243494, 0.03312210079505173, 0.032973595707204505, 0.03282571953299349, 0.032678465582135025, 0.03253182734634845, 0.03238579849409301, 0.032240372865458694, 0.03209554446720664, 0.03195130746795478, 0.03180765619350449, 0.0316645851223042, 0.03152208888104581, 0.03138016224039013, 0.031238800110817398, 0.03109799753859927, 0.03095774970188851, 0.03081805190692298, 0.030678899584340443, 0.030540288285600802, 0.03040221367951253, 0.030264671548860214, 0.03012765778713003, 0.029991168395330198, 0.02985519947890357, 0.02971974724472949, 0.02958480799821217, 0.02945037814045303, 0.02931645416550427, 0.029183032657701388, 0.02905011028907203, 0.028917683816818945, 0.028785750080874743, 0.028654306001526225, 0.02852334857710622, 0.028392874881750765, 0.028262882063219703, 0.028133367340778734, 0.028004328003141003, 0.027875761406466512, 0.02774766497241744, 0.02762003618626781, 0.02749287259506572, 0.02736617180584672, 0.027239931483896536, 0.027114149351061895, 0.026988823184107877, 0.026863950813120326, 0.026739530119952143, 0.026615559036712005, 0.026492035544294266, 0.026368957670948906, 0.02624632349089013, 0.02612413112294277, 0.026002378729225038, 0.025881064513866875, 0.025760186721762578, 0.025639743637356913, 0.02551973358346358, 0.02540015492011524, 0.025281006043444017, 0.02516228538459174, 0.02504399140864902, 0.02492612261362229, 0.02480867752942811, 0.024691654716913834, 0.024575052766904033, 0.024458870299271844, 0.02434310596203457, 0.024227758430472892, 0.024112826406272995, 0.023998308616690986, 0.02388420381373898, 0.023770510773392296, 0.02365722829481717, 0.023544355199618325, 0.023431890331106126, 0.023319832553582415, 0.023208180751644922, 0.02309693382950943, 0.02298609071034944, 0.022875650335652746, 0.022765611664594565, 0.022655973673426696, 0.02254673535488241, 0.022437895717596537, 0.022329453785540458, 0.022221408597471563, 0.022113759206396848, 0.022006504679050222, 0.0218996440953833, 0.021793176548069216, 0.02168710114201919, 0.021581416993911556, 0.02147612323173289, 0.021371218994330986, 0.021266703430979347, 0.021162575700952972, 0.021058834973115063, 0.02095548042551456, 0.020852511244994, 0.020749926626807736, 0.020647725774250003, 0.02054590789829281, 0.0204444722172333, 0.020343417956350387, 0.020242744347570497, 0.020142450629142133, 0.020042536045319116, 0.019942999846052262, 0.019843841286689354, 0.019745059627683133, 0.019646654134307263, 0.019548624076379903, 0.019450968727994913, 0.019353687367260355, 0.019256779276044272, 0.019160243739727432, 0.019064080046963024, 0.018968287489443052, 0.01887286536167134, 0.018777812960742966, 0.01868312958612999, 0.018588814539473385, 0.018494867124380934, 0.018401286646231082, 0.018308072411982537, 0.018215223729989516, 0.01812273990982252, 0.018030620262094517, 0.0179388640982924, 0.017847470730613657, 0.017756439471808036, 0.01766576963502427, 0.017575460533661567, 0.01748551148122588, 0.017395921791190833, 0.017306690776863174, 0.017217817751252713, 0.017129302026946576, 0.017041142915987746, 0.0169533397297578, 0.016865891778863686, 0.016778798373028522, 0.01669205882098633, 0.016605672430380563, 0.016519638507666412, 0.01643395635801677, 0.016348625285231774, 0.01626364459165191, 0.01617901357807449, 0.016094731543673576, 0.016010797785923125, 0.0159272116005234, 0.015843972281330544, 0.0157610791202892, 0.015678531407368197, 0.015596328430499172, 0.015514469475518083, 0.015432953826109541, 0.01535178076375395, 0.015270949567677293, 0.015190459514803634, 0.015110309879710147, 0.015030499934584725, 0.014951028949186013, 0.014871896190805941, 0.014793100924234548, 0.014714642411727149, 0.014636519912973772, 0.014558732685070797, 0.014481279982494745, 0.014404161057078216, 0.014327375157987828, 0.014250921531704215, 0.014174799422003996, 0.014099008069943643, 0.014023546713845201, 0.013948414589283933, 0.01387361092907765, 0.013799134963277832, 0.01372498591916245, 0.013651163021230461, 0.013577665491197896, 0.01350449254799555, 0.013431643407768193, 0.013359117283875321, 0.013286913386893326, 0.013215030924619117, 0.013143469102075138, 0.013072227121515746, 0.01300130418243482, 0.012930699481574836, 0.012860412212936994, 0.012790441567792694, 0.012720786734696128, 0.012651446899498067, 0.012582421245360704, 0.012513708952773666, 0.012445309199571009, 0.012377221160949277, 0.012309444009486548, 0.01224197691516243, 0.012174819045379039, 0.012107969564982814, 0.012041427636287287, 0.011975192419096658, 0.011909263070730206, 0.01184363874604753, 0.011778318597474488, 0.011713301775030004, 0.011648587426353484, 0.011584174696732969, 0.01152006272913401, 0.011456250664229117, 0.011392737640427891, 0.011329522793907726, 0.011266605258645123, 0.011203984166447542, 0.011141658646985787, 0.011079627827826935, 0.01101789083446773, 0.01095644679036848, 0.010895294816987375, 0.010834434033815288, 0.010773863558410922, 0.01071358250643643, 0.010653589991693373, 0.010593885126159018, 0.01053446702002302, 0.010475334781724407, 0.010416487517988864, 0.010357924333866318, 0.010299644332768795, 0.010241646616508534, 0.010183930285336325, 0.010126494437980091, 0.010069338171683675, 0.010012460582245813, 0.009955860764059287, 0.009899537810150266, 0.009843490812217748, 0.009787718860673205, 0.009732221044680278, 0.009676996452194643, 0.009622044170003945, 0.009567363283767817, 0.009512952878057973, 0.009458812036398364, 0.009404939841305377, 0.009351335374328066, 0.00929799771608842, 0.00924492594632163, 0.009192119143916367, 0.009139576386955043, 0.009087296752754066, 0.00903527931790405, 0.008983523158310002, 0.008932027349231443, 0.008880790965322483, 0.00882981308067183, 0.008779092768842707, 0.008728629102912704, 0.008678421155513517, 0.008628467998870607, 0.00857876870484271, 0.00852932234496128, 0.008480127990469764, 0.008431184712362764, 0.008382491581425051, 0.008334047668270426, 0.008285852043380443, 0.008237903777142955, 0.00819020193989049, 0.008142745601938459, 0.008095533833623198, 0.008048565705339777, 0.00800184028757967, 0.007955356650968195, 0.007909113866301753, 0.007863111004584873, 0.007817347137067013, 0.00777182133527918, 0.007726532671070294, 0.007681480216643337, 0.007636663044591266, 0.0075920802279327, 0.007547730840147324, 0.007503613955211113, 0.0074597286476312495, 0.007416073992480797, 0.007372649065433157, 0.007329452942796211, 0.007286484701546224, 0.007243743419361493, 0.007201228174655694, 0.007158938046610976, 0.00711687211521079, 0.007075029461272404, 0.007033409166479166, 0.006992010313412475, 0.006950831985583463, 0.006909873267464386, 0.006869133244519735, 0.006828611003237045, 0.006788305631157408, 0.006748216216905702, 0.006708341850220505, 0.006668681621983734, 0.006629234624249943, 0.006589999950275366, 0.0065509766945466286, 0.0065121639528091515, 0.006473560822095263, 0.006435166400752002, 0.0063969797884686035, 0.006359000086303685, 0.006321226396712123, 0.006283657823571609, 0.006246293472208909, 0.006209132449425815, 0.006172173863524769, 0.0061354168243341715, 0.006098860443233415, 0.006062503833177564, 0.006026346108721742, 0.00599038638604521, 0.005954623782975124, 0.005919057419009983, 0.005883686415342761, 0.00584850989488375, 0.005813526982283061, 0.005778736803952826, 0.00574413848808911, 0.0057097311646934715, 0.005675513965594254, 0.005641486024467551, 0.0056076464768578605, 0.005573994460198438, 0.005540529113831337, 0.005507249579027163, 0.005474154999004492, 0.00544124451894901, 0.005408517286032344, 0.0053759724494305775, 0.005343609160342492, 0.0053114265720074815, 0.00527942383972318, 0.005247600120862802, 0.005215954574892169, 0.0051844863633864514, 0.005153194650046608, 0.0051220786007155576, 0.005091137383394025, 0.005060370168256117, 0.005029776127664622, 0.0049993544361859885, 0.004969104270605058, 0.004939024809939484, 0.00490911523545389, 0.004879374730673728, 0.004849802481398879, 0.004820397675716955, 0.004791159504016351, 0.0047620871589989875, 0.004733179835692827, 0.004704436731464078, 0.004675857046029153, 0.004647439981466352, 0.004619184742227296, 0.004591090535148064, 0.0045631565694601054, 0.0045353820568008775, 0.0045077662112242125, 0.0044803082492104514, 0.004453007389676314, 0.004425862853984512, 0.0043988738659531176, 0.0043720396518646875, 0.004345359440475135, 0.0043188324630223495, 0.004292457953234601, 0.004266235147338673, 0.004240163284067776, 0.004214241604669221, 0.004188469352911851, 0.004162845775093259, 0.004137370120046744, 0.00411204163914808, 0.0040868595863220196, 0.0040618232180485965, 0.004036931793369199, 0.004012184573892426, 0.003987580823799726, 0.003963119809850802, 0.003938800801388836, 0.0039146230703454715, 0.0038905858912456, 0.003866688541211939, 0.003842930299969398, 0.0038193104498492484, 0.003795828275793089, 0.0037724830653566035, 0.00374927410871314, 0.0037262006986570713, 0.0037032621306069776, 0.003680457702608635, 0.003657786715337812, 0.0036352484721028744, 0.003612842278847215, 0.0035905674441514945, 0.0035684232792356965, 0.003546409097961014, 0.0035245242168315447, 0.003502767954995826, 0.0034811396342481885, 0.003459638579029931, 0.0034382641164303444, 0.003417015576187556, 0.0033958922906892016, 0.003374893594972956, 0.00335401882672688, 0.0033332673262896208, 0.0033126384366504525, 0.00329213150344916, 0.00327174587497576, 0.003251480902170095, 0.0032313359386212494, 0.0032113103405668354, 0.0031914034668921263, 0.003171614679129051, 0.0031519433414550335, 0.003132388820691711, 0.0031129504863035, 0.0030936277103960244, 0.003074419867714422, 0.003055326335641502, 0.0030363464941957855, 0.0030174797260294093, 0.002998725416425896, 0.0029800829532978163, 0.002961551727184309, 0.0029431311312484902, 0.0029248205612747344, 0.002906619415665848, 0.00288852709544011, 0.002870543004228213, 0.002852666548270077, 0.0028348971364115672, 0.002817234180101087, 0.002799677093386066, 0.00278222529290935, 0.0027648781979054764, 0.0027476352301968447, 0.0027304958141897958, 0.0027134593768705826, 0.002696525347801245, 0.002679693159115382, 0.00266296224551384, 0.002646332044260299, 0.002629801995176762, 0.0026133715406389665, 0.0025970401255717003, 0.00258080719744402, 0.002564672206264402, 0.002548634604575796, 0.0025326938474505936, 0.002516849392485528, 0.002501100699796478, 0.002485447232013203, 0.0024698884542739977, 0.0024544238342202717, 0.0024390528419910512, 0.0024237749502174087, 0.0024085896340168295, 0.0023934963709874883, 0.0023784946412024766, 0.0023635839272039554, 0.0023487637139972275, 0.0023340334890447787, 0.0023193927422602086, 0.0023048409660021453, 0.002290377655068063, 0.0022760023066880635, 0.002261714420518579, 0.0022475134986360435, 0.002233399045530469, 0.0022193705680990184, 0.002205427575639466, 0.002191569579843662, 0.0021777960947908983, 0.0021641066369412596, 0.002150500725128895, 0.0021369778805552736, 0.0021235376267823586, 0.0021101794897257706, 0.0020969029976478743, 0.0020837076811508494, 0.00207059307316969, 0.002057558708965196, 0.0020446041261168927, 0.0020317288645159354, 0.002018932466357956, 0.002006214476135891, 0.001993574440632753, 0.0019810119089143955, 0.0019685264323222023, 0.0019561175644657912, 0.0019437848612156403, 0.0019315278806957268, 0.0019193461832760876, 0.0019072393315654032, 0.001895206890403497, 0.0018832484268538627, 0.0018713635101961167, 0.0018595517119184626, 0.001847812605710099, 0.001836145767453633, 0.0018245507752174444, 0.0018130272092480488, 0.001801574651962418, 0.0017901926879403058, 0.001778880903916524, 0.0017676388887732306, 0.0017564662335321692, 0.0017453625313469177, 0.0017343273774950987, 0.0017233603693705933, 0.0017124611064757186, 0.0017016291904134156, 0.0016908642248793953, 0.0016801658156543047, 0.0016695335705958407, 0.0016589670996308976, 0.0016484660147476579, 0.0016380299299877151, 0.0016276584614381537, 0.0016173512272236433, 0.0016071078474985076, 0.0015969279444388034, 0.0015868111422343717, 0.0015767570670809057, 0.0015667653471719916, 0.0015568356126911638, 0.0015469674958039374, 0.0015371606306498547, 0.0015274146533345114, 0.0015177292019215981, 0.0015081039164249197, 0.0014985384388004348, 0.0014890324129382747, 0.0014795854846547788, 0.0014701973016845113, 0.0014608675136723059, 0.0014515957721652763, 0.001442381730604867, 0.0014332250443188682, 0.0014241253705134696, 0.0014150823682652874, 0.0014060956985134166, 0.0013971650240514704, 0.0013882900095196432, 0.0013794703213967573, 0.001370705627992336, 0.0013619955994386642, 0.001353339907682875, 0.0013447382264790194, 0.0013361902313801693, 0.0013276955997305047, 0.001319254010657431, 0.0013108651450636822, 0.0013025286856194556, 0.0012942443167545353, 0.0012860117246504452, 0.001277830597232593, 0.0012697006241624374, 0.0012616214968296673, 0.0012535929083443802, 0.0012456145535292853, 0.001237686128911909, 0.0012298073327168218, 0.0012219778648578643, 0.0012141974269304049, 0.0012064657222035896, 0.0011987824556126269, 0.0011911473337510663, 0.0011835600648631085, 0.0011760203588359137, 0.0011685279271919438, 0.0011610824830812975, 0.0011536837412740822, 0.0011463314181527843, 0.0011390252317046692, 0.0011317649015141818, 0.0011245501487553867, 0.0011173806961843936, 0.0011102562681318336, 0.001103176590495322, 0.0010961413907319651, 0.0010891503978508613, 0.0010822033424056408, 0.0010752999564870025, 0.0010684399737152918, 0.0010616231292330755, 0.001054849159697753, 0.001048117803274173, 0.00104142879962728, 0.0010347818899147682, 0.0010281768167797716, 0.0010216133243435553, 0.0010150911581982421, 0.0010086100653995467, 0.0010021697944595435, 0.0009957700953394399, 0.0009894107194423798, 0.0009830914196062713, 0.0009768119500966224, 0.0009705720665994105, 0.0009643715262139622, 0.0009582100874458679, 0.0009520875101998996, 0.0009460035557729716, 0.0009399579868471029, 0.000933950567482419, 0.0009279810631101584, 0.0009220492405257201, 0.000916154867881712, 0.0009102977146810459, 0.0009044775517700311, 0.0008986941513315102, 0.0008929472868780022, 0.0008872367332448828, 0.0008815622665835708, 0.000875923664354758, 0.0008703207053216388, 0.0008647531695431904, 0.0008592208383674425, 0.0008537234944248088, 0.0008482609216214053, 0.0008428329051324167, 0.0008374392313954821, 0.0008320796881040915, 0.0008267540642010254, 0.0008214621498717989, 0.0008162037365381471, 0.0008109786168515182, 0.0008057865846866072, 0.0008006274351348969, 0.0007955009644982383, 0.000790406970282441, 0.0007853452511909022, 0.0007803156071182429, 0.0007753178391439892, 0.0007703517495262549, 0.0007654171416954723, 0.0007605138202481215, 0.0007556415909405111, 0.0007508002606825596, 0.0007459896375316187, 0.0007412095306863079, 0.0007364597504803868, 0.0007317401083766369, 0.0007270504169607837, 0.0007223904899354289, 0.0007177601421140193, 0.0007131591894148288, 0.000708587448854978, 0.000704044738544465, 0.0006995308776802331, 0.000695045686540251, 0.0006905889864776305, 0.0006861605999147545, 0.0006817603503374473, 0.0006773880622891477, 0.0006730435613651316, 0.0006687266742067325, 0.0006644372284956142, 0.0006601750529480411, 0.0006559399773091971, 0.0006517318323475094, 0.0006475504498490133, 0.0006433956626117275, 0.000639267304440065, 0.0006351652101392597, 0.0006310892155098273, 0.000627039157342036, 0.000623014873410422, 0.0006190162024683074, 0.0006150429842423612, 0.0006110950594271705, 0.0006071722696798482, 0.0006032744576146517, 0.0005994014667976407, 0.0005955531417413458, 0.0005917293278994718, 0.0005879298716616162, 0.0005841546203480207, 0.0005804034222043373, 0.0005766761263964302, 0.000572972583005187, 0.000569292643021371, 0.0005656361583404792, 0.0005620029817576416, 0.0005583929669625298, 0.0005548059685343015, 0.0005512418419365569, 0.0005477004435123316, 0.0005441816304791011, 0.0005406852609238192, 0.00053721119379797, 0.0005337592889126543, 0.0005303294069336893, 0.0005269214093767403, 0.0005235351586024677, 0.000520170517811706, 0.000516827351040656, 0.000513505523156112, 0.0005102048998507008, 0.0005069253476381528, 0.0005036667338485876, 0.0005004289266238343, 0.0004972117949127599, 0.000494015208466635, 0.0004908390378345103, 0.00048768315435862645, 0.00048454743016983746, 0.0004814317381830633, 0.00047833595209276024, 0.0004752599463684193, 0.0004722035962500786, 0.0004691667777438703, 0.0004661493676175759, 0.00046315124339621683, 0.0004601722833576558, 0.00045721236652823124, 0.0004542713726784021, 0.0004513491823184267, 0.000448445676694053, 0.0004455607377822392, 0.00044269424828688816, 0.00043984609163461177, 0.00043701615197050837, 0.0004342043141539717, 0.0004314104637545093, 0.00042863448704759643, 0.000425876271010536, 0.00042313570331835456, 0.0004204126723397077, 0.0004177070671328151, 0.00041501877744140917, 0.00041234769369071335, 0.0004096937069834323, 0.00040705670909577064, 0.0004044365924734661, 0.00040183325022785004, 0.0003992465761319204, 0.0003966764646164447, 0.0003941228107660745, 0.00039158551031548807, 0.0003890644596455464, 0.00038655955577947607, 0.00038407069637906544, 0.0003815977797408892, 0.0003791407047925441, 0.0003766993710889127, 0.00037427367880843893, 0.0003718635287494337, 0.0003694688223263888, 0.0003670894615663184, 0.0003647253491051195, 0.00036237638818394655, 0.0003600424826456135, 0.00035772353693100644, 0.0003554194560755242, 0.0003531301457055295, 0.00035085551203482883, 0.00034859546186116134, 0.0003463499025627155, 0.00034411874209465783, 0.00034190188898568626, 0.000339699252334596, 0.0003375107418068713, 0.0003353362676312878, 0.0003331757405965429, 0.0003310290720478931, 0.0003288961738838218, 0.00032677695855271407, 0.00032467133904956014, 0.0003225792289126669, 0.0003205005422203973, 0.0003184351935879185, 0.000316383098163976, 0.00031434417162767923, 0.00031231833018530945, 0.0003103054905671411, 0.00030830557002428633, 0.00030631848632555066, 0.0003043441577543116, 0.0003023825031054102, 0.0003004334416820642, 0.00029849689329279323, 0.00029657277824836727, 0.000294661017358766, 0.00029276153193016056, 0.00029087424376190735, 0.0002889990751435635, 0.0002871359488519135, 0.00028528478814801903, 0.0002834455167742793, 0.0002816180589515122, 0.0002798023393760488, 0.00027799828321684776, 0.00027620581611262113, 0.0002744248641689822, 0.0002726553539556037, 0.0002708972125033982, 0.0002691503673017058, 0.0002674147462955109, 0.0002656902778826581, 0.00026397689091110083, 0.000262274514676151, 0.0002605830789177562, 0.00025890251381778333, 0.00025723274999732394, 0.0002555737185140104, 0.0002539253508593521, 0.0002522875789560811, 0.00025066033515551943, 0.0002490435522349554, 0.0002474371633950403, 0.00024584110225719507, 0.00024425530286103657, 0.00024267969966181382, 0.00024111422752786461, 0.00023955882173808078, 0.0002380134179793933, 0.0002364779523442677, 0.00023495236132821778, 0.00023343658182732938, 0.0002319305511358033, 0.00023043420694350794, 0.00022894748733355002, 0.0002274703307798553, 0.00022600267614476794, 0.0002245444626766588, 0.00022309563000755316, 0.00022165611815076644, 0.000220225867498559, 0.0002188048188197999, 0.00021739291325764893, 0.00021599009232724705, 0.00021459629791342554, 0.00021321147226842412, 0.00021183555800962568, 0.00021046849811730162, 0.00020911023593237288, 0.00020776071515418116, 0.0002064198798382772, 0.00020508767439421727, 0.00020376404358337746, 0.00020244893251677513, 0.00020114228665291133, 0.00019984405179561496, 0.0001985541740919117, 0.00019727260002989422, 0.00019599927643661435, 0.00019473415047598035, 0.00019347716964667223, 0.00019222828178006485, 0.00019098743503816738, 0.00018975457791157074, 0.00018852965921741156, 0.00018731262809734375, 0.0001861034340155266, 0.00018490202675662055, 0.00018370835642379853, 0.00018252237343676587, 0.00018134402852979512, 0.00018017327274976906, 0.00017901005745423924, 0.0001778543343094922, 0.0001767060552886309, 0.00017556517266966392, 0.0001744316390336096, 0.0001733054072626078, 0.00017218643053804717, 0.00017107466233869925, 0.0001699700564388673, 0.0001688725669065435, 0.00016778214810157967, 0.0001666987546738658, 0.0001656223415615234, 0.00016455286398910562, 0.0001634902774658119, 0.00016243453778371007, 0.000161385601015971, 0.00016034342351511433, 0.00015930796191126236, 0.0001582791731104074, 0.00015725701429268656, 0.00015624144291067016, 0.00015523241668765605, 0.00015422989361598064, 0.00015323383195533211, 0.00015224419023108184, 0.00015126092723261855, 0.00015028400201169895, 0.00014931337388080344, 0.0001483490024115047, 0.0001473908474328445, 0.00014643886902972154, 0.00014549302754128757, 0.00014455328355935537, 0.0001436195979268137, 0.00014269193173605438, 0.00014177024632740692, 0.00014085450328758423, 0.000139944664448136, 0.0001390406918839137, 0.00013814254791154259, 0.00013725019508790487, 0.00013636359620863056, 0.00013548271430659903, 0.00013460751265044794, 0.00013373795474309313, 0.00013287400432025574, 0.0001320156253489999, 0.0001311627820262777, 0.00013031543877748482, 0.00012947356025502275, 0.00012863711133687255, 0.00012780605712517463, 0.00012698036294481923, 0.00012615999434204336, 0.0001253449170830397, 0.0001245350971525695, 0.0001237305007525884, 0.00012293109430087723, 0.00012213684442968352, 0.00012134771798436942, 0.00012056368202207, 0.00011978470381035746, 0.00011901075082591585, 0.00011824179075322158, 0.00011747779148323435, 0.00011671872111209356, 0.000115964547939826, 0.00011521524046905729, 0.00011447076740373617, 0.00011373109764786097, 0.00011299620030422019, 0.00011226604467313437, 0.00011154060025121151, 0.00011081983673010572, 0.00011010372399528653, 0.00010939223212481339, 0.00010868533138812013, 0.00010798299224480456, 0.00010728518534342741, 0.0001065918815203173, 0.00010590305179838431, 0.00010521866738593933, 0.00010453869967552265, 0.0001038631202427377, 0.00010319190084509403, 0.00010252501342085534, 0.00010186243008789681, 0.00010120412314256711, 0.00010055006505856019, 9.990022848579128e-05, 9.925458624928205e-05, 9.861311134805105e-05, 9.797577695401252e-05, 9.734255641088022e-05, 9.671342323308007e-05, 9.608835110466779e-05, 9.546731387825447e-05, 9.485028557393775e-05, 9.423724037824083e-05, 9.362815264305662e-05, 9.302299688460014e-05, 9.24217477823656e-05, 9.182438017809176e-05, 9.123086907473184e-05, 9.064118963543186e-05, 9.005531718251311e-05, 8.947322719646333e-05, 8.889489531493185e-05, 8.832029733173295e-05, 8.77494091958538e-05, 8.718220701047004e-05, 8.661866703196555e-05, 8.60587656689615e-05, 8.550247948134709e-05, 8.494978517932105e-05, 8.440065962243455e-05, 8.38550798186441e-05, 8.331302292336753e-05, 8.277446623854729e-05, 8.22393872117188e-05, 8.170776343508553e-05, 8.117957264459859e-05, 8.065479271904353e-05, 8.013340167913147e-05, 7.961537768659697e-05, 7.91006990433007e-05, 7.858934419033849e-05, 7.808129170715504e-05, 7.757652031066439e-05, 7.707500885437444e-05, 7.657673632751829e-05, 7.608168185418995e-05, 7.558982469248638e-05, 7.510114423365377e-05, 7.461562000124067e-05, 7.413323165025478e-05, 7.365395896632644e-05, 7.317778186487626e-05, 7.270468039028891e-05, 7.223463471509091e-05, 7.17676251391352e-05, 7.130363208878912e-05, 7.084263611612856e-05, 7.038461789813713e-05, 6.992955823590934e-05, 6.947743805386048e-05, 6.902823839893967e-05, 6.858194043984926e-05, 6.813852546626808e-05, 6.769797488808061e-05, 6.726027023460954e-05, 6.68253931538552e-05, 6.639332541173731e-05, 6.596404889134416e-05, 6.55375455921835e-05, 6.51137976294416e-05, 6.469278723324342e-05, 6.427449674792039e-05, 6.385890863128081e-05, 6.344600545388614e-05, 6.303576989833063e-05, 6.262818475852685e-05, 6.22232329389944e-05, 6.18208974541542e-05, 6.142116142762629e-05, 6.102400809153287e-05, 6.0629420785804914e-05, 6.0237382957494166e-05, 5.9847878160088285e-05, 5.946089005283148e-05, 5.907640240004823e-05, 5.8694399070472574e-05, 5.831486403658043e-05, 5.793778137392699e-05, 5.756313526048763e-05, 5.7190909976003755e-05, 5.6821089901331724e-05, 5.6453659517797074e-05, 5.608860340655174e-05, 5.5725906247936286e-05, 5.536555282084517e-05, 5.5007528002097045e-05, 5.465181676580805e-05, 5.42984041827701e-05, 5.394727541983194e-05, 5.3598415739285274e-05, 5.3251810498253766e-05, 5.290744514808681e-05, 5.256530523375607e-05, 5.222537639325715e-05, 5.1887644357013716e-05, 5.155209494728655e-05, 5.121871407758528e-05, 5.0887487752084885e-05, 5.0558402065044804e-05, 5.023144320023289e-05, 4.9906597430351805e-05, 4.958385111647029e-05, 4.926319070745644e-05, 4.8944602739416914e-05, 4.8628073835136745e-05, 4.831359070352545e-05, 4.8001140139064805e-05, 4.769070902126118e-05, 4.738228431410042e-05, 4.707585306550728e-05, 4.677140240680718e-05, 4.646891955219235e-05, 4.616839179819047e-05, 4.586980652313753e-05, 4.5573151186653134e-05, 4.5278413329120146e-05, 4.498558057116663e-05, 4.4694640613151965e-05, 4.440558123465541e-05, 4.411839029396868e-05, 4.3833055727590964e-05, 4.354956554972806e-05, 4.326790785179372e-05, 4.2988070801915e-05, 4.2710042644440045e-05, 4.243381169944971e-05, 4.215936636227149e-05, 4.1886695102997336e-05, 4.16157864660039e-05, 4.134662906947631e-05, 4.107921160493447e-05, 4.081352283676298e-05, 4.0549551601743286e-05, 4.028728680858976e-05, 4.002671743748767e-05, 3.976783253963507e-05 ], + "y": [ 0.001, 0.002, 0.003, 0.004, 0.005, 0.006, 0.007, 0.008, 0.009000000000000001, 0.010000000000000002, 0.011, 0.012, 0.013000000000000001, 0.014000000000000002, 0.015, 0.016, 0.017, 0.018000000000000002, 0.019000000000000003, 0.02, 0.021, 0.022000000000000002, 0.023, 0.024, 0.025, 0.026000000000000002, 0.027000000000000003, 0.028, 0.029, 0.030000000000000002, 0.031, 0.032, 0.033, 0.034, 0.035, 0.036000000000000004, 0.037000000000000005, 0.038, 0.039, 0.04, 0.041, 0.042, 0.043000000000000003, 0.044000000000000004, 0.045, 0.046, 0.047, 0.048, 0.049, 0.05, 0.051000000000000004, 0.052000000000000005, 0.053000000000000005, 0.054, 0.055, 0.056, 0.057, 0.058, 0.059000000000000004, 0.060000000000000005, 0.061, 0.062, 0.063, 0.064, 0.065, 0.066, 0.067, 0.068, 0.069, 0.07, 0.07100000000000001, 0.07200000000000001, 0.07300000000000001, 0.074, 0.075, 0.076, 0.077, 0.078, 0.079, 0.08, 0.081, 0.082, 0.083, 0.084, 0.085, 0.08600000000000001, 0.08700000000000001, 0.08800000000000001, 0.089, 0.09, 0.091, 0.092, 0.093, 0.094, 0.095, 0.096, 0.097, 0.098, 0.099, 0.1, 0.101, 0.10200000000000001, 0.10300000000000001, 0.10400000000000001, 0.10500000000000001, 0.106, 0.107, 0.108, 0.109, 0.11, 0.111, 0.112, 0.113, 0.114, 0.115, 0.116, 0.117, 0.11800000000000001, 0.11900000000000001, 0.12000000000000001, 0.121, 0.122, 0.123, 0.124, 0.125, 0.126, 0.127, 0.128, 0.129, 0.13, 0.131, 0.132, 0.133, 0.134, 0.135, 0.136, 0.137, 0.138, 0.139, 0.14, 0.14100000000000001, 0.14200000000000002, 0.14300000000000002, 0.14400000000000002, 0.14500000000000002, 0.146, 0.147, 0.148, 0.149, 0.15, 0.151, 0.152, 0.153, 0.154, 0.155, 0.156, 0.157, 0.158, 0.159, 0.16, 0.161, 0.162, 0.163, 0.164, 0.165, 0.166, 0.167, 0.168, 0.169, 0.17, 0.171, 0.17200000000000001, 0.17300000000000001, 0.17400000000000002, 0.17500000000000002, 0.17600000000000002, 0.177, 0.178, 0.179, 0.18, 0.181, 0.182, 0.183, 0.184, 0.185, 0.186, 0.187, 0.188, 0.189, 0.19, 0.191, 0.192, 0.193, 0.194, 0.195, 0.196, 0.197, 0.198, 0.199, 0.2, 0.201, 0.202, 0.203, 0.20400000000000001, 0.20500000000000002, 0.20600000000000002, 0.20700000000000002, 0.20800000000000002, 0.20900000000000002, 0.21, 0.211, 0.212, 0.213, 0.214, 0.215, 0.216, 0.217, 0.218, 0.219, 0.22, 0.221, 0.222, 0.223, 0.224, 0.225, 0.226, 0.227, 0.228, 0.229, 0.23, 0.231, 0.232, 0.233, 0.234, 0.23500000000000001, 0.23600000000000002, 0.23700000000000002, 0.23800000000000002, 0.23900000000000002, 0.24000000000000002, 0.241, 0.242, 0.243, 0.244, 0.245, 0.246, 0.247, 0.248, 0.249, 0.25, 0.251, 0.252, 0.253, 0.254, 0.255, 0.256, 0.257, 0.258, 0.259, 0.26, 0.261, 0.262, 0.263, 0.264, 0.265, 0.266, 0.267, 0.268, 0.269, 0.27, 0.271, 0.272, 0.273, 0.274, 0.275, 0.276, 0.277, 0.278, 0.279, 0.28, 0.281, 0.28200000000000003, 0.28300000000000003, 0.28400000000000003, 0.28500000000000003, 0.28600000000000003, 0.28700000000000003, 0.28800000000000003, 0.28900000000000003, 0.29, 0.291, 0.292, 0.293, 0.294, 0.295, 0.296, 0.297, 0.298, 0.299, 0.3, 0.301, 0.302, 0.303, 0.304, 0.305, 0.306, 0.307, 0.308, 0.309, 0.31, 0.311, 0.312, 0.313, 0.314, 0.315, 0.316, 0.317, 0.318, 0.319, 0.32, 0.321, 0.322, 0.323, 0.324, 0.325, 0.326, 0.327, 0.328, 0.329, 0.33, 0.331, 0.332, 0.333, 0.334, 0.335, 0.336, 0.337, 0.338, 0.339, 0.34, 0.341, 0.342, 0.343, 0.34400000000000003, 0.34500000000000003, 0.34600000000000003, 0.34700000000000003, 0.34800000000000003, 0.34900000000000003, 0.35000000000000003, 0.35100000000000003, 0.35200000000000004, 0.353, 0.354, 0.355, 0.356, 0.357, 0.358, 0.359, 0.36, 0.361, 0.362, 0.363, 0.364, 0.365, 0.366, 0.367, 0.368, 0.369, 0.37, 0.371, 0.372, 0.373, 0.374, 0.375, 0.376, 0.377, 0.378, 0.379, 0.38, 0.381, 0.382, 0.383, 0.384, 0.385, 0.386, 0.387, 0.388, 0.389, 0.39, 0.391, 0.392, 0.393, 0.394, 0.395, 0.396, 0.397, 0.398, 0.399, 0.4, 0.401, 0.402, 0.403, 0.404, 0.405, 0.406, 0.40700000000000003, 0.40800000000000003, 0.40900000000000003, 0.41000000000000003, 0.41100000000000003, 0.41200000000000003, 0.41300000000000003, 0.41400000000000003, 0.41500000000000004, 0.41600000000000004, 0.41700000000000004, 0.418, 0.419, 0.42, 0.421, 0.422, 0.423, 0.424, 0.425, 0.426, 0.427, 0.428, 0.429, 0.43, 0.431, 0.432, 0.433, 0.434, 0.435, 0.436, 0.437, 0.438, 0.439, 0.44, 0.441, 0.442, 0.443, 0.444, 0.445, 0.446, 0.447, 0.448, 0.449, 0.45, 0.451, 0.452, 0.453, 0.454, 0.455, 0.456, 0.457, 0.458, 0.459, 0.46, 0.461, 0.462, 0.463, 0.464, 0.465, 0.466, 0.467, 0.468, 0.46900000000000003, 0.47000000000000003, 0.47100000000000003, 0.47200000000000003, 0.47300000000000003, 0.47400000000000003, 0.47500000000000003, 0.47600000000000003, 0.47700000000000004, 0.47800000000000004, 0.47900000000000004, 0.48000000000000004, 0.481, 0.482, 0.483, 0.484, 0.485, 0.486, 0.487, 0.488, 0.489, 0.49, 0.491, 0.492, 0.493, 0.494, 0.495, 0.496, 0.497, 0.498, 0.499, 0.5, 0.501, 0.502, 0.503, 0.504, 0.505, 0.506, 0.507, 0.508, 0.509, 0.51, 0.511, 0.512, 0.513, 0.514, 0.515, 0.516, 0.517, 0.518, 0.519, 0.52, 0.521, 0.522, 0.523, 0.524, 0.525, 0.526, 0.527, 0.528, 0.529, 0.53, 0.531, 0.532, 0.533, 0.534, 0.535, 0.536, 0.537, 0.538, 0.539, 0.54, 0.541, 0.542, 0.543, 0.544, 0.545, 0.546, 0.547, 0.548, 0.549, 0.55, 0.551, 0.552, 0.553, 0.554, 0.555, 0.556, 0.557, 0.558, 0.559, 0.56, 0.561, 0.562, 0.5630000000000001, 0.5640000000000001, 0.5650000000000001, 0.5660000000000001, 0.5670000000000001, 0.5680000000000001, 0.5690000000000001, 0.5700000000000001, 0.5710000000000001, 0.5720000000000001, 0.5730000000000001, 0.5740000000000001, 0.5750000000000001, 0.5760000000000001, 0.5770000000000001, 0.578, 0.579, 0.58, 0.581, 0.582, 0.583, 0.584, 0.585, 0.586, 0.587, 0.588, 0.589, 0.59, 0.591, 0.592, 0.593, 0.594, 0.595, 0.596, 0.597, 0.598, 0.599, 0.6, 0.601, 0.602, 0.603, 0.604, 0.605, 0.606, 0.607, 0.608, 0.609, 0.61, 0.611, 0.612, 0.613, 0.614, 0.615, 0.616, 0.617, 0.618, 0.619, 0.62, 0.621, 0.622, 0.623, 0.624, 0.625, 0.626, 0.627, 0.628, 0.629, 0.63, 0.631, 0.632, 0.633, 0.634, 0.635, 0.636, 0.637, 0.638, 0.639, 0.64, 0.641, 0.642, 0.643, 0.644, 0.645, 0.646, 0.647, 0.648, 0.649, 0.65, 0.651, 0.652, 0.653, 0.654, 0.655, 0.656, 0.657, 0.658, 0.659, 0.66, 0.661, 0.662, 0.663, 0.664, 0.665, 0.666, 0.667, 0.668, 0.669, 0.67, 0.671, 0.672, 0.673, 0.674, 0.675, 0.676, 0.677, 0.678, 0.679, 0.68, 0.681, 0.682, 0.683, 0.684, 0.685, 0.686, 0.687, 0.6880000000000001, 0.6890000000000001, 0.6900000000000001, 0.6910000000000001, 0.6920000000000001, 0.6930000000000001, 0.6940000000000001, 0.6950000000000001, 0.6960000000000001, 0.6970000000000001, 0.6980000000000001, 0.6990000000000001, 0.7000000000000001, 0.7010000000000001, 0.7020000000000001, 0.7030000000000001, 0.7040000000000001, 0.705, 0.706, 0.707, 0.708, 0.709, 0.71, 0.711, 0.712, 0.713, 0.714, 0.715, 0.716, 0.717, 0.718, 0.719, 0.72, 0.721, 0.722, 0.723, 0.724, 0.725, 0.726, 0.727, 0.728, 0.729, 0.73, 0.731, 0.732, 0.733, 0.734, 0.735, 0.736, 0.737, 0.738, 0.739, 0.74, 0.741, 0.742, 0.743, 0.744, 0.745, 0.746, 0.747, 0.748, 0.749, 0.75, 0.751, 0.752, 0.753, 0.754, 0.755, 0.756, 0.757, 0.758, 0.759, 0.76, 0.761, 0.762, 0.763, 0.764, 0.765, 0.766, 0.767, 0.768, 0.769, 0.77, 0.771, 0.772, 0.773, 0.774, 0.775, 0.776, 0.777, 0.778, 0.779, 0.78, 0.781, 0.782, 0.783, 0.784, 0.785, 0.786, 0.787, 0.788, 0.789, 0.79, 0.791, 0.792, 0.793, 0.794, 0.795, 0.796, 0.797, 0.798, 0.799, 0.8, 0.801, 0.802, 0.803, 0.804, 0.805, 0.806, 0.807, 0.808, 0.809, 0.81, 0.811, 0.812, 0.8130000000000001, 0.8140000000000001, 0.8150000000000001, 0.8160000000000001, 0.8170000000000001, 0.8180000000000001, 0.8190000000000001, 0.8200000000000001, 0.8210000000000001, 0.8220000000000001, 0.8230000000000001, 0.8240000000000001, 0.8250000000000001, 0.8260000000000001, 0.8270000000000001, 0.8280000000000001, 0.8290000000000001, 0.8300000000000001, 0.8310000000000001, 0.8320000000000001, 0.8330000000000001, 0.834, 0.835, 0.836, 0.837, 0.838, 0.839, 0.84, 0.841, 0.842, 0.843, 0.844, 0.845, 0.846, 0.847, 0.848, 0.849, 0.85, 0.851, 0.852, 0.853, 0.854, 0.855, 0.856, 0.857, 0.858, 0.859, 0.86, 0.861, 0.862, 0.863, 0.864, 0.865, 0.866, 0.867, 0.868, 0.869, 0.87, 0.871, 0.872, 0.873, 0.874, 0.875, 0.876, 0.877, 0.878, 0.879, 0.88, 0.881, 0.882, 0.883, 0.884, 0.885, 0.886, 0.887, 0.888, 0.889, 0.89, 0.891, 0.892, 0.893, 0.894, 0.895, 0.896, 0.897, 0.898, 0.899, 0.9, 0.901, 0.902, 0.903, 0.904, 0.905, 0.906, 0.907, 0.908, 0.909, 0.91, 0.911, 0.912, 0.913, 0.914, 0.915, 0.916, 0.917, 0.918, 0.919, 0.92, 0.921, 0.922, 0.923, 0.924, 0.925, 0.926, 0.927, 0.928, 0.929, 0.93, 0.931, 0.932, 0.933, 0.934, 0.935, 0.936, 0.937, 0.9380000000000001, 0.9390000000000001, 0.9400000000000001, 0.9410000000000001, 0.9420000000000001, 0.9430000000000001, 0.9440000000000001, 0.9450000000000001, 0.9460000000000001, 0.9470000000000001, 0.9480000000000001, 0.9490000000000001, 0.9500000000000001, 0.9510000000000001, 0.9520000000000001, 0.9530000000000001, 0.9540000000000001, 0.9550000000000001, 0.9560000000000001, 0.9570000000000001, 0.9580000000000001, 0.9590000000000001, 0.9600000000000001, 0.961, 0.962, 0.963, 0.964, 0.965, 0.966, 0.967, 0.968, 0.969, 0.97, 0.971, 0.972, 0.973, 0.974, 0.975, 0.976, 0.977, 0.978, 0.979, 0.98, 0.981, 0.982, 0.983, 0.984, 0.985, 0.986, 0.987, 0.988, 0.989, 0.99, 0.991, 0.992, 0.993, 0.994, 0.995, 0.996, 0.997, 0.998, 0.999, 1.0, 1.001, 1.002, 1.003, 1.004, 1.005, 1.006, 1.007, 1.008, 1.009, 1.01, 1.011, 1.012, 1.013, 1.014, 1.015, 1.016, 1.017, 1.018, 1.019, 1.02, 1.021, 1.022, 1.023, 1.024, 1.025, 1.0259999999999998, 1.027, 1.0279999999999998, 1.029, 1.0299999999999998, 1.031, 1.0319999999999998, 1.033, 1.0339999999999998, 1.035, 1.0359999999999998, 1.037, 1.0379999999999998, 1.039, 1.0399999999999998, 1.041, 1.0419999999999998, 1.043, 1.0439999999999998, 1.045, 1.0459999999999998, 1.047, 1.0479999999999998, 1.049, 1.0499999999999998, 1.051, 1.0519999999999998, 1.053, 1.0539999999999998, 1.055, 1.0559999999999998, 1.057, 1.0579999999999998, 1.059, 1.0599999999999998, 1.061, 1.0619999999999998, 1.063, 1.0639999999999998, 1.065, 1.0659999999999998, 1.067, 1.0679999999999998, 1.069, 1.0699999999999998, 1.071, 1.0719999999999998, 1.073, 1.0739999999999998, 1.075, 1.0759999999999998, 1.077, 1.0779999999999998, 1.079, 1.0799999999999998, 1.081, 1.0819999999999999, 1.083, 1.0839999999999999, 1.085, 1.0859999999999999, 1.087, 1.0879999999999999, 1.089, 1.0899999999999999, 1.091, 1.0919999999999999, 1.093, 1.0939999999999999, 1.095, 1.0959999999999999, 1.097, 1.0979999999999999, 1.099, 1.0999999999999999, 1.101, 1.1019999999999999, 1.103, 1.1039999999999999, 1.105, 1.1059999999999999, 1.107, 1.1079999999999999, 1.109, 1.1099999999999999, 1.111, 1.1119999999999999, 1.113, 1.1139999999999999, 1.115, 1.1159999999999999, 1.117, 1.1179999999999999, 1.119, 1.1199999999999999, 1.121, 1.1219999999999999, 1.123, 1.1239999999999999, 1.125, 1.126, 1.127, 1.128, 1.129, 1.13, 1.131, 1.132, 1.133, 1.134, 1.135, 1.136, 1.137, 1.138, 1.139, 1.14, 1.141, 1.142, 1.143, 1.144, 1.145, 1.146, 1.147, 1.148, 1.149, 1.15, 1.151, 1.152, 1.153, 1.154, 1.1549999999999998, 1.156, 1.1569999999999998, 1.158, 1.1589999999999998, 1.16, 1.1609999999999998, 1.162, 1.1629999999999998, 1.164, 1.1649999999999998, 1.166, 1.1669999999999998, 1.168, 1.1689999999999998, 1.17, 1.1709999999999998, 1.172, 1.1729999999999998, 1.174, 1.1749999999999998, 1.176, 1.1769999999999998, 1.178, 1.1789999999999998, 1.18, 1.1809999999999998, 1.182, 1.1829999999999998, 1.184, 1.1849999999999998, 1.186, 1.1869999999999998, 1.188, 1.1889999999999998, 1.19, 1.1909999999999998, 1.192, 1.1929999999999998, 1.194, 1.1949999999999998, 1.196, 1.1969999999999998, 1.198, 1.1989999999999998, 1.2, 1.2009999999999998, 1.202, 1.2029999999999998, 1.204, 1.2049999999999998, 1.206, 1.2069999999999999, 1.208, 1.2089999999999999, 1.21, 1.2109999999999999, 1.212, 1.2129999999999999, 1.214, 1.2149999999999999, 1.216, 1.2169999999999999, 1.218, 1.2189999999999999, 1.22, 1.2209999999999999, 1.222, 1.2229999999999999, 1.224, 1.2249999999999999, 1.226, 1.2269999999999999, 1.228, 1.2289999999999999, 1.23, 1.2309999999999999, 1.232, 1.2329999999999999, 1.234, 1.2349999999999999, 1.236, 1.2369999999999999, 1.238, 1.2389999999999999, 1.24, 1.2409999999999999, 1.242, 1.2429999999999999, 1.244, 1.2449999999999999, 1.246, 1.2469999999999999, 1.248, 1.2489999999999999, 1.25, 1.251, 1.252, 1.253, 1.254, 1.255, 1.256, 1.257, 1.258, 1.259, 1.26, 1.261, 1.262, 1.263, 1.264, 1.265, 1.266, 1.267, 1.268, 1.269, 1.27, 1.271, 1.272, 1.273, 1.274, 1.275, 1.276, 1.277, 1.278, 1.279, 1.28, 1.281, 1.2819999999999998, 1.283, 1.2839999999999998, 1.285, 1.2859999999999998, 1.287, 1.2879999999999998, 1.289, 1.2899999999999998, 1.291, 1.2919999999999998, 1.293, 1.2939999999999998, 1.295, 1.2959999999999998, 1.297, 1.2979999999999998, 1.299, 1.2999999999999998, 1.301, 1.3019999999999998, 1.303, 1.3039999999999998, 1.305, 1.3059999999999998, 1.307, 1.3079999999999998, 1.309, 1.3099999999999998, 1.311, 1.3119999999999998, 1.313, 1.3139999999999998, 1.315, 1.3159999999999998, 1.317, 1.3179999999999998, 1.319, 1.3199999999999998, 1.321, 1.3219999999999998, 1.323, 1.3239999999999998, 1.325, 1.3259999999999998, 1.327, 1.3279999999999998, 1.329, 1.3299999999999998, 1.331, 1.3319999999999999, 1.333, 1.3339999999999999, 1.335, 1.3359999999999999, 1.337, 1.3379999999999999, 1.339, 1.3399999999999999, 1.341, 1.3419999999999999, 1.343, 1.3439999999999999, 1.345, 1.3459999999999999, 1.347, 1.3479999999999999, 1.349, 1.3499999999999999, 1.351, 1.3519999999999999, 1.353, 1.3539999999999999, 1.355, 1.3559999999999999, 1.357, 1.3579999999999999, 1.359, 1.3599999999999999, 1.361, 1.3619999999999999, 1.363, 1.3639999999999999, 1.365, 1.3659999999999999, 1.367, 1.3679999999999999, 1.369, 1.3699999999999999, 1.371, 1.3719999999999999, 1.373, 1.3739999999999999, 1.375, 1.376, 1.377, 1.378, 1.379, 1.38, 1.381, 1.382, 1.383, 1.384, 1.385, 1.386, 1.387, 1.388, 1.389, 1.39, 1.391, 1.392, 1.393, 1.394, 1.395, 1.396, 1.397, 1.398, 1.399, 1.4, 1.401, 1.402, 1.403, 1.404, 1.405, 1.406, 1.407, 1.408, 1.4089999999999998, 1.41, 1.4109999999999998, 1.412, 1.4129999999999998, 1.414, 1.4149999999999998, 1.416, 1.4169999999999998, 1.418, 1.4189999999999998, 1.42, 1.4209999999999998, 1.422, 1.4229999999999998, 1.424, 1.4249999999999998, 1.426, 1.4269999999999998, 1.428, 1.4289999999999998, 1.43, 1.4309999999999998, 1.432, 1.4329999999999998, 1.434, 1.4349999999999998, 1.436, 1.4369999999999998, 1.438, 1.4389999999999998, 1.44, 1.4409999999999998, 1.442, 1.4429999999999998, 1.444, 1.4449999999999998, 1.446, 1.4469999999999998, 1.448, 1.4489999999999998, 1.45, 1.4509999999999998, 1.452, 1.4529999999999998, 1.454, 1.4549999999999998, 1.456, 1.4569999999999999, 1.458, 1.4589999999999999, 1.46, 1.4609999999999999, 1.462, 1.4629999999999999, 1.464, 1.4649999999999999, 1.466, 1.4669999999999999, 1.468, 1.4689999999999999, 1.47, 1.4709999999999999, 1.472, 1.4729999999999999, 1.474, 1.4749999999999999, 1.476, 1.4769999999999999, 1.478, 1.4789999999999999, 1.48, 1.4809999999999999, 1.482, 1.4829999999999999, 1.484, 1.4849999999999999, 1.486, 1.4869999999999999, 1.488, 1.4889999999999999, 1.49, 1.4909999999999999, 1.492, 1.4929999999999999, 1.494, 1.4949999999999999, 1.496, 1.4969999999999999, 1.498, 1.4989999999999999 ] + }, + "Negative electrode lithiation OCP [V]": { + "x": [ 0.9771857548058345, 0.9771057026269641, 0.9770246440438949, 0.9769425602795043, 0.9768594319238472, 0.9767752389028015, 0.9766899604450024, 0.976603575046968, 0.9765160604363217, 0.9764273935330067, 0.9763375504083883, 0.9762465062421268, 0.9761542352767058, 0.9760607107694925, 0.9759659049421922, 0.9758697889275714, 0.9757723327132958, 0.975673505082737, 0.9755732735525914, 0.9754716043071456, 0.9753684621290122, 0.975263810326161, 0.9751576106550548, 0.9750498232396891, 0.9749404064863374, 0.9748293169937788, 0.9747165094587932, 0.97460193657668, 0.9744855489365722, 0.9743672949112756, 0.974247120541385, 0.9741249694133965, 0.9740007825315304, 0.9738744981829732, 0.9737460517962198, 0.9736153757921985, 0.9734823994278303, 0.9733470486316519, 0.9732092458311066, 0.9730689097710572, 0.9729259553230073, 0.9727802932844289, 0.9726318301674334, 0.972480467975804, 0.9723261039690413, 0.972168630411521, 0.972007934303979, 0.9718438970931688, 0.9716763943533688, 0.9715052954300212, 0.9713304630304331, 0.9711517527380782, 0.9709690124138175, 0.9707820814265986, 0.9705907896235537, 0.9703949558981042, 0.9701943861340506, 0.9699888701768883, 0.9697781772844174, 0.9695620491957259, 0.9693401894657614, 0.9691122469398609, 0.9688777900282719, 0.9686362665330001, 0.9683869407827883, 0.9681287951266002, 0.967860375450136, 0.967579548794655, 0.9672831230040135, 0.9669662499280374, 0.9666214894034486, 0.9662373423933289, 0.9657959554212975, 0.9652695362301098, 0.9646147773345983, 0.9637642302461418, 0.9626130856959464, 0.9609992134213854, 0.9586737548241895, 0.955259558000179, 0.950196631097536, 0.9426804786409473, 0.9316157899084783, 0.9156399628637668, 0.8933136158944118, 0.8635868986778917, 0.8265310222293499, 0.7840021226665443, 0.7396062200909161, 0.697620956341404, 0.6614498365784898, 0.6326782712428192, 0.6111728491236308, 0.5957893696559433, 0.5850781029838297, 0.5777072448614764, 0.572622943737195, 0.5690581596471107, 0.5664818377356559, 0.5645374129568628, 0.5629899576238107, 0.5616864420638928, 0.5605278185338252, 0.5594501455730118, 0.5584121049878749, 0.557386846594711, 0.5563566824280489, 0.5553096141790135, 0.5542370041243098, 0.5531319135179259, 0.5519877587841588, 0.5507969929010125, 0.5495495150921426, 0.5482304436697771, 0.546816740845553, 0.5452719302837301, 0.5435377688487713, 0.5415212114963343, 0.539074417430875, 0.5359652334655042, 0.5318366076655966, 0.5261583086675271, 0.5181881882594821, 0.5069892235952571, 0.49158889755017154, 0.4713743619411931, 0.4466821294924969, 0.41921677307796, 0.39174771670698577, 0.36703207653307723, 0.3467473737549228, 0.3312062226249073, 0.31978409681344133, 0.31150745846666966, 0.30544379530646243, 0.3008571054541379, 0.29722309467908065, 0.29418990828766944, 0.2915298915563731, 0.2890992093399595, 0.28680853763935366, 0.2846032371537953, 0.2824504485065457, 0.2803308763223553, 0.27823362525438294, 0.2761529779413283, 0.2740863923002698, 0.2720332584652658, 0.26999412684870644, 0.2679702276953185, 0.2659631708473514, 0.26397475699518, 0.2620068580531431, 0.260061340584062, 0.25814001623135047, 0.25624460929231424, 0.2543767353598011, 0.2525378872863054, 0.2507294261491857, 0.2489525757656078, 0.24720841983543235, 0.24549790111144315, 0.2438218221902727, 0.24218084763407371, 0.2405755072031174, 0.2390062000218861, 0.2374731995273784, 0.23597665906523968, 0.23451661801115764, 0.23309300830418622, 0.23170566128668446, 0.2303543147531105, 0.22903862011733359, 0.22775814961548269, 0.2265124034685436, 0.22530081693572135, 0.2241227671956603, 0.22297757999749226, 0.22186453602671755, 0.22078287693119936, 0.21973181094877775, 0.2187105180682661, 0.2177181546370635, 0.21675385729708166, 0.21581674607980295, 0.2149059264115435, 0.2140204896570228, 0.21315951164153307, 0.21232204830678356, 0.21150712722385695, 0.2107137330349815, 0.2099407839134463, 0.20918709465256896, 0.20845131977376752, 0.2077318667158452, 0.20702676419846827, 0.2063334634729964, 0.20564853930414284, 0.20496724172228506, 0.20428282708164242, 0.20358556600242791, 0.2028612857277081, 0.20208925863662902, 0.2012392111575723, 0.20026723703864385, 0.1991105465003285, 0.19768145207867163, 0.19586209604583932, 0.193503540005241, 0.1904359747819881, 0.18649941063831874, 0.18160140195872237, 0.17579278064596787, 0.16932414619969388, 0.16262904560477542, 0.15621225854234844, 0.15049571401773437, 0.14571344134086028, 0.14190223391990828, 0.13896167463161388, 0.13672939563870204, 0.13503666273474046, 0.13373708652929, 0.13271561642897414, 0.13188707802450492, 0.1311907433426466, 0.13058434228613416, 0.13003889914404057, 0.12953473905332058, 0.12905857548587718, 0.12860145852476368, 0.1281573601763047, 0.12772221209764004, 0.12729325675861397, 0.1268686124179157, 0.12644698252367606, 0.12602746204790383, 0.1256094086108837, 0.12519235679366714, 0.12477596118845838, 0.12435995854986992, 0.12394414263268758, 0.12352834745228919, 0.12311243613573436, 0.1226962934835509, 0.12227982099459223, 0.12186293352610181, 0.12144555703964369, 0.12102762706831871, 0.12060908766322573, 0.12018989065839239, 0.1197699951472914, 0.11934936709979808, 0.11892797907214832, 0.1185058099781817, 0.11808284490059155, 0.11765907492783421, 0.11723449700695887, 0.11680911380568956, 0.11638293357914253, 0.11595597003793817, 0.11552824221539994, 0.11509977433216825, 0.11467059565700025, 0.11424074036284186, 0.11381024737748792, 0.11337916022832362, 0.11294752688077837, 0.11251539957024076, 0.11208283462728244, 0.11164989229613081, 0.11121663654641156, 0.11078313487826257, 0.11034945812099334, 0.1099156802255358, 0.10948187805100038, 0.1090481311457149, 0.1086145215231864, 0.10818113343348146, 0.10774805313057598, 0.10731536863627247, 0.10688316950132751, 0.10645154656447137, 0.10602059171003386, 0.1055903976249195, 0.10516105755569481, 0.10473266506656817, 0.10430531379904971, 0.10387909723408323, 0.1034541084574377, 0.10303043992913691, 0.10260818325769042, 0.10218742897986668, 0.10176826634672351, 0.10135078311657798, 0.10093506535556135, 0.10052119724636277, 0.10010926090572109, 0.09969933621117341, 0.0992915006375192, 0.09888582910340293, 0.0984823938283628, 0.09808126420063486, 0.09768250665594436, 0.09728618456745608, 0.0968923581469984, 0.09650108435761696, 0.09611241683745758, 0.0957264058349236, 0.09534309815499906, 0.09496253711657957, 0.09458476252060427, 0.09420981062873814, 0.09383771415231207, 0.09346850225119036, 0.09310220054220084, 0.09273883111673245, 0.09237841256707782, 0.09202096002107563, 0.09166648518458853, 0.09131499639133661, 0.09096649865959461, 0.09062099375525312, 0.09027848026073926, 0.08993895364929026, 0.08960240636407601, 0.08926882790166962, 0.0889382048993741, 0.08861052122592086, 0.08828575807506944, 0.08796389406165038, 0.0876449053196097, 0.08732876560163018, 0.08701544637992355, 0.08670491694780681, 0.08639714452169722, 0.08609209434318103, 0.08578972978083316, 0.08549001243148673, 0.08519290222067442, 0.08489835750198449, 0.08460633515509729, 0.08431679068228999, 0.08402967830321753, 0.08374495104779991, 0.08346256084706526, 0.08318245862181821, 0.08290459436902167, 0.08262891724579834, 0.0823553756509751, 0.0820839173041103, 0.08181448932195878, 0.0815470382923444, 0.08128151034542301, 0.08101785122233181, 0.08075600634123227, 0.0804959208607652, 0.0802375397409456, 0.07998080780153477, 0.07972566977793462, 0.07947207037465687, 0.07921995431642603, 0.07896926639698117, 0.07871995152564597, 0.07847195477174133, 0.07822522140691829, 0.07797969694549173, 0.07773532718285839, 0.07749205823208385, 0.077249836558745, 0.07700860901411487, 0.07676832286677787, 0.07652892583276222, 0.07629036610427697, 0.07605259237713982, 0.07581555387698034, 0.07557920038430273, 0.07534348225848908, 0.07510835046082362, 0.07487375657661478, 0.07463965283649042, 0.07440599213693802, 0.07417272806015973, 0.07393981489330781, 0.07370720764716446, 0.07347486207432484, 0.0732427346869403, 0.07301078277407404, 0.07277896441871859, 0.07254723851452012, 0.07231556478225129, 0.07208390378607007, 0.07185221694959827, 0.07162046657184933, 0.0713886158430313, 0.07115662886024618, 0.07092447064310362, 0.07069210714926208, 0.07045950528990721, 0.07022663294517245, 0.06999345897950349, 0.06975995325696366, 0.06952608665647368, 0.06929183108697519, 0.06905715950250359, 0.06882204591715177, 0.0685864654199031, 0.06835039418930755, 0.06811380950797226, 0.06787668977683384, 0.06763901452917617, 0.0674007644443555, 0.0671619213611899, 0.06692246829096893, 0.06668238943003563, 0.06644167017189113, 0.0662002971187694, 0.06595825809262806, 0.06571554214549911, 0.06547213956914213, 0.06522804190394076, 0.06498324194698277, 0.06473773375926302, 0.0644915126719481, 0.06424457529164149, 0.0639969195045883, 0.06374854447975885, 0.06349945067075154, 0.06324963981645652, 0.06299911494042311, 0.06274788034887588, 0.062495941627326586, 0.062243305635731536, 0.06198998050214721, 0.06173597561483972, 0.0614813016128077, 0.061225970374682165, 0.06096999500597066, 0.060713389824617936, 0.060456170344860255, 0.06019835325935513, 0.05993995641957402, 0.05968099881445084, 0.05942150054728507, 0.05916148281090397, 0.05890096786109461, 0.05863997898832286, 0.05837854048776223, 0.05811667762766228, 0.057854416616092585, 0.057591784566104316, 0.05732880945935831, 0.057065520108273975, 0.05680194611676054, 0.056538117839596794, 0.056274066340532475, 0.05600982334918907, 0.05574542121684343, 0.0554808928711827, 0.05521627177012325, 0.054951591854791156, 0.05468688750176515, 0.05442219347468673, 0.0541575448753453, 0.053892977094348454, 0.05362852576148999, 0.05336422669592979, 0.0531001158563008, 0.0528362292908592, 0.05257260308779381, 0.052309273325810486, 0.052046276025106725, 0.05178364709884964, 0.05152142230526954, 0.051259637200478214, 0.050998327092118795, 0.05073752699395058, 0.050477271581468634, 0.05021759514865394, 0.04995853156594535, 0.049700114239520116, 0.04944237607196414, 0.049185349424408414, 0.048929066080201894, 0.04867355721018543, 0.04841885333962553, 0.0481649843168602, 0.047911979283703075, 0.047659866647645634, 0.04740867405589069, 0.04715842837124433, 0.04690915564988647, 0.04666088112103463, 0.04641362916850848, 0.046167423314197154, 0.04592228620342514, 0.04567823959220662, 0.04543530433637279, 0.04519350038255097, 0.0449528467609696, 0.04471336158005768, 0.04447506202280342, 0.04423796434483153, 0.04400208387415576, 0.04376743501255824, 0.04353403123854489, 0.04330188511182248, 0.043071008279240125, 0.042841411482135994, 0.04261310456502736, 0.04238609648558072, 0.04216039532579691, 0.04193600830434512, 0.04171294178997901, 0.04149120131596685, 0.04127079159546814, 0.041051716537788566, 0.040833979265445366, 0.04061758213197585, 0.04040252674042234, 0.040188813962427586, 0.03997644395787594, 0.03976541619501685, 0.03955572947100831, 0.03934738193282001, 0.039140371098437196, 0.038934693878308266, 0.03873034659698102, 0.0385273250148746, 0.0383256243501362, 0.03812523930053362, 0.03792616406533735, 0.037728392367147895, 0.037531917473626164, 0.03733673221908757, 0.03714282902592223, 0.03695019992580642, 0.03675883658067241, 0.03656873030340632, 0.03637987207824574, 0.036192252580851014, 0.036005862198026616, 0.035820691047070516, 0.03563672899473213, 0.0354539656757612, 0.03527239051103167, 0.03509199272522693, 0.034912761364074195, 0.03473468531111788, 0.034557753304023144, 0.034381953950402576, 0.03420727574316059, 0.034033707075351104, 0.03386123625454606, 0.033689851516713, 0.0335195410396015, 0.03335029295563945, 0.03318209536434071, 0.033014936344227384, 0.03284880396427032, 0.03268368629485239, 0.03251957141826016, 0.03235644743870991, 0.03219430249191487, 0.03203312475420092, 0.03187290245117885, 0.03171362386598134, 0.03155527734707353, 0.031397851315646444, 0.031241334272602624, 0.03108571480514381, 0.030930981592970634, 0.030777123414104574, 0.030624129150342495, 0.030471987792354258, 0.03032068844443384, 0.030170220328914834, 0.03002057279026068, 0.029871735298840296, 0.02972369745440001, 0.029576448989241846, 0.029429979771118997, 0.02928427980585869, 0.029139339239722777, 0.02899514836151606, 0.0288516976044525, 0.028708977547788977, 0.028566978918236303, 0.028425692591157018, 0.02828510959155918, 0.028145221094895242, 0.02800601842767493, 0.027867493067900782, 0.027729636645334763, 0.027592440941604256, 0.027455897890155415, 0.027319999576061633, 0.0271847382356948, 0.027050106256266554, 0.026916096175246755, 0.026782700679666014, 0.026649912605308967, 0.026517724935804704, 0.026386130801620642, 0.026255123478965796, 0.026124696388609224, 0.025994843094619306, 0.025865557303029096, 0.0257368328604331, 0.025608663752520237, 0.02548104410254788, 0.025353968169761543, 0.025227430347764517, 0.025101425162841785, 0.024975947272242123, 0.024850991462422284, 0.024726552647256924, 0.02460262586621785, 0.024479206282525822, 0.024356289181278204, 0.024233869967555475, 0.024111944164509486, 0.02399050741143626, 0.02386955546183587, 0.02374908418146201, 0.023629089546363516, 0.023509567640920114, 0.023390514655874474, 0.02327192688636271, 0.023153800729944985, 0.023036132684638243, 0.022918919346952595, 0.022802157409933053, 0.022685843661208016, 0.02256997498104597, 0.022454548340421713, 0.022339560799093307, 0.022225009503690968, 0.022110891685818895, 0.021997204660171125, 0.021883945822662308, 0.021771112648574262, 0.021658702690719137, 0.02154671357761994, 0.021435143011709103, 0.02132398876754566, 0.021213248690051784, 0.021102920692769006, 0.02099300275613473, 0.020883492925779512, 0.02077438931084532, 0.020665690082325362, 0.02055739347142562, 0.020449497767948438, 0.020342001318698406, 0.020234902525910786, 0.02012819984570255, 0.020021891786546297, 0.019915976907767127, 0.019810453818062557, 0.019705321174045547, 0.01960057767881075, 0.01949622208052388, 0.019392253171034334, 0.019288669784511037, 0.019185470796101344, 0.01908265512061313, 0.018980221711219908, 0.018878169558188843, 0.01877649768763172, 0.018675205160278593, 0.018574291070274123, 0.018473754543996343, 0.018373594738897856, 0.018273810842369186, 0.0181744020706242, 0.018075367667607384, 0.01797670690392278, 0.017878419075784517, 0.017780503503988552, 0.01768295953290558, 0.017585786529494853, 0.017488983882338674, 0.017392551000697386, 0.017296487313584647, 0.017200792268862723, 0.0171054653323576, 0.017010505986993704, 0.016915913731947983, 0.016821688081823088, 0.016727828565839473, 0.01663433472704614, 0.016541206121549776, 0.01644844231776213, 0.016356042895665238, 0.016264007446094433, 0.016172335570038728, 0.016081026877958468, 0.01599008098911993, 0.015899497530946653, 0.015809276138387257, 0.015719416453299502, 0.01562991812385037, 0.01554078080393189, 0.015452004152592536, 0.015363587833483827, 0.015275531514322097, 0.015187834866365015, 0.015100497563902686, 0.01501351928376312, 0.01492689970483185, 0.014840638507585385, 0.014754735373638384, 0.014669189985304226, 0.014584002025168824, 0.014499171175677393, 0.014414697118734027, 0.014330579535313807, 0.014246818105087246, 0.014163412506056829, 0.014080362414205513, 0.013997667503156862, 0.013915327443846694, 0.013833341904206015, 0.013751710548854993, 0.013670433038807828, 0.013589509031188288, 0.013508938178955692, 0.013428720130641204, 0.013348854530094162, 0.013269341016238317, 0.013190179222837772, 0.013111368778272419, 0.013032909305322693, 0.012954800420963461, 0.012877041736166897, 0.012799632855714099, 0.012722573378015307, 0.01264586289493858, 0.012569500991646677, 0.012493487246442055, 0.012417821230619757, 0.01234250250832805, 0.012267530636436652, 0.01219290516441236, 0.012118625634201949, 0.012044691580122162, 0.011971102528756637, 0.011897857998859649, 0.011824957501266446, 0.011752400538810114, 0.01168018660624474, 0.0116083151901748, 0.011536785768990577, 0.01146559781280949, 0.011394750783423183, 0.011324244134250242, 0.011254077310294418, 0.011184249748108176, 0.011114760875761517, 0.011045610112815818, 0.010976796870302731, 0.010908320550707836, 0.010840180547959075, 0.010772376247419706, 0.010704907025885805, 0.01063777225158806, 0.010570971284197813, 0.010504503474837237, 0.010438368166093483, 0.01037256469203675, 0.010307092378242117, 0.010241950541815046, 0.010177138491420455, 0.010112655527315252, 0.010048500941384216, 0.009984674017179136, 0.009921174029961104, 0.009858000246745866, 0.009795151926352113, 0.00973262831945267, 0.009670428668628392, 0.009608552208424815, 0.009546998165411328, 0.009485765758242864, 0.009424854197724014, 0.009364262686875423, 0.009303990421002484, 0.00924403658776613, 0.009184400367255732, 0.009125080932063979, 0.009066077447363681, 0.009007389070986398, 0.00894901495350284, 0.008890954238304966, 0.008833206061689655, 0.008775769552943985, 0.008718643834431924, 0.008661828021682463, 0.008605321223479085, 0.008549122541950472, 0.008493231072662463, 0.008437645904711126, 0.008382366120816907, 0.008327390797419837, 0.008272719004775645, 0.008218349807052806, 0.008164282262430433, 0.00811051542319695, 0.008057048335849495, 0.008003880041194006, 0.007951009574445944, 0.00789843596533158, 0.007846158238189814, 0.0077941754120744635, 0.007742486500857, 0.007691090513329646, 0.007639986453308829, 0.0075891733197389075, 0.007538650106796165, 0.007488415803992999, 0.007438469396282282, 0.007388809864161837, 0.007339436183779004, 0.0072903473270352695, 0.007241542261690876, 0.007193019951469415, 0.007144779356162376, 0.007096819431733575, 0.00704913913042346, 0.007001737400853255, 0.0069546131881289145, 0.006907765433944836, 0.006861193076687334, 0.006814895051537805, 0.006768870290575616, 0.006723117722880622, 0.006677636274635312, 0.0066324248692265905, 0.006587482427347113, 0.006542807867096188, 0.006498400104080216, 0.0064542580515126406, 0.006410380620313374, 0.006366766719207707, 0.006323415254824655, 0.006280325131794743, 0.006237495252847176, 0.006194924518906431, 0.006152611829188189, 0.006110556081294648, 0.006068756171309149, 0.0060272109938901575, 0.005985919442364507, 0.005944880408819991, 0.00590409278419718, 0.005863555458380537, 0.00582326732028878, 0.005783227257964476, 0.0057434341586628706, 0.005703886908939937, 0.005664584394739628, 0.005625525501480327, 0.0055867091141404805, 0.005548134117343424, 0.005509799395441358, 0.00547170383259852, 0.005433846312873453, 0.00539622572030049, 0.005358840938970324, 0.005321690853109752, 0.005284774347160509, 0.005248090305857275, 0.0052116376143047476, 0.0051754151580538765, 0.005139421823177164, 0.005103656496343119, 0.0050681180648897714, 0.005032805416897315, 0.0049977174412598295, 0.004962853027756118, 0.004928211067119617, 0.004893790451107412, 0.0048595900725683415, 0.004825608825510192, 0.004791845605165971, 0.004758299308059288, 0.004724968832068804, 0.004691853076491798, 0.0046589509421067895, 0.004626261331235276, 0.004593783147802555, 0.00456151529739764, 0.0045294566873322695, 0.004497606226699017, 0.00446596282642849, 0.004434525399345655, 0.004403292860225219, 0.0043722641258461805, 0.004341438115045427, 0.0043108137487705015, 0.004280389950131434, 0.004250165644451737, 0.004220139759318489, 0.004190311224631572, 0.004160678972652024, 0.00413124193804953, 0.004101999057949057, 0.004072949271976635, 0.004044091522304277, 0.0040154247536940664, 0.003986947913541394, 0.0039586599519173616, 0.00393055982161036, 0.0039026464781668126, 0.003874918879931107, 0.0038473759880847122, 0.003820016766684477, 0.0037928401827001515, 0.003765845206051068, 0.003739030809642085, 0.003712395969398699, 0.0036859396643014125, 0.0036596608764193055, 0.0036335585909428587, 0.003607631796216001, 0.003581879483767424, 0.0035563006483411274, 0.003530894287926245, 0.0035056594037861186, 0.0034805950004866684, 0.0034557000859240143, 0.003430973671351413, 0.003406414771405468, 0.0033820224041316528, 0.0033577955910091294, 0.0033337333569748986, 0.003309834730447254, 0.0032860987433485757, 0.0032625244311274507, 0.0032391108327801525, 0.003215856990871442, 0.0031927619515547574, 0.0031698247645917375, 0.0031470444833711425, 0.0031244201649271303, 0.003101950869956935, 0.003079635662837918, 0.0030574736116440473, 0.003035463788161748, 0.003013605267905197, 0.002991897130131014, 0.0029703384578524004, 0.0029489283378526937, 0.00292766586069838, 0.002906550120751542, 0.002885580216181775, 0.002864755248977548, 0.002844074324957059, 0.002823536553778541, 0.002803141048950074, 0.002782886927838864, 0.0027627733116800442, 0.002742799325584968, 0.0027229640985490045, 0.0027032667634588714, 0.002683706457099474, 0.002664282320160293, 0.0026449934972412876, 0.0026258391368583723, 0.0026068183914484183, 0.0025879304173738295, 0.0025691743749266787, 0.0025505494283324134, 0.0025320547457531343, 0.002513689499290478, 0.002495452864988058, 0.0024773440228335352, 0.0024593621567602702, 0.002441506454648591, 0.002423776108326677, 0.0024061703135710736, 0.002388688270106813, 0.0023713291816071925, 0.002354092255693176, 0.0023369767039324568, 0.002319981741838154, 0.002303106588867191, 0.0022863504684183062, 0.0022697126078297697, 0.0022531922383767448, 0.002236788595268351, 0.0022205009176443995, 0.002204328448571837, 0.002188270435040863, 0.002172326127960786, 0.0021564947821555523, 0.002140775656359015, 0.0021251680132099073, 0.002109671119246554, 0.0020942842449013007, 0.002079006664494681, 0.002063837656229344, 0.0020487765021836865, 0.0020338224883052875, 0.0020189749044040436, 0.0020042330441451222, 0.0019895962050416223, 0.0019750636884470606, 0.0019606347995475863, 0.0019463088473540132, 0.0019320851446936033, 0.001917963008201675, 0.0019039417583129603, 0.0018900207192528184, 0.0018761992190281867, 0.0018624765894183996, 0.0018488521659657696, 0.001835325287966024, 0.0018218952984585246, 0.0018085615442163532, 0.0017953233757361754, 0.0017821801472279967, 0.001769131216604687, 0.0017561759454714195, 0.001743313699114883, 0.001730543846492389, 0.0017178657602208332, 0.0017052788165654665, 0.0016927823954285875, 0.0016803758803380444, 0.0016680586584356468, 0.0016558301204654129, 0.0016436896607617225, 0.0016316366772373167, 0.001619670571371214, 0.0016077907481964705, 0.0015959966162878724, 0.0015842875877494739, 0.001572663078202074, 0.0015611225067705533, 0.0015496652960711441, 0.001538290872198571, 0.0015269986647131388, 0.0015157881066276864, 0.0015046586343944973, 0.0014936096878920843, 0.0014826407104119384, 0.0014717511486451512, 0.0014609404526690095, 0.0014502080759334754, 0.0014395534752476321, 0.0014289761107660324, 0.0014184754459750123, 0.001408050947678913, 0.0013977020859862726, 0.001387428334295934, 0.0013772291692831244, 0.001367104070885459, 0.0013570525222889203, 0.0013470740099137605, 0.001337168023400398, 0.0013273340555952254, 0.0013175716025364275, 0.00130788016343971, 0.0012982592406840443, 0.0012887083397973304, 0.0012792269694420703, 0.0012698146414009777, 0.0012604708705625908, 0.0012511951749068283, 0.0012419870754905586, 0.001232846096433105, 0.0012237717649017804, 0.0012147636110973522, 0.001205821168239541, 0.0011969439725524648, 0.0011881315632501013, 0.001179383482521715, 0.0011706992755173005, 0.001162078490332993, 0.001153520677996498, 0.001145025392452494, 0.0011365921905480566, 0.0011282206320180563, 0.0011199102794705843, 0.0011116606983723539, 0.0011034714570341323, 0.0010953421265961494, 0.0010872722810135425, 0.0010792614970417818, 0.0010713093542221303, 0.0010634154348670855, 0.0010555793240458718, 0.0010478006095699013, 0.0010400788819782912, 0.0010324137345233612, 0.0010248047631561778, 0.0010172515665120927, 0.00100975374589632, 0.0010023109052695136, 0.0009949226512333906, 0.0009875885930163489, 0.0009803083424591364, 0.0009730815140005205, 0.0009659077246630037, 0.0009587865940385463, 0.0009517177442743383, 0.0009447008000585744, 0.0009377353886062853, 0.0009308211396451744, 0.0009239576854015064, 0.0009171446605860103, 0.0009103817023798337, 0.0009036684504205057, 0.0008970045467879691, 0.0008903896359906045, 0.000883823364951336, 0.0008773053829937324, 0.000870835341828179, 0.0008644128955380617, 0.0008580377005660106, 0.0008517094157001644, 0.0008454277020604924, 0.0008391922230851423, 0.0008330026445168404, 0.0008268586343893248, 0.00082075986301383, 0.000814706002965604, 0.0008086967290704822, 0.0008027317183914872, 0.0007968106502154989, 0.0007909332060399375, 0.0007850990695595251, 0.000779307926653065, 0.0007735594653702892, 0.0007678533759187362, 0.0007621893506506916, 0.0007565670840501578, 0.0007509862727198959, 0.0007454466153684885, 0.0007399478127974794, 0.0007344895678885355, 0.0007290715855906829, 0.0007236935729075747, 0.0007183552388848199, 0.0007130562945973553, 0.0007077964531368772, 0.0007025754295993125, 0.000697392941072355, 0.000692248706623038, 0.0006871424472853771, 0.0006820738860480432, 0.0006770427478421126, 0.0006720487595288454, 0.0006670916498875336, 0.0006621711496034007, 0.0006572869912555412, 0.0006524389093049338, 0.0006476266400824876, 0.0006428499217771592, 0.0006381084944241109, 0.0006334020998929345, 0.0006287304818759147, 0.0006240933858763649, 0.0006194905591969983, 0.0006149217509283718, 0.0006103867119373664, 0.0006058851948557401, 0.00060141695406872, 0.0005969817457036626, 0.0005925793276187556, 0.0005882094593917891, 0.0005838719023089673, 0.0005795664193537888, 0.0005752927751959702, 0.0005710507361804352, 0.000566840070316349, 0.0005626605472662184, 0.0005585119383350351, 0.0005543940164594887, 0.0005503065561972162, 0.0005462493337161296, 0.0005422221267837755, 0.0005382247147567697, 0.0005342568785702703, 0.0005303184007275214, 0.000526409065289436, 0.0005225286578642497, 0.0005186769655972165, 0.0005148537771603683, 0.0005110588827423229, 0.0005072920740381531, 0.0005035531442393029, 0.0004998418880235677, 0.0004961581015451198, 0.0004925015824245962, 0.0004888721297392341, 0.00048526954401306857, 0.0004816936272071734, 0.00047814418270997135, 0.00047462101532758024, 0.00047112393127423345, 0.0004676527381627308, 0.00046420724499497007, 0.00046078726215250407, 0.00045739260138717686, 0.0004540230758117925, 0.00045067849989085303, 0.0004473586894313382, 0.00044406346157354574, 0.0004407926347819789, 0.00043754602883629265, 0.0004343234648222849, 0.0004311247651229492, 0.00042794975340957117, 0.000424798254632884, 0.0004216700950142692, 0.0004185651020370184, 0.0004154831044376341, 0.00041242393219719723, 0.00040938741653277083, 0.00040637338988886796, 0.0004033816859289598, 0.00040041213952704535, 0.00039746458675925966, 0.00039453886489554586, 0.00039163481239136487, 0.00038875226887946597, 0.0003858910751616991, 0.00038305107320088364, 0.0003802321061127204, 0.0003774340181577601, 0.0003746566547334139, 0.0003718998623660197, 0.0003691634887029516, 0.0003664473825047834, 0.00036375139363749396, 0.0003610753730647304, 0.0003584191728401082, 0.0003557826460995698, 0.00035316564705378193, 0.0003505680309805885, 0.0003479896542175034, 0.00034543037415425785, 0.0003428900492253868, 0.00034036853890287124, 0.0003378657036888157, 0.0003353814051081861, 0.0003329155057015782, 0.000330467869018047, 0.00032803835960796933, 0.0003256268430159616, 0.00032323318577383504, 0.00032085725539360375, 0.0003184989203605294, 0.00031615805012621967, 0.0003138345151017613, 0.00031152818665090794, 0.00030923893708330156, 0.0003069666396477473, 0.00030471116852552474, 0.0003024723988237474, 0.0003002502065687615, 0.0002980444686995926, 0.00029585506306142916, 0.0002936818683991551, 0.000291524764350918, 0.00028938363144174713, 0.00028725835107720494, 0.0002851488055370891, 0.0002830548779691671, 0.00028097645238296155, 0.00027891341364356763, 0.00027686564746551924, 0.0002748330404066889, 0.0002728154798622355, 0.00027081285405858367, 0.000268825052047453, 0.00026685196369991725, 0.00026489347970051205, 0.00026294949154137526, 0.00026101989151643004, 0.0002591045727156075, 0.0002572034290191044, 0.0002553163550916844, 0.0002534432463770125, 0.00025158399909203387, 0.00024973851022138196, 0.000247906677511836, 0.0002460883994668027, 0.0002442835753408484, 0.00024249210513425644, 0.00024071388958763162, 0.0002389488301765338, 0.00023719682910615286, 0.00023545778930601663, 0.0002337316144247379, 0.0002320182088247939, 0.0002303174775773458, 0.00022862932645708852, 0.00022695366193714107, 0.00022529039118396722, 0.00022363942205233528, 0.00022200066308030792, 0.0002203740234842722, 0.00021875941315399724, 0.00021715674264773268, 0.00021556592318733422, 0.00021398686665342981, 0.00021241948558061222, 0.0002108636931526717, 0.00020931940319785536, 0.0002077865301841648, 0.00020626498921468223, 0.00020475469602293243, 0.00020325556696827344, 0.00020176751903132334, 0.00020029046980941505, 0.00019882433751208613, 0.0001973690409565966, 0.00019592449956348248, 0.00019449063335213513, 0.00019306736293641703, 0.00019165460952030297, 0.000190252294893557, 0.00018886034142743415, 0.0001874786720704184, 0.00018610721034398453, 0.0001847458803383951, 0.00018339460670852242, 0.0001820533146697046, 0.00018072192999362533, 0.00017940037900422912, 0.00017808858857365858, 0.00017678648611822704, 0.00017549399959441325, 0.00017421105749489092, 0.00017293758884457964, 0.0001716735231967301, 0.00017041879062903209, 0.0001691733217397537, 0.00016793704764390467, 0.00016670989996943095, 0.00016549181085343174, 0.0001642827129384081, 0.00016308253936853383, 0.000161891223785957, 0.0001607087003271242, 0.00015953490361913432, 0.00015836976877611536, 0.00015721323139562975, 0.00015606522755510306, 0.00015492569380828056, 0.00015379456718170607, 0.0001526717851712304, 0.0001515572857385396, 0.00015045100730771326, 0.0001493528887618028, 0.00014826286943943838, 0.0001471808891314569, 0.00014610688807755687, 0.00014504080696297494, 0.000143982586915189, 0.00014293216950064173, 0.00014188949672149154, 0.000140854511012383, 0.0001398271552372442, 0.0001388073726861042, 0.0001377951070719359, 0.0001367903025275194, 0.00013579290360233044, 0.0001348028552594487, 0.00013382010287249136, 0.00013284459222256595, 0.00013187626949524785, 0.00013091508127757723, 0.0001299609745550806, 0.00012901389670881016, 0.00012807379551240967, 0.00012714061912919556, 0.00012621431610926575, 0.00012529483538662286, 0.00012438212627632452, 0.00012347613847164948, 0.0001225768220412876, 0.00012168412742654808, 0.00012079800543859001, 0.00011991840725567081, 0.00011904528442041728, 0.00011817858883711417, 0.0001173182727690143, 0.00011646428883566699, 0.00011561659001026723, 0.00011477512961702269, 0.0001139398613285419, 0.00011311073916323928, 0.00011228771748276153, 0.00011147075098943027, 0.00011065979472370618, 0.00010985480406166845, 0.00010905573471251676, 0.00010826254271608682, 0.00010747518444038866, 0.00010669361657915938, 0.0001059177961494363, 0.00010514768048914614, 0.00010438322725471352, 0.00010362439441868545, 0.00010287114026737425, 0.00010212342339851794, 0.0001013812027189563, 0.0001006444374423266, 9.991308708677332e-05, 9.918711147267739e-05, 9.84664707203998e-05, 9.775112524804405e-05, 9.704103576923273e-05, 9.63361632909031e-05, 9.563646911111594e-05, 9.494191481688378e-05, 9.42524622820116e-05, 9.356807366495728e-05, 9.288871140670401e-05, 9.22143382286517e-05, 9.154491713052153e-05, 9.08804113882776e-05, 9.022078455206248e-05, 8.956600044414972e-05, 8.891602315690962e-05, 8.827081705079182e-05, 8.7630346752321e-05, 8.69945771521094e-05, 8.636347340288177e-05, 8.57370009175173e-05, 8.511512536710395e-05, 8.449781267900879e-05, 8.388502903496122e-05, 8.327674086915184e-05, 8.267291486634404e-05, 8.20735179600007e-05, 8.147851733042368e-05, 8.088788040290841e-05, 8.030157484591062e-05, 7.971956856922828e-05, 7.91418297221954e-05, 7.856832669189109e-05, 7.799902810135961e-05, 7.743390280784616e-05, 7.687291990104327e-05, 7.631604870135278e-05, 7.576325875815779e-05, 7.521451984811085e-05, 7.466980197343127e-05, 7.412907536021856e-05, 7.359231045677507e-05, 7.305947793194418e-05, 7.253054867345846e-05, 7.200549378630171e-05, 7.148428459108192e-05, 7.096689262241774e-05, 7.04532896273352e-05, 6.994344756367838e-05, 6.943733859853001e-05, 6.893493510664544e-05, 6.843620966889658e-05, 6.794113507072974e-05, 6.744968430063197e-05, 6.696183054861194e-05, 6.647754720468953e-05, 6.599680785739874e-05, 6.551958629229986e-05, 6.504585649050459e-05, 6.457559262721062e-05, 6.410876907024823e-05, 6.36453603786369e-05, 6.318534130115349e-05, 6.272868677491018e-05, 6.227537192394413e-05, 6.182537205781647e-05, 6.137866267022297e-05, 6.093521943761382e-05, 6.0495018217825004e-05, 6.005803504871851e-05, 5.962424614683434e-05, 5.919362790605078e-05, 5.876615689625641e-05, 5.834180986203047e-05, 5.7920563721334594e-05, 5.7502395564212746e-05, 5.708728265150251e-05, 5.667520241355454e-05, 5.6266132448962754e-05, 5.586005052330311e-05, 5.545693456788267e-05, 5.505676267849683e-05, 5.465951311419773e-05, 5.4265164296069476e-05, 5.387369480601497e-05 ], + "y": [ 0.001, 0.002, 0.003, 0.004, 0.005, 0.006, 0.007, 0.008, 0.009000000000000001, 0.010000000000000002, 0.011, 0.012, 0.013000000000000001, 0.014000000000000002, 0.015, 0.016, 0.017, 0.018000000000000002, 0.019000000000000003, 0.02, 0.021, 0.022000000000000002, 0.023, 0.024, 0.025, 0.026000000000000002, 0.027000000000000003, 0.028, 0.029, 0.030000000000000002, 0.031, 0.032, 0.033, 0.034, 0.035, 0.036000000000000004, 0.037000000000000005, 0.038, 0.039, 0.04, 0.041, 0.042, 0.043000000000000003, 0.044000000000000004, 0.045, 0.046, 0.047, 0.048, 0.049, 0.05, 0.051000000000000004, 0.052000000000000005, 0.053000000000000005, 0.054, 0.055, 0.056, 0.057, 0.058, 0.059000000000000004, 0.060000000000000005, 0.061, 0.062, 0.063, 0.064, 0.065, 0.066, 0.067, 0.068, 0.069, 0.07, 0.07100000000000001, 0.07200000000000001, 0.07300000000000001, 0.074, 0.075, 0.076, 0.077, 0.078, 0.079, 0.08, 0.081, 0.082, 0.083, 0.084, 0.085, 0.08600000000000001, 0.08700000000000001, 0.08800000000000001, 0.089, 0.09, 0.091, 0.092, 0.093, 0.094, 0.095, 0.096, 0.097, 0.098, 0.099, 0.1, 0.101, 0.10200000000000001, 0.10300000000000001, 0.10400000000000001, 0.10500000000000001, 0.106, 0.107, 0.108, 0.109, 0.11, 0.111, 0.112, 0.113, 0.114, 0.115, 0.116, 0.117, 0.11800000000000001, 0.11900000000000001, 0.12000000000000001, 0.121, 0.122, 0.123, 0.124, 0.125, 0.126, 0.127, 0.128, 0.129, 0.13, 0.131, 0.132, 0.133, 0.134, 0.135, 0.136, 0.137, 0.138, 0.139, 0.14, 0.14100000000000001, 0.14200000000000002, 0.14300000000000002, 0.14400000000000002, 0.14500000000000002, 0.146, 0.147, 0.148, 0.149, 0.15, 0.151, 0.152, 0.153, 0.154, 0.155, 0.156, 0.157, 0.158, 0.159, 0.16, 0.161, 0.162, 0.163, 0.164, 0.165, 0.166, 0.167, 0.168, 0.169, 0.17, 0.171, 0.17200000000000001, 0.17300000000000001, 0.17400000000000002, 0.17500000000000002, 0.17600000000000002, 0.177, 0.178, 0.179, 0.18, 0.181, 0.182, 0.183, 0.184, 0.185, 0.186, 0.187, 0.188, 0.189, 0.19, 0.191, 0.192, 0.193, 0.194, 0.195, 0.196, 0.197, 0.198, 0.199, 0.2, 0.201, 0.202, 0.203, 0.20400000000000001, 0.20500000000000002, 0.20600000000000002, 0.20700000000000002, 0.20800000000000002, 0.20900000000000002, 0.21, 0.211, 0.212, 0.213, 0.214, 0.215, 0.216, 0.217, 0.218, 0.219, 0.22, 0.221, 0.222, 0.223, 0.224, 0.225, 0.226, 0.227, 0.228, 0.229, 0.23, 0.231, 0.232, 0.233, 0.234, 0.23500000000000001, 0.23600000000000002, 0.23700000000000002, 0.23800000000000002, 0.23900000000000002, 0.24000000000000002, 0.241, 0.242, 0.243, 0.244, 0.245, 0.246, 0.247, 0.248, 0.249, 0.25, 0.251, 0.252, 0.253, 0.254, 0.255, 0.256, 0.257, 0.258, 0.259, 0.26, 0.261, 0.262, 0.263, 0.264, 0.265, 0.266, 0.267, 0.268, 0.269, 0.27, 0.271, 0.272, 0.273, 0.274, 0.275, 0.276, 0.277, 0.278, 0.279, 0.28, 0.281, 0.28200000000000003, 0.28300000000000003, 0.28400000000000003, 0.28500000000000003, 0.28600000000000003, 0.28700000000000003, 0.28800000000000003, 0.28900000000000003, 0.29, 0.291, 0.292, 0.293, 0.294, 0.295, 0.296, 0.297, 0.298, 0.299, 0.3, 0.301, 0.302, 0.303, 0.304, 0.305, 0.306, 0.307, 0.308, 0.309, 0.31, 0.311, 0.312, 0.313, 0.314, 0.315, 0.316, 0.317, 0.318, 0.319, 0.32, 0.321, 0.322, 0.323, 0.324, 0.325, 0.326, 0.327, 0.328, 0.329, 0.33, 0.331, 0.332, 0.333, 0.334, 0.335, 0.336, 0.337, 0.338, 0.339, 0.34, 0.341, 0.342, 0.343, 0.34400000000000003, 0.34500000000000003, 0.34600000000000003, 0.34700000000000003, 0.34800000000000003, 0.34900000000000003, 0.35000000000000003, 0.35100000000000003, 0.35200000000000004, 0.353, 0.354, 0.355, 0.356, 0.357, 0.358, 0.359, 0.36, 0.361, 0.362, 0.363, 0.364, 0.365, 0.366, 0.367, 0.368, 0.369, 0.37, 0.371, 0.372, 0.373, 0.374, 0.375, 0.376, 0.377, 0.378, 0.379, 0.38, 0.381, 0.382, 0.383, 0.384, 0.385, 0.386, 0.387, 0.388, 0.389, 0.39, 0.391, 0.392, 0.393, 0.394, 0.395, 0.396, 0.397, 0.398, 0.399, 0.4, 0.401, 0.402, 0.403, 0.404, 0.405, 0.406, 0.40700000000000003, 0.40800000000000003, 0.40900000000000003, 0.41000000000000003, 0.41100000000000003, 0.41200000000000003, 0.41300000000000003, 0.41400000000000003, 0.41500000000000004, 0.41600000000000004, 0.41700000000000004, 0.418, 0.419, 0.42, 0.421, 0.422, 0.423, 0.424, 0.425, 0.426, 0.427, 0.428, 0.429, 0.43, 0.431, 0.432, 0.433, 0.434, 0.435, 0.436, 0.437, 0.438, 0.439, 0.44, 0.441, 0.442, 0.443, 0.444, 0.445, 0.446, 0.447, 0.448, 0.449, 0.45, 0.451, 0.452, 0.453, 0.454, 0.455, 0.456, 0.457, 0.458, 0.459, 0.46, 0.461, 0.462, 0.463, 0.464, 0.465, 0.466, 0.467, 0.468, 0.46900000000000003, 0.47000000000000003, 0.47100000000000003, 0.47200000000000003, 0.47300000000000003, 0.47400000000000003, 0.47500000000000003, 0.47600000000000003, 0.47700000000000004, 0.47800000000000004, 0.47900000000000004, 0.48000000000000004, 0.481, 0.482, 0.483, 0.484, 0.485, 0.486, 0.487, 0.488, 0.489, 0.49, 0.491, 0.492, 0.493, 0.494, 0.495, 0.496, 0.497, 0.498, 0.499, 0.5, 0.501, 0.502, 0.503, 0.504, 0.505, 0.506, 0.507, 0.508, 0.509, 0.51, 0.511, 0.512, 0.513, 0.514, 0.515, 0.516, 0.517, 0.518, 0.519, 0.52, 0.521, 0.522, 0.523, 0.524, 0.525, 0.526, 0.527, 0.528, 0.529, 0.53, 0.531, 0.532, 0.533, 0.534, 0.535, 0.536, 0.537, 0.538, 0.539, 0.54, 0.541, 0.542, 0.543, 0.544, 0.545, 0.546, 0.547, 0.548, 0.549, 0.55, 0.551, 0.552, 0.553, 0.554, 0.555, 0.556, 0.557, 0.558, 0.559, 0.56, 0.561, 0.562, 0.5630000000000001, 0.5640000000000001, 0.5650000000000001, 0.5660000000000001, 0.5670000000000001, 0.5680000000000001, 0.5690000000000001, 0.5700000000000001, 0.5710000000000001, 0.5720000000000001, 0.5730000000000001, 0.5740000000000001, 0.5750000000000001, 0.5760000000000001, 0.5770000000000001, 0.578, 0.579, 0.58, 0.581, 0.582, 0.583, 0.584, 0.585, 0.586, 0.587, 0.588, 0.589, 0.59, 0.591, 0.592, 0.593, 0.594, 0.595, 0.596, 0.597, 0.598, 0.599, 0.6, 0.601, 0.602, 0.603, 0.604, 0.605, 0.606, 0.607, 0.608, 0.609, 0.61, 0.611, 0.612, 0.613, 0.614, 0.615, 0.616, 0.617, 0.618, 0.619, 0.62, 0.621, 0.622, 0.623, 0.624, 0.625, 0.626, 0.627, 0.628, 0.629, 0.63, 0.631, 0.632, 0.633, 0.634, 0.635, 0.636, 0.637, 0.638, 0.639, 0.64, 0.641, 0.642, 0.643, 0.644, 0.645, 0.646, 0.647, 0.648, 0.649, 0.65, 0.651, 0.652, 0.653, 0.654, 0.655, 0.656, 0.657, 0.658, 0.659, 0.66, 0.661, 0.662, 0.663, 0.664, 0.665, 0.666, 0.667, 0.668, 0.669, 0.67, 0.671, 0.672, 0.673, 0.674, 0.675, 0.676, 0.677, 0.678, 0.679, 0.68, 0.681, 0.682, 0.683, 0.684, 0.685, 0.686, 0.687, 0.6880000000000001, 0.6890000000000001, 0.6900000000000001, 0.6910000000000001, 0.6920000000000001, 0.6930000000000001, 0.6940000000000001, 0.6950000000000001, 0.6960000000000001, 0.6970000000000001, 0.6980000000000001, 0.6990000000000001, 0.7000000000000001, 0.7010000000000001, 0.7020000000000001, 0.7030000000000001, 0.7040000000000001, 0.705, 0.706, 0.707, 0.708, 0.709, 0.71, 0.711, 0.712, 0.713, 0.714, 0.715, 0.716, 0.717, 0.718, 0.719, 0.72, 0.721, 0.722, 0.723, 0.724, 0.725, 0.726, 0.727, 0.728, 0.729, 0.73, 0.731, 0.732, 0.733, 0.734, 0.735, 0.736, 0.737, 0.738, 0.739, 0.74, 0.741, 0.742, 0.743, 0.744, 0.745, 0.746, 0.747, 0.748, 0.749, 0.75, 0.751, 0.752, 0.753, 0.754, 0.755, 0.756, 0.757, 0.758, 0.759, 0.76, 0.761, 0.762, 0.763, 0.764, 0.765, 0.766, 0.767, 0.768, 0.769, 0.77, 0.771, 0.772, 0.773, 0.774, 0.775, 0.776, 0.777, 0.778, 0.779, 0.78, 0.781, 0.782, 0.783, 0.784, 0.785, 0.786, 0.787, 0.788, 0.789, 0.79, 0.791, 0.792, 0.793, 0.794, 0.795, 0.796, 0.797, 0.798, 0.799, 0.8, 0.801, 0.802, 0.803, 0.804, 0.805, 0.806, 0.807, 0.808, 0.809, 0.81, 0.811, 0.812, 0.8130000000000001, 0.8140000000000001, 0.8150000000000001, 0.8160000000000001, 0.8170000000000001, 0.8180000000000001, 0.8190000000000001, 0.8200000000000001, 0.8210000000000001, 0.8220000000000001, 0.8230000000000001, 0.8240000000000001, 0.8250000000000001, 0.8260000000000001, 0.8270000000000001, 0.8280000000000001, 0.8290000000000001, 0.8300000000000001, 0.8310000000000001, 0.8320000000000001, 0.8330000000000001, 0.834, 0.835, 0.836, 0.837, 0.838, 0.839, 0.84, 0.841, 0.842, 0.843, 0.844, 0.845, 0.846, 0.847, 0.848, 0.849, 0.85, 0.851, 0.852, 0.853, 0.854, 0.855, 0.856, 0.857, 0.858, 0.859, 0.86, 0.861, 0.862, 0.863, 0.864, 0.865, 0.866, 0.867, 0.868, 0.869, 0.87, 0.871, 0.872, 0.873, 0.874, 0.875, 0.876, 0.877, 0.878, 0.879, 0.88, 0.881, 0.882, 0.883, 0.884, 0.885, 0.886, 0.887, 0.888, 0.889, 0.89, 0.891, 0.892, 0.893, 0.894, 0.895, 0.896, 0.897, 0.898, 0.899, 0.9, 0.901, 0.902, 0.903, 0.904, 0.905, 0.906, 0.907, 0.908, 0.909, 0.91, 0.911, 0.912, 0.913, 0.914, 0.915, 0.916, 0.917, 0.918, 0.919, 0.92, 0.921, 0.922, 0.923, 0.924, 0.925, 0.926, 0.927, 0.928, 0.929, 0.93, 0.931, 0.932, 0.933, 0.934, 0.935, 0.936, 0.937, 0.9380000000000001, 0.9390000000000001, 0.9400000000000001, 0.9410000000000001, 0.9420000000000001, 0.9430000000000001, 0.9440000000000001, 0.9450000000000001, 0.9460000000000001, 0.9470000000000001, 0.9480000000000001, 0.9490000000000001, 0.9500000000000001, 0.9510000000000001, 0.9520000000000001, 0.9530000000000001, 0.9540000000000001, 0.9550000000000001, 0.9560000000000001, 0.9570000000000001, 0.9580000000000001, 0.9590000000000001, 0.9600000000000001, 0.961, 0.962, 0.963, 0.964, 0.965, 0.966, 0.967, 0.968, 0.969, 0.97, 0.971, 0.972, 0.973, 0.974, 0.975, 0.976, 0.977, 0.978, 0.979, 0.98, 0.981, 0.982, 0.983, 0.984, 0.985, 0.986, 0.987, 0.988, 0.989, 0.99, 0.991, 0.992, 0.993, 0.994, 0.995, 0.996, 0.997, 0.998, 0.999, 1.0, 1.001, 1.002, 1.003, 1.004, 1.005, 1.006, 1.007, 1.008, 1.009, 1.01, 1.011, 1.012, 1.013, 1.014, 1.015, 1.016, 1.017, 1.018, 1.019, 1.02, 1.021, 1.022, 1.023, 1.024, 1.025, 1.0259999999999998, 1.027, 1.0279999999999998, 1.029, 1.0299999999999998, 1.031, 1.0319999999999998, 1.033, 1.0339999999999998, 1.035, 1.0359999999999998, 1.037, 1.0379999999999998, 1.039, 1.0399999999999998, 1.041, 1.0419999999999998, 1.043, 1.0439999999999998, 1.045, 1.0459999999999998, 1.047, 1.0479999999999998, 1.049, 1.0499999999999998, 1.051, 1.0519999999999998, 1.053, 1.0539999999999998, 1.055, 1.0559999999999998, 1.057, 1.0579999999999998, 1.059, 1.0599999999999998, 1.061, 1.0619999999999998, 1.063, 1.0639999999999998, 1.065, 1.0659999999999998, 1.067, 1.0679999999999998, 1.069, 1.0699999999999998, 1.071, 1.0719999999999998, 1.073, 1.0739999999999998, 1.075, 1.0759999999999998, 1.077, 1.0779999999999998, 1.079, 1.0799999999999998, 1.081, 1.0819999999999999, 1.083, 1.0839999999999999, 1.085, 1.0859999999999999, 1.087, 1.0879999999999999, 1.089, 1.0899999999999999, 1.091, 1.0919999999999999, 1.093, 1.0939999999999999, 1.095, 1.0959999999999999, 1.097, 1.0979999999999999, 1.099, 1.0999999999999999, 1.101, 1.1019999999999999, 1.103, 1.1039999999999999, 1.105, 1.1059999999999999, 1.107, 1.1079999999999999, 1.109, 1.1099999999999999, 1.111, 1.1119999999999999, 1.113, 1.1139999999999999, 1.115, 1.1159999999999999, 1.117, 1.1179999999999999, 1.119, 1.1199999999999999, 1.121, 1.1219999999999999, 1.123, 1.1239999999999999, 1.125, 1.126, 1.127, 1.128, 1.129, 1.13, 1.131, 1.132, 1.133, 1.134, 1.135, 1.136, 1.137, 1.138, 1.139, 1.14, 1.141, 1.142, 1.143, 1.144, 1.145, 1.146, 1.147, 1.148, 1.149, 1.15, 1.151, 1.152, 1.153, 1.154, 1.1549999999999998, 1.156, 1.1569999999999998, 1.158, 1.1589999999999998, 1.16, 1.1609999999999998, 1.162, 1.1629999999999998, 1.164, 1.1649999999999998, 1.166, 1.1669999999999998, 1.168, 1.1689999999999998, 1.17, 1.1709999999999998, 1.172, 1.1729999999999998, 1.174, 1.1749999999999998, 1.176, 1.1769999999999998, 1.178, 1.1789999999999998, 1.18, 1.1809999999999998, 1.182, 1.1829999999999998, 1.184, 1.1849999999999998, 1.186, 1.1869999999999998, 1.188, 1.1889999999999998, 1.19, 1.1909999999999998, 1.192, 1.1929999999999998, 1.194, 1.1949999999999998, 1.196, 1.1969999999999998, 1.198, 1.1989999999999998, 1.2, 1.2009999999999998, 1.202, 1.2029999999999998, 1.204, 1.2049999999999998, 1.206, 1.2069999999999999, 1.208, 1.2089999999999999, 1.21, 1.2109999999999999, 1.212, 1.2129999999999999, 1.214, 1.2149999999999999, 1.216, 1.2169999999999999, 1.218, 1.2189999999999999, 1.22, 1.2209999999999999, 1.222, 1.2229999999999999, 1.224, 1.2249999999999999, 1.226, 1.2269999999999999, 1.228, 1.2289999999999999, 1.23, 1.2309999999999999, 1.232, 1.2329999999999999, 1.234, 1.2349999999999999, 1.236, 1.2369999999999999, 1.238, 1.2389999999999999, 1.24, 1.2409999999999999, 1.242, 1.2429999999999999, 1.244, 1.2449999999999999, 1.246, 1.2469999999999999, 1.248, 1.2489999999999999, 1.25, 1.251, 1.252, 1.253, 1.254, 1.255, 1.256, 1.257, 1.258, 1.259, 1.26, 1.261, 1.262, 1.263, 1.264, 1.265, 1.266, 1.267, 1.268, 1.269, 1.27, 1.271, 1.272, 1.273, 1.274, 1.275, 1.276, 1.277, 1.278, 1.279, 1.28, 1.281, 1.2819999999999998, 1.283, 1.2839999999999998, 1.285, 1.2859999999999998, 1.287, 1.2879999999999998, 1.289, 1.2899999999999998, 1.291, 1.2919999999999998, 1.293, 1.2939999999999998, 1.295, 1.2959999999999998, 1.297, 1.2979999999999998, 1.299, 1.2999999999999998, 1.301, 1.3019999999999998, 1.303, 1.3039999999999998, 1.305, 1.3059999999999998, 1.307, 1.3079999999999998, 1.309, 1.3099999999999998, 1.311, 1.3119999999999998, 1.313, 1.3139999999999998, 1.315, 1.3159999999999998, 1.317, 1.3179999999999998, 1.319, 1.3199999999999998, 1.321, 1.3219999999999998, 1.323, 1.3239999999999998, 1.325, 1.3259999999999998, 1.327, 1.3279999999999998, 1.329, 1.3299999999999998, 1.331, 1.3319999999999999, 1.333, 1.3339999999999999, 1.335, 1.3359999999999999, 1.337, 1.3379999999999999, 1.339, 1.3399999999999999, 1.341, 1.3419999999999999, 1.343, 1.3439999999999999, 1.345, 1.3459999999999999, 1.347, 1.3479999999999999, 1.349, 1.3499999999999999, 1.351, 1.3519999999999999, 1.353, 1.3539999999999999, 1.355, 1.3559999999999999, 1.357, 1.3579999999999999, 1.359, 1.3599999999999999, 1.361, 1.3619999999999999, 1.363, 1.3639999999999999, 1.365, 1.3659999999999999, 1.367, 1.3679999999999999, 1.369, 1.3699999999999999, 1.371, 1.3719999999999999, 1.373, 1.3739999999999999, 1.375, 1.376, 1.377, 1.378, 1.379, 1.38, 1.381, 1.382, 1.383, 1.384, 1.385, 1.386, 1.387, 1.388, 1.389, 1.39, 1.391, 1.392, 1.393, 1.394, 1.395, 1.396, 1.397, 1.398, 1.399, 1.4, 1.401, 1.402, 1.403, 1.404, 1.405, 1.406, 1.407, 1.408, 1.4089999999999998, 1.41, 1.4109999999999998, 1.412, 1.4129999999999998, 1.414, 1.4149999999999998, 1.416, 1.4169999999999998, 1.418, 1.4189999999999998, 1.42, 1.4209999999999998, 1.422, 1.4229999999999998, 1.424, 1.4249999999999998, 1.426, 1.4269999999999998, 1.428, 1.4289999999999998, 1.43, 1.4309999999999998, 1.432, 1.4329999999999998, 1.434, 1.4349999999999998, 1.436, 1.4369999999999998, 1.438, 1.4389999999999998, 1.44, 1.4409999999999998, 1.442, 1.4429999999999998, 1.444, 1.4449999999999998, 1.446, 1.4469999999999998, 1.448, 1.4489999999999998, 1.45, 1.4509999999999998, 1.452, 1.4529999999999998, 1.454, 1.4549999999999998, 1.456, 1.4569999999999999, 1.458, 1.4589999999999999, 1.46, 1.4609999999999999, 1.462, 1.4629999999999999, 1.464, 1.4649999999999999, 1.466, 1.4669999999999999, 1.468, 1.4689999999999999, 1.47, 1.4709999999999999, 1.472, 1.4729999999999999, 1.474, 1.4749999999999999, 1.476, 1.4769999999999999, 1.478, 1.4789999999999999, 1.48, 1.4809999999999999, 1.482, 1.4829999999999999, 1.484, 1.4849999999999999, 1.486, 1.4869999999999999, 1.488, 1.4889999999999999, 1.49, 1.4909999999999999, 1.492, 1.4929999999999999, 1.494, 1.4949999999999999, 1.496, 1.4969999999999999, 1.498, 1.4989999999999999 ] + } + }, + "Positive electrode": { + "Particle radius [m]": 4.6e-06, + "Thickness [m]": 5.23e-05, + "Diffusivity [m2.s-1]": 3.2e-14, + "OCP [V]": "-3.04420906 * x + 10.04892207 - 0.65637536 * tanh(-4.02134095 * (x - 0.80063948)) + 4.24678547 * tanh(12.17805062 * (x - 7.57659337)) - 0.3757068 * tanh(59.33067782 * (x - 0.99784492))", + "Entropic change coefficient [V.K-1]": -1e-4, + "Conductivity [S.m-1]": 0.789, + "Surface area per unit volume [m-1]": 432072, + "Porosity": 0.277493, + "Transport efficiency": 0.1462, + "Reaction rate constant [mol.m-2.s-1]": 2.305e-05, + "Minimum stoichiometry": 0.42424, + "Maximum stoichiometry": 0.96210, + "Maximum concentration [mol.m-3]": 46200, + "Diffusivity activation energy [J.mol-1]": 15000, + "Reaction rate constant activation energy [J.mol-1]": 35000 + }, + "Separator": { + "Thickness [m]": 2e-05, + "Porosity": 0.47, + "Transport efficiency": 0.3222 + } + } +} From e4b061ce09528f3cbb83f5bbd2c651cdfa066191 Mon Sep 17 00:00:00 2001 From: Ivan Korotkin Date: Mon, 25 Sep 2023 12:07:47 +0100 Subject: [PATCH 30/47] Updated changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 281f6a9..765e33d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ - Added validation based on models: SPM, SPMe, DFN ([#34](https://github.com/pybamm-team/BPX/pull/34)). A warning will be produced if the user-defined model type does not match the parameter set (e.g., if the model is `SPM`, but the full DFN model parameters are provided). - Added support for well-mixed, blended electrodes that contain more than one active material ([#33](https://github.com/pybamm-team/BPX/pull/33)) +- Added five parametrisation examples (two DFN parametrisation examples from About:Energy open-source release, blended electrode definition, user-defined 0th-order hysteresis, and SPM parametrisation). # [v0.3.1](https://github.com/pybamm-team/BPX/releases/tag/v0.3.1) From fc3806201ca311e274ce3fa44f72e5f33719235b Mon Sep 17 00:00:00 2001 From: Robert Timms Date: Thu, 5 Oct 2023 13:51:18 +0100 Subject: [PATCH 31/47] #26 fix types for user-defined parameters --- bpx/schema.py | 16 ++++++++++++++-- tests/test_schema.py | 18 +++++++++++++++++- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/bpx/schema.py b/bpx/schema.py index bd58f6a..1e2a8a2 100644 --- a/bpx/schema.py +++ b/bpx/schema.py @@ -1,4 +1,4 @@ -from typing import List, Literal, Union, Dict, get_args +from typing import List, Literal, Union, Dict from pydantic import BaseModel, Field, Extra, root_validator from bpx import Function, InterpolatedTable from warnings import warn @@ -273,10 +273,22 @@ class UserDefined(BaseModel): class Config: extra = Extra.allow + def __init__(Self, **data): + """ + Overwrite the default __init__ to convert strings to Function objects and + dicts to InterpolatedTable objects + """ + for k, v in data.items(): + if isinstance(v, str): + data[k] = Function(v) + elif isinstance(v, dict): + data[k] = InterpolatedTable(**v) + super().__init__(**data) + @root_validator(pre=True) def validate_extra_fields(cls, values): for k, v in values.items(): - if not isinstance(v, get_args(FloatFunctionTable)): + if not isinstance(v, (float, Function, InterpolatedTable)): raise TypeError(f"{k} must be of type 'FloatFunctionTable'") return values diff --git a/tests/test_schema.py b/tests/test_schema.py index 4353137..6bb4840 100644 --- a/tests/test_schema.py +++ b/tests/test_schema.py @@ -270,10 +270,26 @@ def test_user_defined(self): self.assertEqual(obj.parameterisation.user_defined.b, 2) self.assertEqual(obj.parameterisation.user_defined.c, 3) + def test_user_defined_table(self): + test = copy.copy(self.base) + test["Parameterisation"]["User-defined"] = { + "a": { + "x": [1.0, 2.0], + "y": [2.3, 4.5], + }, + } + parse_obj_as(BPX, test) + + def test_user_defined_function(self): + test = copy.copy(self.base) + test["Parameterisation"]["User-defined"] = {"a": "2.0 * x"} + parse_obj_as(BPX, test) + def test_bad_user_defined(self): test = copy.copy(self.base) + # bool not allowed type test["Parameterisation"]["User-defined"] = { - "bad": "strings aren't allowed", + "bad": True, } with self.assertRaises(ValidationError): parse_obj_as(BPX, test) From f116efd5221b2929a713955737474cb621331498 Mon Sep 17 00:00:00 2001 From: Robert Timms Date: Thu, 5 Oct 2023 13:52:16 +0100 Subject: [PATCH 32/47] #26 use get_args --- bpx/schema.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bpx/schema.py b/bpx/schema.py index 1e2a8a2..3908f6b 100644 --- a/bpx/schema.py +++ b/bpx/schema.py @@ -1,4 +1,4 @@ -from typing import List, Literal, Union, Dict +from typing import List, Literal, Union, Dict, get_args from pydantic import BaseModel, Field, Extra, root_validator from bpx import Function, InterpolatedTable from warnings import warn @@ -288,7 +288,7 @@ def __init__(Self, **data): @root_validator(pre=True) def validate_extra_fields(cls, values): for k, v in values.items(): - if not isinstance(v, (float, Function, InterpolatedTable)): + if not isinstance(v, get_args(FloatFunctionTable)): raise TypeError(f"{k} must be of type 'FloatFunctionTable'") return values From dd506d8470519471c8fc2f6c19b1a78442083a0c Mon Sep 17 00:00:00 2001 From: Robert Timms Date: Thu, 5 Oct 2023 13:53:21 +0100 Subject: [PATCH 33/47] #26 use get_args --- bpx/schema.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bpx/schema.py b/bpx/schema.py index 3908f6b..888cafc 100644 --- a/bpx/schema.py +++ b/bpx/schema.py @@ -273,7 +273,7 @@ class UserDefined(BaseModel): class Config: extra = Extra.allow - def __init__(Self, **data): + def __init__(self, **data): """ Overwrite the default __init__ to convert strings to Function objects and dicts to InterpolatedTable objects From b797fea2246c98bbda5f2e7df93fdb3af5dbef2e Mon Sep 17 00:00:00 2001 From: Robert Timms Date: Thu, 5 Oct 2023 15:48:50 +0100 Subject: [PATCH 34/47] #26 update changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7637464..aa70310 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,5 @@ # Unreleased -- Allow user-defined parameters to be added using the field ["Parameterisation"]["User-Defined"] ([#44](https://github.com/pybamm-team/BPX/pull/44)) +- Allow user-defined parameters to be added using the field ["Parameterisation"]["User-defined"] ([#44](https://github.com/pybamm-team/BPX/pull/44)) - Added validation based on models: SPM, SPMe, DFN ([#34](https://github.com/pybamm-team/BPX/pull/34)). A warning will be produced if the user-defined model type does not match the parameter set (e.g., if the model is `SPM`, but the full DFN model parameters are provided). - Added support for well-mixed, blended electrodes that contain more than one active material ([#33](https://github.com/pybamm-team/BPX/pull/33)) From 4cba3f68391b0a82cb4fe3b508fe32ac38d876d9 Mon Sep 17 00:00:00 2001 From: Robert Timms Date: Mon, 16 Oct 2023 11:08:38 +0100 Subject: [PATCH 35/47] update url --- CHANGELOG.md | 18 +++++++++--------- README.md | 4 ++-- docs/conf.py | 8 ++++---- docs/index.rst | 6 +++--- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 281f6a9..82058f3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,21 +1,21 @@ # Unreleased -- Added validation based on models: SPM, SPMe, DFN ([#34](https://github.com/pybamm-team/BPX/pull/34)). A warning will be produced if the user-defined model type does not match the parameter set (e.g., if the model is `SPM`, but the full DFN model parameters are provided). -- Added support for well-mixed, blended electrodes that contain more than one active material ([#33](https://github.com/pybamm-team/BPX/pull/33)) +- Added validation based on models: SPM, SPMe, DFN ([#34](https://github.com/FaradayInstitution/BPX/pull/34)). A warning will be produced if the user-defined model type does not match the parameter set (e.g., if the model is `SPM`, but the full DFN model parameters are provided). +- Added support for well-mixed, blended electrodes that contain more than one active material ([#33](https://github.com/FaradayInstitution/BPX/pull/33)) -# [v0.3.1](https://github.com/pybamm-team/BPX/releases/tag/v0.3.1) +# [v0.3.1](https://github.com/FaradayInstitution/BPX/releases/tag/v0.3.1) -- Temporarily pin Pydantic version ([#35](https://github.com/pybamm-team/BPX/pull/35)) +- Temporarily pin Pydantic version ([#35](https://github.com/FaradayInstitution/BPX/pull/35)) -# [v0.3.0](https://github.com/pybamm-team/BPX/releases/tag/v0.3.0) +# [v0.3.0](https://github.com/FaradayInstitution/BPX/releases/tag/v0.3.0) - Added a missing factor of 2 in the definition of the interfacial current, see the Butler-Volmer equation (2a) in the associated BPX standard document. The interfacial current is now given by $j=2j_0\sinh(F\eta/2/R/T)$ instead of $j=j_0\sinh(F\eta/2/R/T)$. -# [v0.2.0](https://github.com/pybamm-team/BPX/releases/tag/v0.2.0) +# [v0.2.0](https://github.com/FaradayInstitution/BPX/releases/tag/v0.2.0) -- Parsing a BPX json file with additional (unexpected) fields now raises a `ValidationError` ([#16](https://github.com/pybamm-team/BPX/pull/16)) -- Fixed a bug in the experiment schema ([#13](https://github.com/pybamm-team/BPX/pull/13)) +- Parsing a BPX json file with additional (unexpected) fields now raises a `ValidationError` ([#16](https://github.com/FaradayInstitution/BPX/pull/16)) +- Fixed a bug in the experiment schema ([#13](https://github.com/FaradayInstitution/BPX/pull/13)) -# [v0.1.0](https://github.com/pybamm-team/BPX/releases/tag/v0.1.0) +# [v0.1.0](https://github.com/FaradayInstitution/BPX/releases/tag/v0.1.0) Initial release of the Battery Parameter eXchange (BPX) format. diff --git a/README.md b/README.md index 14f40e4..897e480 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # 🔋 BPX -![tests](https://github.com/pybamm-team/BPX/actions/workflows/test.yml/badge.svg) -[![codecov](https://codecov.io/gh/pybamm-team/BPX/branch/main/graph/badge.svg?token=Krv0JW3gYZ)](https://codecov.io/gh/pybamm-team/BPX) +![tests](https://github.com/FaradayInstitution/BPX/actions/workflows/test.yml/badge.svg) +[![codecov](https://codecov.io/gh/FaradayInstitution/BPX/branch/main/graph/badge.svg?token=Krv0JW3gYZ)](https://codecov.io/gh/FaradayInstitution/BPX) An implementation of the Battery Parameter eXchange (BPX) format in Pydantic. BPX, an outcome of the Faraday Institution [Multi-scale Modelling project](https://www.faraday.ac.uk/research/lithium-ion/battery-system-modelling/), is an open standard for physics-based Li-ion battery models that has been developed to reduce costs and time-to-market through a common definition of physics-based battery models that can be used widely across industry. To find out more, visit the [BPX website](https://bpxstandard.com/). diff --git a/docs/conf.py b/docs/conf.py index 15ca9c6..f63e0ae 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -111,7 +111,7 @@ "icon_links": [ { "name": "GitHub", - "url": "https://github.com/pybamm-team/bpx", + "url": "https://github.com/FaradayInstitution/BPX", "icon": "fa-brands fa-square-github", }, { @@ -124,7 +124,7 @@ "external_links": [ { "name": "Contributing", - "url": "https://github.com/pybamm-team/bpx/tree/develop/CONTRIBUTING.md", + "url": "https://github.com/FaradayInstitution/BPX/tree/develop/CONTRIBUTING.md", }, ], "footer_start": [ @@ -152,8 +152,8 @@ # For edit button html_context = { - "github_user": "pybamm-team", - "github_repo": "bpx", + "github_user": "FaradayInstitution", + "github_repo": "BPX", "github_version": "main", "doc_path": "docs/", } diff --git a/docs/index.rst b/docs/index.rst index 47685f4..7423b0f 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -17,8 +17,8 @@ BPX documentation **Useful links**: `Project Home Page `_ | `Installation `_ | -`Source Repository `_ | -`Issue Tracker `_ | -`Discussions `_ +`Source Repository `_ | +`Issue Tracker `_ | +`Discussions `_ BPX, an outcome of the Faraday Institution Multi-scale Modelling project, is an open standard for physics-based Li-ion battery models that has been developed to reduce costs and time-to-market through a common definition of physics-based battery models that can be used widely across industry. From 694e7271bb75b4cb1b9da9e1ea1e74cd3b2b2a79 Mon Sep 17 00:00:00 2001 From: Robert Timms Date: Mon, 16 Oct 2023 11:14:35 +0100 Subject: [PATCH 36/47] update docstrings --- bpx/expression_parser.py | 3 ++- bpx/function.py | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/bpx/expression_parser.py b/bpx/expression_parser.py index 746e2d9..58aa87d 100644 --- a/bpx/expression_parser.py +++ b/bpx/expression_parser.py @@ -9,7 +9,8 @@ class ExpressionParser: """ - An expression parser for mathematical expressions. + An expression parser for mathematical expressions. For valid expressions, + please see :class:`bpx.Function`. """ ParseException = pp.ParseException diff --git a/bpx/function.py b/bpx/function.py index 44ad7ae..4a73643 100644 --- a/bpx/function.py +++ b/bpx/function.py @@ -46,8 +46,8 @@ def to_python_function(self, preamble: str = None) -> Callable: Parameters ---------- - preamble: ste, options - a string of python code to be prepended to the function + preamble: str, optional + A string of python code to be prepended to the function definition. This can be used to import modules or define helper functions. """ From ee7f21c044eee6d653e1e2733e7957729b702af8 Mon Sep 17 00:00:00 2001 From: Robert Timms Date: Thu, 19 Oct 2023 14:17:24 +0100 Subject: [PATCH 37/47] update authors and install --- docs/conf.py | 4 ++-- docs/source/user_guide/getting_started.md | 6 +----- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index f63e0ae..d212099 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -26,8 +26,8 @@ # -- Project information ----------------------------------------------------- project = "BPX" -copyright = "2022, University of Oxford" -author = "Martin Robinson" +copyright = "2022-2023, University of Oxford" +author = "Edmund Dickinson, Ivan Korotkin, Martin Robinson, Robert Timms" # The short X.Y version version = bpx.__version__ diff --git a/docs/source/user_guide/getting_started.md b/docs/source/user_guide/getting_started.md index ee8f3c2..0c99f41 100644 --- a/docs/source/user_guide/getting_started.md +++ b/docs/source/user_guide/getting_started.md @@ -1,10 +1,6 @@ # Getting Started -To get started, first install the `BPX` module using pip -```bash -pip install bpx -``` -For more detailed installation instructions, see [](installation). +To get started, first install the `BPX` following the instructions given in [](installation). To create a BPX object from a JSON file, you can use the `parse_bpx_file` function ```python From 8b359b3f338a018568183447d65e9f05c6dcf11a Mon Sep 17 00:00:00 2001 From: Robert Timms Date: Thu, 19 Oct 2023 14:28:48 +0100 Subject: [PATCH 38/47] add readthedocs.yaml --- .readthedocs.yaml | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 .readthedocs.yaml diff --git a/.readthedocs.yaml b/.readthedocs.yaml new file mode 100644 index 0000000..08df06c --- /dev/null +++ b/.readthedocs.yaml @@ -0,0 +1,25 @@ +# .readthedocs.yaml +# Read the Docs configuration file +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details + +# Required +version: 2 + +# Set the version of Python and other tools you might need +build: + os: ubuntu-22.04 + tools: + python: "3.11" + +# Build documentation in the docs/ directory with Sphinx +sphinx: + builder: html + configuration: docs/conf.py + fail_on_warning: false + +# Optionally declare the Python requirements required to build your docs +python: + install: + - method: pip + path: . + From 1d51b3d7f4e7cd78f588ea5d781e1afd11cbba52 Mon Sep 17 00:00:00 2001 From: Ivan Korotkin Date: Thu, 19 Oct 2023 15:53:29 +0100 Subject: [PATCH 39/47] Add v_tol to parse_bpx_obj and parse_bpx_str, rename the global setting for tolerances --- CHANGELOG.md | 2 +- bpx/parsers.py | 22 +++++++++++++++++++--- bpx/schema.py | 12 +++++++----- bpx/validators.py | 2 +- tests/test_schema.py | 4 ++-- 5 files changed, 30 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d57fb14..0ba31e6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ - Allow user-defined parameters to be added using the field ["Parameterisation"]["User-defined"] ([#44](https://github.com/pybamm-team/BPX/pull/44)) - Added validation based on models: SPM, SPMe, DFN ([#34](https://github.com/pybamm-team/BPX/pull/34)). A warning will be produced if the user-defined model type does not match the parameter set (e.g., if the model is `SPM`, but the full DFN model parameters are provided). - Added support for well-mixed, blended electrodes that contain more than one active material ([#33](https://github.com/pybamm-team/BPX/pull/33)) -- Added validation of the STO limits subbed into the OCPs vs the upper/lower cut-off voltage limits for non-blended electrodes with the OCPs defined as functions ([#32](https://github.com/FaradayInstitution/BPX/pull/32)). The user can provide a tolerance by updating the settings variable `BPX.settings.v_tol` or by passing extra option `v_tol` to `parse_bpx_file()` function. Default value of the tolerance is 1 mV. The tolerance cannot be negative. +- Added validation of the STO limits subbed into the OCPs vs the upper/lower cut-off voltage limits for non-blended electrodes with the OCPs defined as functions ([#32](https://github.com/FaradayInstitution/BPX/pull/32)). The user can provide a tolerance by updating the settings variable `BPX.settings.tolerances["Voltage [V]"]` or by passing extra option `v_tol` to `parse_bpx_file()`, `parse_bpx_obj()` or `parse_bpx_str()` functions. Default value of the tolerance is 1 mV. The tolerance cannot be negative. - Added the target SOC check in `get_electrode_concentrations()` function. Raise a warning if the SOC is outside of [0,1] interval. - In `get_electrode_stoichiometries()` function, raise a warning instead of an error if the SOC is outside of [0,1] interval. - Added five parametrisation examples (two DFN parametrisation examples from About:Energy open-source release, blended electrode definition, user-defined 0th-order hysteresis, and SPM parametrisation). diff --git a/bpx/parsers.py b/bpx/parsers.py index 6b13a7f..49d9066 100644 --- a/bpx/parsers.py +++ b/bpx/parsers.py @@ -19,36 +19,52 @@ def parse_bpx_file(filename: str, v_tol: float = 0.001) -> BPX: if v_tol < 0: raise ValueError("v_tol should not be negative") - return BPX.parse_file(BPX, filename, v_tol=v_tol) + BPX.settings.tolerances["Voltage [V]"] = v_tol + return BPX.parse_file(filename) -def parse_bpx_obj(bpx: dict) -> BPX: + +def parse_bpx_obj(bpx: dict, v_tol: float = 0.001) -> BPX: """ Parameters ---------- bpx: dict a dict object in bpx format + v_tol: float + absolute tolerance in [V] to validate the voltage limits, 1 mV by default Returns ------- BPX: a parsed BPX model """ + if v_tol < 0: + raise ValueError("v_tol should not be negative") + + BPX.settings.tolerances["Voltage [V]"] = v_tol + return BPX.parse_obj(bpx) -def parse_bpx_str(bpx: str) -> BPX: +def parse_bpx_str(bpx: str, v_tol: float = 0.001) -> BPX: """ Parameters ---------- bpx: str a json formatted string in bpx format + v_tol: float + absolute tolerance in [V] to validate the voltage limits, 1 mV by default Returns ------- BPX: a parsed BPX model """ + if v_tol < 0: + raise ValueError("v_tol should not be negative") + + BPX.settings.tolerances["Voltage [V]"] = v_tol + return BPX.parse_raw(bpx) diff --git a/bpx/schema.py b/bpx/schema.py index b34cf45..de57b97 100644 --- a/bpx/schema.py +++ b/bpx/schema.py @@ -10,13 +10,15 @@ class ExtraBaseModel(BaseModel): class Config: extra = Extra.forbid - # @dataclass class settings: - v_tol: float = 0.001 # Absolute tolerance in [V] to validate the voltage limits + """ + Class with BPX-related settings. + It might be worth moving it to a separate file if it grows bigger. + """ - def parse_file(self, filename, v_tol): - self.settings.v_tol = v_tol - return super().parse_file(filename) + tolerances = { + "Voltage [V]": 1e-3, # Absolute tolerance in [V] to validate the voltage limits + } class Header(ExtraBaseModel): diff --git a/bpx/validators.py b/bpx/validators.py index ed113cb..5825b10 100644 --- a/bpx/validators.py +++ b/bpx/validators.py @@ -24,7 +24,7 @@ def check_sto_limits(cls, values): V_max = values.get("cell").upper_voltage_cutoff # Voltage tolerance from `settings` data class - tol = cls.settings.v_tol + tol = cls.settings.tolerances["Voltage [V]"] # Checks the maximum voltage estimated from STO V_max_sto = ocp_p(sto_p_min) - ocp_n(sto_n_max) diff --git a/tests/test_schema.py b/tests/test_schema.py index ca0d979..588ff73 100644 --- a/tests/test_schema.py +++ b/tests/test_schema.py @@ -331,7 +331,7 @@ def test_check_sto_limits_validator_high_voltage_tolerance(self): warnings.filterwarnings("error") # Treat warnings as errors test = copy.copy(self.base_non_blended) test["Parameterisation"]["Cell"]["Upper voltage cut-off [V]"] = 4.0 - BPX.settings.v_tol = 0.25 + BPX.settings.tolerances["Voltage [V]"] = 0.25 parse_obj_as(BPX, test) def test_check_sto_limits_validator_low_voltage(self): @@ -344,7 +344,7 @@ def test_check_sto_limits_validator_low_voltage_tolerance(self): warnings.filterwarnings("error") # Treat warnings as errors test = copy.copy(self.base_non_blended) test["Parameterisation"]["Cell"]["Lower voltage cut-off [V]"] = 3.0 - BPX.settings.v_tol = 0.35 + BPX.settings.tolerances["Voltage [V]"] = 0.35 parse_obj_as(BPX, test) def test_user_defined(self): From cd577b9c718b01ecd1d24b1d1b320ce86650a6ee Mon Sep 17 00:00:00 2001 From: Ivan Korotkin Date: Thu, 19 Oct 2023 16:18:33 +0100 Subject: [PATCH 40/47] Added tests --- tests/test_parsers.py | 108 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 105 insertions(+), 3 deletions(-) diff --git a/tests/test_parsers.py b/tests/test_parsers.py index 506cdda..fc00011 100644 --- a/tests/test_parsers.py +++ b/tests/test_parsers.py @@ -1,12 +1,114 @@ import unittest +import warnings +import copy -from bpx import parse_bpx_file +from bpx import BPX, parse_bpx_file, parse_bpx_obj, parse_bpx_str class TestParsers(unittest.TestCase): - def test_negative_v_tol(self): + def setUp(self): + self.base = """ + { + "Header": { + "BPX": 0.1, + "Title": "Parameterisation example of an NMC111|graphite 12.5 Ah pouch cell", + "Model": "DFN" + }, + "Parameterisation": { + "Cell": { + "Ambient temperature [K]": 298.15, + "Initial temperature [K]": 298.15, + "Reference temperature [K]": 298.15, + "Lower voltage cut-off [V]": 2.7, + "Upper voltage cut-off [V]": 4.2, + "Nominal cell capacity [A.h]": 12.5, + "Specific heat capacity [J.K-1.kg-1]": 913, + "Thermal conductivity [W.m-1.K-1]": 2.04, + "Density [kg.m-3]": 1847, + "Electrode area [m2]": 0.016808, + "Number of electrode pairs connected in parallel to make a cell": 34, + "External surface area [m2]": 0.0379, + "Volume [m3]": 0.000128 + }, + "Electrolyte": { + "Initial concentration [mol.m-3]": 1000, + "Cation transference number": 0.2594, + "Conductivity [S.m-1]": "0.1297 * (x / 1000) ** 3 - 2.51 * (x / 1000) ** 1.5 + 3.329 * (x / 1000)", + "Diffusivity [m2.s-1]": "8.794e-11 * (x / 1000) ** 2 - 3.972e-10 * (x / 1000) + 4.862e-10", + "Conductivity activation energy [J.mol-1]": 17100, + "Diffusivity activation energy [J.mol-1]": 17100 + }, + "Negative electrode": { + "Particle radius [m]": 4.12e-06, + "Thickness [m]": 5.62e-05, + "Diffusivity [m2.s-1]": 2.728e-14, + "OCP [V]": "9.47057878e-01 * exp(-1.59418743e+02 * x) - 3.50928033e+04 + 1.64230269e-01 * tanh(-4.55509094e+01 * (x - 3.24116012e-02 )) + 3.69968491e-02 * tanh(-1.96718868e+01 * (x - 1.68334476e-01)) + 1.91517003e+04 * tanh(3.19648312e+00 * (x - 1.85139824e+00)) + 5.42448511e+04 * tanh(-3.19009848e+00 * (x - 2.01660395e+00))", + "Entropic change coefficient [V.K-1]": "(-0.1112 * x + 0.02914 + 0.3561 * exp(-((x - 0.08309) ** 2) / 0.004616)) / 1000", + "Conductivity [S.m-1]": 0.222, + "Surface area per unit volume [m-1]": 499522, + "Porosity": 0.253991, + "Transport efficiency": 0.128, + "Reaction rate constant [mol.m-2.s-1]": 5.199e-06, + "Minimum stoichiometry": 0.005504, + "Maximum stoichiometry": 0.75668, + "Maximum concentration [mol.m-3]": 29730, + "Diffusivity activation energy [J.mol-1]": 30000, + "Reaction rate constant activation energy [J.mol-1]": 55000 + }, + "Positive electrode": { + "Particle radius [m]": 4.6e-06, + "Thickness [m]": 5.23e-05, + "Diffusivity [m2.s-1]": 3.2e-14, + "OCP [V]": "-3.04420906 * x + 10.04892207 - 0.65637536 * tanh(-4.02134095 * (x - 0.80063948)) + 4.24678547 * tanh(12.17805062 * (x - 7.57659337)) - 0.3757068 * tanh(59.33067782 * (x - 0.99784492))", + "Entropic change coefficient [V.K-1]": -1e-4, + "Conductivity [S.m-1]": 0.789, + "Surface area per unit volume [m-1]": 432072, + "Porosity": 0.277493, + "Transport efficiency": 0.1462, + "Reaction rate constant [mol.m-2.s-1]": 2.305e-05, + "Minimum stoichiometry": 0.42424, + "Maximum stoichiometry": 0.96210, + "Maximum concentration [mol.m-3]": 46200, + "Diffusivity activation energy [J.mol-1]": 15000, + "Reaction rate constant activation energy [J.mol-1]": 35000 + }, + "Separator": { + "Thickness [m]": 2e-05, + "Porosity": 0.47, + "Transport efficiency": 0.3222 + } + } + } + """ + + def test_negative_v_tol_file(self): with self.assertRaisesRegex( ValueError, "v_tol should not be negative", ): - parse_bpx_file("filename", -0.001) + parse_bpx_file("filename", v_tol=-0.001) + + def test_negative_v_tol_object(self): + bpx_obj = {"BPX": 1.0} + with self.assertRaisesRegex( + ValueError, + "v_tol should not be negative", + ): + parse_bpx_obj(bpx_obj, v_tol=-0.001) + + def test_negative_v_tol_string(self): + with self.assertRaisesRegex( + ValueError, + "v_tol should not be negative", + ): + parse_bpx_str("String", v_tol=-0.001) + + def test_parse_string(self): + test = copy.copy(self.base) + with self.assertWarns(UserWarning): + parse_bpx_str(test) + + def test_parse_string_tolerance(self): + warnings.filterwarnings("error") # Treat warnings as errors + test = copy.copy(self.base) + parse_bpx_str(test, v_tol=0.002) From df537c74b6b519cf51180a7c719336913a8a69e6 Mon Sep 17 00:00:00 2001 From: Ivan Korotkin Date: Thu, 19 Oct 2023 16:35:12 +0100 Subject: [PATCH 41/47] Split long strings into several lines --- tests/test_parsers.py | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/tests/test_parsers.py b/tests/test_parsers.py index fc00011..c278c2e 100644 --- a/tests/test_parsers.py +++ b/tests/test_parsers.py @@ -7,7 +7,7 @@ class TestParsers(unittest.TestCase): def setUp(self): - self.base = """ + base = """ { "Header": { "BPX": 0.1, @@ -42,8 +42,14 @@ def setUp(self): "Particle radius [m]": 4.12e-06, "Thickness [m]": 5.62e-05, "Diffusivity [m2.s-1]": 2.728e-14, - "OCP [V]": "9.47057878e-01 * exp(-1.59418743e+02 * x) - 3.50928033e+04 + 1.64230269e-01 * tanh(-4.55509094e+01 * (x - 3.24116012e-02 )) + 3.69968491e-02 * tanh(-1.96718868e+01 * (x - 1.68334476e-01)) + 1.91517003e+04 * tanh(3.19648312e+00 * (x - 1.85139824e+00)) + 5.42448511e+04 * tanh(-3.19009848e+00 * (x - 2.01660395e+00))", - "Entropic change coefficient [V.K-1]": "(-0.1112 * x + 0.02914 + 0.3561 * exp(-((x - 0.08309) ** 2) / 0.004616)) / 1000", + "OCP [V]": + "9.47057878e-01 * exp(-1.59418743e+02 * x) - 3.50928033e+04 + + 1.64230269e-01 * tanh(-4.55509094e+01 * (x - 3.24116012e-02 )) + + 3.69968491e-02 * tanh(-1.96718868e+01 * (x - 1.68334476e-01)) + + 1.91517003e+04 * tanh(3.19648312e+00 * (x - 1.85139824e+00)) + + 5.42448511e+04 * tanh(-3.19009848e+00 * (x - 2.01660395e+00))", + "Entropic change coefficient [V.K-1]": + "(-0.1112 * x + 0.02914 + 0.3561 * exp(-((x - 0.08309) ** 2) / 0.004616)) / 1000", "Conductivity [S.m-1]": 0.222, "Surface area per unit volume [m-1]": 499522, "Porosity": 0.253991, @@ -59,7 +65,9 @@ def setUp(self): "Particle radius [m]": 4.6e-06, "Thickness [m]": 5.23e-05, "Diffusivity [m2.s-1]": 3.2e-14, - "OCP [V]": "-3.04420906 * x + 10.04892207 - 0.65637536 * tanh(-4.02134095 * (x - 0.80063948)) + 4.24678547 * tanh(12.17805062 * (x - 7.57659337)) - 0.3757068 * tanh(59.33067782 * (x - 0.99784492))", + "OCP [V]": + "-3.04420906 * x + 10.04892207 - 0.65637536 * tanh(-4.02134095 * (x - 0.80063948)) + + 4.24678547 * tanh(12.17805062 * (x - 7.57659337)) - 0.3757068 * tanh(59.33067782 * (x - 0.99784492))", "Entropic change coefficient [V.K-1]": -1e-4, "Conductivity [S.m-1]": 0.789, "Surface area per unit volume [m-1]": 432072, @@ -80,6 +88,7 @@ def setUp(self): } } """ + self.base = base.replace("\n", "") def test_negative_v_tol_file(self): with self.assertRaisesRegex( From fee5318735dd09d2fba71d8603f667535edda709 Mon Sep 17 00:00:00 2001 From: Ivan Korotkin Date: Thu, 19 Oct 2023 17:58:56 +0100 Subject: [PATCH 42/47] Fix one typo and one description --- bpx/schema.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bpx/schema.py b/bpx/schema.py index 888cafc..70b696b 100644 --- a/bpx/schema.py +++ b/bpx/schema.py @@ -32,7 +32,7 @@ class Header(ExtraBaseModel): references: str = Field( None, alias="References", - descrciption=("May contain any references"), + description=("May contain any references"), example="Chang-Hui Chen et al 2020 J. Electrochem. Soc. 167 080534", ) model: Literal["SPM", "SPMe", "DFN"] = Field( @@ -249,7 +249,7 @@ class Electrode(Contact): conductivity: float = Field( alias="Conductivity [S.m-1]", example=0.18, - description=("Electrolyte conductivity (constant)"), + description=("Effective electronic conductivity of the porous electrode matrix (constant)"), ) From 19b78b858f3e9f46067c789351ab02e37e9cf517 Mon Sep 17 00:00:00 2001 From: Robert Timms Date: Wed, 8 Nov 2023 11:46:26 +0000 Subject: [PATCH 43/47] remove makefile --- docs/Makefile | 19 ------------------- 1 file changed, 19 deletions(-) delete mode 100644 docs/Makefile diff --git a/docs/Makefile b/docs/Makefile deleted file mode 100644 index 46d9ea6..0000000 --- a/docs/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -# Minimal makefile for Sphinx documentation -# - -# You can set these variables from the command line. -SPHINXOPTS = -j auto -SPHINXBUILD = sphinx-build -SOURCEDIR = . -BUILDDIR = _build - -# Put it first so that "make" without argument is like "make help". -help: - @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) - -.PHONY: help Makefile - -# Catch-all target: route all unknown targets to Sphinx using the new -# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). -%: Makefile - @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) From c36a05b153793ba26b865d93a5538b1ab54a6a6b Mon Sep 17 00:00:00 2001 From: Robert Timms Date: Wed, 8 Nov 2023 11:49:53 +0000 Subject: [PATCH 44/47] bump version number --- CHANGELOG.md | 3 ++- bpx/__init__.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 60f0fa3..f9ae3a4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,8 @@ -# Unreleased +# v0.4.0 - Added five parametrisation examples (two DFN parametrisation examples from About:Energy open-source release, blended electrode definition, user-defined 0th-order hysteresis, and SPM parametrisation). ([#45](https://github.com/FaradayInstitution/BPX/pull/45)) - Allow user-defined parameters to be added using the field ["Parameterisation"]["User-defined"] ([#44](https://github.com/pybamm-team/BPX/pull/44)) +- Added basic API documentation ([#43](https://github.com/FaradayInstitution/BPX/pull/43)) - Added validation based on models: SPM, SPMe, DFN ([#34](https://github.com/pybamm-team/BPX/pull/34)). A warning will be produced if the user-defined model type does not match the parameter set (e.g., if the model is `SPM`, but the full DFN model parameters are provided). - Added support for well-mixed, blended electrodes that contain more than one active material ([#33](https://github.com/pybamm-team/BPX/pull/33)) - Added validation of the STO limits subbed into the OCPs vs the upper/lower cut-off voltage limits for non-blended electrodes with the OCPs defined as functions ([#32](https://github.com/FaradayInstitution/BPX/pull/32)). The user can provide a tolerance by updating the settings variable `BPX.settings.tolerances["Voltage [V]"]` or by passing extra option `v_tol` to `parse_bpx_file()`, `parse_bpx_obj()` or `parse_bpx_str()` functions. Default value of the tolerance is 1 mV. The tolerance cannot be negative. diff --git a/bpx/__init__.py b/bpx/__init__.py index e7d9f3b..0d01aa4 100644 --- a/bpx/__init__.py +++ b/bpx/__init__.py @@ -1,7 +1,7 @@ """BPX schema and parsers""" # flake8: noqa F401 -__version__ = "0.3.1" +__version__ = "0.4.0" from .interpolated_table import InterpolatedTable from .expression_parser import ExpressionParser From 39ad3d6777aad363257085987d3a8a6108e12bd0 Mon Sep 17 00:00:00 2001 From: Robert Timms Date: Wed, 8 Nov 2023 11:51:20 +0000 Subject: [PATCH 45/47] update changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f9ae3a4..8fdc6c7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -# v0.4.0 +# [v0.4.0](https://github.com/FaradayInstitution/BPX/releases/tag/v0.4.0) - Added five parametrisation examples (two DFN parametrisation examples from About:Energy open-source release, blended electrode definition, user-defined 0th-order hysteresis, and SPM parametrisation). ([#45](https://github.com/FaradayInstitution/BPX/pull/45)) - Allow user-defined parameters to be added using the field ["Parameterisation"]["User-defined"] ([#44](https://github.com/pybamm-team/BPX/pull/44)) From c184b7b8aa0539d7971272c186ac68bbc5f1071b Mon Sep 17 00:00:00 2001 From: Robert Timms Date: Mon, 13 Nov 2023 09:46:14 +0000 Subject: [PATCH 46/47] update urls and docs instructios --- CHANGELOG.md | 8 ++++---- README.md | 6 +++--- docs/source/user_guide/getting_started.md | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5ba5659..676b29e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,10 @@ # [v0.4.0](https://github.com/FaradayInstitution/BPX/releases/tag/v0.4.0) - Added five parametrisation examples (two DFN parametrisation examples from About:Energy open-source release, blended electrode definition, user-defined 0th-order hysteresis, and SPM parametrisation). ([#45](https://github.com/FaradayInstitution/BPX/pull/45)) -- Allow user-defined parameters to be added using the field ["Parameterisation"]["User-defined"] ([#44](https://github.com/pybamm-team/BPX/pull/44)) +- Allow user-defined parameters to be added using the field ["Parameterisation"]["User-defined"] ([#44](https://github.com/FaradayInstitution/BPX/pull/44)) - Added basic API documentation ([#43](https://github.com/FaradayInstitution/BPX/pull/43)) -- Added validation based on models: SPM, SPMe, DFN ([#34](https://github.com/pybamm-team/BPX/pull/34)). A warning will be produced if the user-defined model type does not match the parameter set (e.g., if the model is `SPM`, but the full DFN model parameters are provided). -- Added support for well-mixed, blended electrodes that contain more than one active material ([#33](https://github.com/pybamm-team/BPX/pull/33)) +- Added validation based on models: SPM, SPMe, DFN ([#34](https://github.com/FaradayInstitution/BPX/pull/34)). A warning will be produced if the user-defined model type does not match the parameter set (e.g., if the model is `SPM`, but the full DFN model parameters are provided). +- Added support for well-mixed, blended electrodes that contain more than one active material ([#33](https://github.com/FaradayInstitution/BPX/pull/33)) - Added validation of the STO limits subbed into the OCPs vs the upper/lower cut-off voltage limits for non-blended electrodes with the OCPs defined as functions ([#32](https://github.com/FaradayInstitution/BPX/pull/32)). The user can provide a tolerance by updating the settings variable `BPX.settings.tolerances["Voltage [V]"]` or by passing extra option `v_tol` to `parse_bpx_file()`, `parse_bpx_obj()` or `parse_bpx_str()` functions. Default value of the tolerance is 1 mV. The tolerance cannot be negative. - Added the target SOC check in `get_electrode_concentrations()` function. Raise a warning if the SOC is outside of [0,1] interval. @@ -12,7 +12,7 @@ - Temporarily pin Pydantic version ([#35](https://github.com/FaradayInstitution/BPX/pull/35)) -# [v0.3.0](https://github.com/pybamm-team/BPX/releases/tag/v0.3.0) +# [v0.3.0](https://github.com/FaradayInstitution/BPX/releases/tag/v0.3.0) - Added a missing factor of 2 in the definition of the interfacial current, see the Butler-Volmer equation (2a) in the associated BPX standard document. The interfacial current is now given by $j=2j_0\sinh(F\eta/2/R/T)$ instead of $j=j_0\sinh(F\eta/2/R/T)$. diff --git a/README.md b/README.md index 8cce679..6bb9c6c 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ This repository features a Pydantic-based parser for JSON files in the BPX forma To support the new open standard, [About:Energy](https://www.aboutenergy.io/) have supplied two parameters sets for an NMC and LFP cell. The BPX files and associated examples and information can be found on the [A:E BPX Parameterisation repository](https://github.com/About-Energy-OpenSource/About-Energy-BPX-Parameterisation/). -To see how to use BPX with [PyBaMM](https://www.pybamm.org/), check out the [BPX example repository](https://github.com/pybamm-team/bpx-example). +To see how to use BPX with [PyBaMM](https://www.pybamm.org/), check out the [BPX example repository](https://github.com/FaradayInstitution/bpx-example). ## 🚀 Installation The BPX package can be installed using pip @@ -26,7 +26,7 @@ import bpx filename = 'path/to/my/file.json' my_params = bpx.parse_bpx_file(filename) ``` -`my_params` will now be of type `BPX`, which acts like a python dataclass with the same attributes as the BPX format. To obatin example files, see the `examples` folder, the [A:E BPX Parameterisation repository](https://github.com/About-Energy-OpenSource/About-Energy-BPX-Parameterisation/), or the [BPX example repository](https://github.com/pybamm-team/bpx-example). +`my_params` will now be of type `BPX`, which acts like a python dataclass with the same attributes as the BPX format. To obatin example files, see the `examples` folder, the [A:E BPX Parameterisation repository](https://github.com/About-Energy-OpenSource/About-Energy-BPX-Parameterisation/), or the [BPX example repository](https://github.com/FaradayInstitution/bpx-example). Attributes of the class can be printed out using the standard Python dot notation, for example, you can print out the initial temperature of the cell using ```python @@ -60,7 +60,7 @@ print(bpx.BPX.schema_json(indent=2)) According to the `pydantic` docs, the generated schemas are compliant with the specifications: JSON Schema Core, JSON Schema Validation and OpenAPI. ## 📖 Documentation -API documentation for the `bpx` package can be built locally using [Sphinx](https://www.sphinx-doc.org/en/master/). To build the documentation first [clone the repository](https://github.com/git-guides/git-clone), then run the following command: +API documentation for the `bpx` package can be built locally using [Sphinx](https://www.sphinx-doc.org/en/master/). To build the documentation first [clone the repository](https://github.com/git-guides/git-clone), install the `bpx` package, and then run the following command: ```bash sphinx-build docs docs/_build/html ``` diff --git a/docs/source/user_guide/getting_started.md b/docs/source/user_guide/getting_started.md index 0c99f41..6090f49 100644 --- a/docs/source/user_guide/getting_started.md +++ b/docs/source/user_guide/getting_started.md @@ -9,7 +9,7 @@ import bpx filename = 'path/to/my/file.json' my_params = bpx.parse_bpx_file(filename) ``` -`my_params` will now be of type `BPX`, which acts like a python dataclass with the same attributes as the BPX format. To obatin example files, see the [A:E BPX Parameterisation repository](https://github.com/About-Energy-OpenSource/About-Energy-BPX-Parameterisation/) or [BPX example repository](https://github.com/pybamm-team/bpx-example). +`my_params` will now be of type `BPX`, which acts like a python dataclass with the same attributes as the BPX format. To obatin example files, see the [A:E BPX Parameterisation repository](https://github.com/About-Energy-OpenSource/About-Energy-BPX-Parameterisation/) or [BPX example repository](https://github.com/FaradayInstitution/bpx-example). Attributes of the class can be printed out using the standard Python dot notation, for example, you can print out the initial temperature of the cell using ```python From 64c6470aaf06d6bdd65de7c3a52b7685bbc81e92 Mon Sep 17 00:00:00 2001 From: Robert Timms Date: Mon, 13 Nov 2023 13:58:23 +0000 Subject: [PATCH 47/47] revert bpx-example url --- README.md | 4 ++-- docs/source/user_guide/getting_started.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 6bb9c6c..a50de69 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ This repository features a Pydantic-based parser for JSON files in the BPX forma To support the new open standard, [About:Energy](https://www.aboutenergy.io/) have supplied two parameters sets for an NMC and LFP cell. The BPX files and associated examples and information can be found on the [A:E BPX Parameterisation repository](https://github.com/About-Energy-OpenSource/About-Energy-BPX-Parameterisation/). -To see how to use BPX with [PyBaMM](https://www.pybamm.org/), check out the [BPX example repository](https://github.com/FaradayInstitution/bpx-example). +To see how to use BPX with [PyBaMM](https://www.pybamm.org/), check out the [BPX example repository](https://github.com/pybamm-team/bpx-example). ## 🚀 Installation The BPX package can be installed using pip @@ -26,7 +26,7 @@ import bpx filename = 'path/to/my/file.json' my_params = bpx.parse_bpx_file(filename) ``` -`my_params` will now be of type `BPX`, which acts like a python dataclass with the same attributes as the BPX format. To obatin example files, see the `examples` folder, the [A:E BPX Parameterisation repository](https://github.com/About-Energy-OpenSource/About-Energy-BPX-Parameterisation/), or the [BPX example repository](https://github.com/FaradayInstitution/bpx-example). +`my_params` will now be of type `BPX`, which acts like a python dataclass with the same attributes as the BPX format. To obatin example files, see the `examples` folder, the [A:E BPX Parameterisation repository](https://github.com/About-Energy-OpenSource/About-Energy-BPX-Parameterisation/), or the [BPX example repository](https://github.com/pybamm-team/bpx-example). Attributes of the class can be printed out using the standard Python dot notation, for example, you can print out the initial temperature of the cell using ```python diff --git a/docs/source/user_guide/getting_started.md b/docs/source/user_guide/getting_started.md index 6090f49..0c99f41 100644 --- a/docs/source/user_guide/getting_started.md +++ b/docs/source/user_guide/getting_started.md @@ -9,7 +9,7 @@ import bpx filename = 'path/to/my/file.json' my_params = bpx.parse_bpx_file(filename) ``` -`my_params` will now be of type `BPX`, which acts like a python dataclass with the same attributes as the BPX format. To obatin example files, see the [A:E BPX Parameterisation repository](https://github.com/About-Energy-OpenSource/About-Energy-BPX-Parameterisation/) or [BPX example repository](https://github.com/FaradayInstitution/bpx-example). +`my_params` will now be of type `BPX`, which acts like a python dataclass with the same attributes as the BPX format. To obatin example files, see the [A:E BPX Parameterisation repository](https://github.com/About-Energy-OpenSource/About-Energy-BPX-Parameterisation/) or [BPX example repository](https://github.com/pybamm-team/bpx-example). Attributes of the class can be printed out using the standard Python dot notation, for example, you can print out the initial temperature of the cell using ```python