From dc3a9c2a497c35a7b6b951a472f26f64153f4a42 Mon Sep 17 00:00:00 2001 From: Valentin Sulzer Date: Tue, 29 Nov 2022 23:01:37 -0500 Subject: [PATCH] #2418 integration tests --- examples/scripts/compare_lithium_ion.py | 6 +-- pybamm/models/standard_variables.py | 43 ------------------- .../current_collector/potential_pair.py | 12 ++++-- .../quite_conductive_potential_pair.py | 10 ++++- .../external_circuit/base_external_circuit.py | 10 +++-- .../interface/lithium_plating/plating.py | 2 + .../test_compare_outputs_two_phase.py | 29 +++++++------ .../test_binary_operators.py | 4 +- .../test_operations/test_jac.py | 4 +- tests/unit/test_solvers/test_idaklu_solver.py | 2 +- .../unit/test_solvers/test_scikits_solvers.py | 8 +++- 11 files changed, 57 insertions(+), 73 deletions(-) diff --git a/examples/scripts/compare_lithium_ion.py b/examples/scripts/compare_lithium_ion.py index e3f8c6d8cd..2a414b3548 100644 --- a/examples/scripts/compare_lithium_ion.py +++ b/examples/scripts/compare_lithium_ion.py @@ -6,9 +6,9 @@ pybamm.set_logging_level("INFO") # load models models = [ - pybamm.lithium_ion.SPM(), - pybamm.lithium_ion.SPMe(), - pybamm.lithium_ion.DFN(), + # pybamm.lithium_ion.SPM(), + # pybamm.lithium_ion.SPMe(), + pybamm.lithium_ion.DFN({"dimensionality": 1}), # pybamm.lithium_ion.DFN( # {"particle": "uniform profile"} # ), diff --git a/pybamm/models/standard_variables.py b/pybamm/models/standard_variables.py index 028465c221..345c8f6c5e 100644 --- a/pybamm/models/standard_variables.py +++ b/pybamm/models/standard_variables.py @@ -6,26 +6,6 @@ class StandardVariables: def __init__(self): - # Discharge capacity and energy - self.Q_Ah = pybamm.Variable("Discharge capacity [A.h]") - self.Q_Wh = pybamm.Variable("Discharge energy [W.h]") - - # Throughput capacity and energy (cumulative) - self.Qt_Ah = pybamm.Variable("Throughput capacity [A.h]") - self.Qt_Wh = pybamm.Variable("Throughput energy [W.h]") - - # Electrode potential - self.phi_s_n = pybamm.Variable( - "Negative electrode potential [V]", - domain="negative electrode", - auxiliary_domains={"secondary": "current collector"}, - ) - self.phi_s_p = pybamm.Variable( - "Positive electrode potential [V]", - domain="positive electrode", - auxiliary_domains={"secondary": "current collector"}, - ) - # Potential difference self.delta_phi_n = pybamm.Variable( "Negative electrode surface potential difference [V]", @@ -47,29 +27,6 @@ def __init__(self): domain="current collector", ) - # current collector variables - self.phi_s_cn = pybamm.Variable( - "Negative current collector potential [V]", domain="current collector" - ) - self.phi_s_cp = pybamm.Variable( - "Positive current collector potential [V]", domain="current collector" - ) - self.i_boundary_cc = pybamm.Variable( - "Current collector current density [A.m-2]", domain="current collector" - ) - self.phi_s_cn_composite = pybamm.Variable( - "Composite negative current collector potential [V]", - domain="current collector", - ) - self.phi_s_cp_composite = pybamm.Variable( - "Composite positive current collector potential [V]", - domain="current collector", - ) - self.i_boundary_cc_composite = pybamm.Variable( - "Composite current collector current density [A.m-2]", - domain="current collector", - ) - def __setattr__(self, name, value): value.print_name = name super().__setattr__(name, value) diff --git a/pybamm/models/submodels/current_collector/potential_pair.py b/pybamm/models/submodels/current_collector/potential_pair.py index 4326438a3d..b3abd7f20f 100644 --- a/pybamm/models/submodels/current_collector/potential_pair.py +++ b/pybamm/models/submodels/current_collector/potential_pair.py @@ -32,14 +32,20 @@ def __init__(self, param): pybamm.citations.register("Timms2021") def get_fundamental_variables(self): - - phi_s_cn = pybamm.standard_variables.phi_s_cn + param = self.param + phi_s_cn = pybamm.Variable( + "Negative current collector potential [V]", domain="current collector" + ) variables = self._get_standard_negative_potential_variables(phi_s_cn) # TODO: grad not implemented for 2D yet i_cc = pybamm.Scalar(0) - i_boundary_cc = pybamm.standard_variables.i_boundary_cc + i_boundary_cc = pybamm.Variable( + "Current collector current density [A.m-2]", + domain="current collector", + scale=param.Q / (param.A_cc * param.n_electrodes_parallel), + ) variables.update(self._get_standard_current_variables(i_cc, i_boundary_cc)) diff --git a/pybamm/models/submodels/current_collector/quite_conductive_potential_pair.py b/pybamm/models/submodels/current_collector/quite_conductive_potential_pair.py index d9689b1ec7..7e0fe3d905 100644 --- a/pybamm/models/submodels/current_collector/quite_conductive_potential_pair.py +++ b/pybamm/models/submodels/current_collector/quite_conductive_potential_pair.py @@ -28,13 +28,19 @@ def __init__(self, param): def get_fundamental_variables(self): - phi_s_cn = pybamm.standard_variables.phi_s_cn + phi_s_cn = pybamm.Variable( + "Negative current collector potential [V]", domain="current collector" + ) variables = self._get_standard_negative_potential_variables(phi_s_cn) # TODO: grad not implemented for 2D yet i_cc = pybamm.Scalar(0) - i_boundary_cc = pybamm.standard_variables.i_boundary_cc + i_boundary_cc = pybamm.Variable( + "Current collector current density [A.m-2]", + domain="current collector", + scale=param.Q / (param.A_cc * param.n_electrodes_parallel), + ) variables.update(self._get_standard_current_variables(i_cc, i_boundary_cc)) diff --git a/pybamm/models/submodels/external_circuit/base_external_circuit.py b/pybamm/models/submodels/external_circuit/base_external_circuit.py index 86ca8ecae2..d665c189ba 100644 --- a/pybamm/models/submodels/external_circuit/base_external_circuit.py +++ b/pybamm/models/submodels/external_circuit/base_external_circuit.py @@ -11,13 +11,15 @@ def __init__(self, param, options): super().__init__(param, options=options) def get_fundamental_variables(self): - Q_Ah = pybamm.standard_variables.Q_Ah + Q_Ah = pybamm.Variable("Discharge capacity [A.h]") variables = {"Discharge capacity [A.h]": Q_Ah} if self.options["calculate discharge energy"] == "true": - Q_Wh = pybamm.standard_variables.Q_Wh - Qt_Wh = pybamm.standard_variables.Qt_Wh - Qt_Ah = pybamm.standard_variables.Qt_Ah + Q_Wh = pybamm.Variable("Discharge energy [W.h]") + + # Throughput capacity and energy (cumulative) + Qt_Ah = pybamm.Variable("Throughput capacity [A.h]") + Qt_Wh = pybamm.Variable("Throughput energy [W.h]") variables.update( { "Discharge energy [W.h]": Q_Wh, diff --git a/pybamm/models/submodels/interface/lithium_plating/plating.py b/pybamm/models/submodels/interface/lithium_plating/plating.py index e860c241ad..321c450acf 100644 --- a/pybamm/models/submodels/interface/lithium_plating/plating.py +++ b/pybamm/models/submodels/interface/lithium_plating/plating.py @@ -41,6 +41,7 @@ def get_fundamental_variables(self): c_plated_Li_av = pybamm.Variable( "X-averaged lithium plating concentration [mol.m-3]", domain="current collector", + scale=self.param.c_plated_Li_0, ) c_plated_Li = pybamm.PrimaryBroadcast(c_plated_Li_av, "negative electrode") c_dead_Li_av = pybamm.Variable( @@ -53,6 +54,7 @@ def get_fundamental_variables(self): "Lithium plating concentration [mol.m-3]", domain="negative electrode", auxiliary_domains={"secondary": "current collector"}, + scale=self.param.c_plated_Li_0, ) c_dead_Li = pybamm.Variable( "Dead lithium concentration [mol.m-3]", diff --git a/tests/integration/test_models/test_full_battery_models/test_lithium_ion/test_compare_outputs_two_phase.py b/tests/integration/test_models/test_full_battery_models/test_lithium_ion/test_compare_outputs_two_phase.py index b395a5cf52..cda80d96dd 100644 --- a/tests/integration/test_models/test_full_battery_models/test_lithium_ion/test_compare_outputs_two_phase.py +++ b/tests/integration/test_models/test_full_battery_models/test_lithium_ion/test_compare_outputs_two_phase.py @@ -69,35 +69,38 @@ def compare_outputs_two_phase_graphite_graphite(self, model_class): # Compare two phase model to standard model for variable in [ "X-averaged negative electrode active material volume fraction", - "X-averaged negative electrode volumetric interfacial current density [A.m-3]", + "X-averaged negative electrode volumetric " + "interfacial current density [A.m-3]", "Terminal voltage [V]", ]: - np.testing.assert_array_almost_equal( - sol[variable].entries, sol_two_phase[variable].entries, decimal=2 + np.testing.assert_allclose( + sol[variable].entries, sol_two_phase[variable].entries, rtol=1e-2 ) # Compare each phase in the two-phase model - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( sol_two_phase[ "Negative primary particle concentration [mol.m-3]" ].entries, sol_two_phase[ "Negative secondary particle concentration [mol.m-3]" ].entries, - decimal=6, + rtol=1e-6, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( sol_two_phase[ - "Negative electrode primary volumetric interfacial current density [A.m-3]" + "Negative electrode primary volumetric " + "interfacial current density [A.m-3]" ].entries / x, sol_two_phase[ - "Negative electrode secondary volumetric interfacial current density [A.m-3]" + "Negative electrode secondary volumetric " + "interfacial current density [A.m-3]" ].entries / (1 - x), - decimal=6, + rtol=1e-6, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( sol_two_phase[ "Negative electrode primary active material volume fraction" ].entries @@ -106,7 +109,7 @@ def compare_outputs_two_phase_graphite_graphite(self, model_class): "Negative electrode secondary active material volume fraction" ].entries / (1 - x), - decimal=6, + rtol=1e-6, ) def test_compare_SPM_graphite_graphite(self): @@ -151,8 +154,8 @@ def compare_outputs_two_phase_silicon_graphite(self, model_class): "Average negative primary particle concentration", "Average negative secondary particle concentration", ]: - np.testing.assert_array_almost_equal( - sol1[var].data[:20], sol2[var].data[:20], decimal=2 + np.testing.assert_allclose( + sol1[var].data[:20], sol2[var].data[:20], rtol=1e-2 ) # More silicon means longer sim diff --git a/tests/unit/test_expression_tree/test_binary_operators.py b/tests/unit/test_expression_tree/test_binary_operators.py index 913a943e88..0ac8513180 100644 --- a/tests/unit/test_expression_tree/test_binary_operators.py +++ b/tests/unit/test_expression_tree/test_binary_operators.py @@ -237,7 +237,9 @@ def test_sparse_divide(self): def test_inner(self): model = pybamm.lithium_ion.BaseModel() - phi_s = pybamm.standard_variables.phi_s_n + phi_s = pybamm.Variable( + "Negative electrode potential [V]", domain="negative electrode" + ) i = pybamm.grad(phi_s) model.rhs = {phi_s: pybamm.inner(i, i)} diff --git a/tests/unit/test_expression_tree/test_operations/test_jac.py b/tests/unit/test_expression_tree/test_operations/test_jac.py index ef55ede42a..515a4eb4d8 100644 --- a/tests/unit/test_expression_tree/test_operations/test_jac.py +++ b/tests/unit/test_expression_tree/test_operations/test_jac.py @@ -283,7 +283,9 @@ def test_jac_of_binary_operator(self): a = pybamm.Symbol("a") b = pybamm.Symbol("b") - phi_s = pybamm.standard_variables.phi_s_n + phi_s = pybamm.Variable( + "Negative electrode potential [V]", domain="negative electrode" + ) i = pybamm.grad(phi_s) inner = pybamm.inner(2, i) diff --git a/tests/unit/test_solvers/test_idaklu_solver.py b/tests/unit/test_solvers/test_idaklu_solver.py index e7b33bea97..fb40d37324 100644 --- a/tests/unit/test_solvers/test_idaklu_solver.py +++ b/tests/unit/test_solvers/test_idaklu_solver.py @@ -341,7 +341,7 @@ def test_set_atol(self): disc.process_model(model) solver = pybamm.IDAKLUSolver() - variable_tols = {"Porosity times concentration [mol.m-3]": 1e-3} + variable_tols = {"Negative electrode potential [V]": 1e-3} solver.set_atol_by_variable(variable_tols, model) model = pybamm.BaseModel() diff --git a/tests/unit/test_solvers/test_scikits_solvers.py b/tests/unit/test_solvers/test_scikits_solvers.py index 3e3b48cb4b..6456794f18 100644 --- a/tests/unit/test_solvers/test_scikits_solvers.py +++ b/tests/unit/test_solvers/test_scikits_solvers.py @@ -886,8 +886,12 @@ def nonsmooth_rate(t): dindex = np.searchsorted(solution.t, discontinuity) value_before = solution.t[dindex - 1] value_after = solution.t[dindex] - self.assertEqual(value_before + sys.float_info.epsilon, discontinuity) - self.assertEqual(value_after - sys.float_info.epsilon, discontinuity) + self.assertEqual( + value_before / (1 - sys.float_info.epsilon), discontinuity + ) + self.assertEqual( + value_after / (1 + sys.float_info.epsilon), discontinuity + ) # both solution time vectors should have same number of points self.assertEqual(len(solution1.t), len(solution2.t))