class TestLeadAcidFullSideReactions(unittest.TestCase): @unittest.skipIf(pybamm.have_scikits_odes(), "scikits.odes not installed") def test_basic_processing(self): options = {"side reactions": ["oxygen"]} model = pybamm.lead_acid.Full(options) modeltest = tests.StandardModelTest(model) modeltest.test_all(skip_output_tests=True, t_eval=np.linspace(0, 0.6)) def test_basic_processing_differential(self): options = {"side reactions": ["oxygen"], "surface form": "differential"} model = pybamm.lead_acid.Full(options) modeltest = tests.StandardModelTest(model) modeltest.test_all(skip_output_tests=True) @unittest.skipIf(pybamm.have_scikits_odes(), "scikits.odes not installed") def test_basic_processing_algebraic(self): options = {"side reactions": ["oxygen"], "surface form": "algebraic"} model = pybamm.lead_acid.Full(options) modeltest = tests.StandardModelTest(model) modeltest.test_all(skip_output_tests=True) def test_basic_processing_charge(self): options = {"side reactions": ["oxygen"], "surface form": "differential"} model = pybamm.lead_acid.Full(options) parameter_values = model.default_parameter_values parameter_values.update( {"Typical current [A]": -1, "Initial State of Charge": 0.5} ) modeltest = tests.StandardModelTest(model, parameter_values=parameter_values) modeltest.test_all(skip_output_tests=True) def test_basic_processing_zero_current(self): options = {"side reactions": ["oxygen"], "surface form": "differential"} model = pybamm.lead_acid.Full(options) parameter_values = model.default_parameter_values parameter_values.update( {"Current function": pybamm.GetConstantCurrent(current=0)} ) modeltest = tests.StandardModelTest(model, parameter_values=parameter_values) modeltest.test_all(skip_output_tests=True) def test_optimisations(self): options = {"side reactions": ["oxygen"], "surface form": "differential"} model = pybamm.lead_acid.Full(options) optimtest = tests.OptimisationsTest(model) original = optimtest.evaluate_model() simplified = optimtest.evaluate_model(simplify=True) using_known_evals = optimtest.evaluate_model(use_known_evals=True) simp_and_known = optimtest.evaluate_model(simplify=True, use_known_evals=True) np.testing.assert_array_almost_equal(original, simplified, decimal=5) np.testing.assert_array_almost_equal(original, using_known_evals) np.testing.assert_array_almost_equal(original, simp_and_known, decimal=5)
def test_solver_citations(self): # Test that solving each solver adds the right citations citations = pybamm.citations citations._reset() self.assertNotIn("virtanen2020scipy", citations._papers_to_cite) pybamm.ScipySolver() self.assertIn("virtanen2020scipy", citations._papers_to_cite) citations._reset() self.assertNotIn("virtanen2020scipy", citations._papers_to_cite) pybamm.AlgebraicSolver() self.assertIn("virtanen2020scipy", citations._papers_to_cite) if pybamm.have_scikits_odes(): citations._reset() self.assertNotIn("scikits-odes", citations._papers_to_cite) pybamm.ScikitsOdeSolver() self.assertIn("scikits-odes", citations._papers_to_cite) citations._reset() self.assertNotIn("scikits-odes", citations._papers_to_cite) pybamm.ScikitsDaeSolver() self.assertIn("scikits-odes", citations._papers_to_cite) if pybamm.have_idaklu(): citations._reset() self.assertNotIn("hindmarsh2005sundials", citations._papers_to_cite) pybamm.IDAKLUSolver() self.assertIn("hindmarsh2005sundials", citations._papers_to_cite)
class TestLeadAcidFOQSSurfaceForm(unittest.TestCase): def test_basic_processing_differential(self): options = { "surface form": "differential", "thermal": "isothermal", "convection": False, } model = pybamm.lead_acid.FOQS(options) param = model.default_parameter_values param.update({"Typical current [A]": 1}) modeltest = tests.StandardModelTest(model, parameter_values=param) modeltest.test_all() @unittest.skipIf(pybamm.have_scikits_odes(), "scikits.odes not installed") def test_basic_processing_algebraic(self): options = { "surface form": "algebraic", "thermal": "isothermal", "convection": False, } model = pybamm.lead_acid.FOQS(options) param = model.default_parameter_values param.update({"Typical current [A]": 1}) modeltest = tests.StandardModelTest(model, parameter_values=param) modeltest.test_all() def test_optimisations(self): options = { "surface form": "differential", "thermal": "isothermal", "convection": False, } model = pybamm.lead_acid.FOQS(options) optimtest = tests.OptimisationsTest(model) original = optimtest.evaluate_model() simplified = optimtest.evaluate_model(simplify=True) using_known_evals = optimtest.evaluate_model(use_known_evals=True) simp_and_known = optimtest.evaluate_model(simplify=True, use_known_evals=True) simp_and_python = optimtest.evaluate_model(simplify=True, to_python=True) np.testing.assert_array_almost_equal(original, simplified) np.testing.assert_array_almost_equal(original, using_known_evals) np.testing.assert_array_almost_equal(original, simp_and_known) np.testing.assert_array_almost_equal(original, simp_and_python) def test_set_up(self): options = { "surface form": "differential", "thermal": "isothermal", "convection": False, } model = pybamm.lead_acid.FOQS(options) optimtest = tests.OptimisationsTest(model) optimtest.set_up_model(simplify=False, to_python=True) optimtest.set_up_model(simplify=True, to_python=True) optimtest.set_up_model(simplify=False, to_python=False) optimtest.set_up_model(simplify=True, to_python=False)
class TestLeadAcidFull(unittest.TestCase): @unittest.skipIf(pybamm.have_scikits_odes(), "scikits.odes not installed") def test_basic_processing(self): options = {"thermal": "isothermal"} model = pybamm.lead_acid.Full(options) modeltest = tests.StandardModelTest(model) modeltest.test_all(t_eval=np.linspace(0, 0.6)) @unittest.skipIf(pybamm.have_scikits_odes(), "scikits.odes not installed") def test_basic_processing_with_convection(self): options = {"thermal": "isothermal", "convection": True} model = pybamm.lead_acid.Full(options) var = pybamm.standard_spatial_vars var_pts = {var.x_n: 10, var.x_s: 10, var.x_p: 10} modeltest = tests.StandardModelTest(model, var_pts=var_pts) modeltest.test_all(t_eval=np.linspace(0, 0.6)) def test_optimisations(self): options = {"thermal": "isothermal"} model = pybamm.lead_acid.Full(options) optimtest = tests.OptimisationsTest(model) original = optimtest.evaluate_model() simplified = optimtest.evaluate_model(simplify=True) using_known_evals = optimtest.evaluate_model(use_known_evals=True) simp_and_known = optimtest.evaluate_model(simplify=True, use_known_evals=True) simp_and_python = optimtest.evaluate_model(simplify=True, to_python=True) np.testing.assert_array_almost_equal(original, simplified) np.testing.assert_array_almost_equal(original, using_known_evals) np.testing.assert_array_almost_equal(original, simp_and_known) np.testing.assert_array_almost_equal(original, simp_and_python) @unittest.skipIf(pybamm.have_scikits_odes(), "scikits.odes not installed") def test_set_up(self): options = {"thermal": "isothermal"} model = pybamm.lead_acid.Full(options) optimtest = tests.OptimisationsTest(model) optimtest.set_up_model(simplify=False, to_python=True) optimtest.set_up_model(simplify=True, to_python=True) optimtest.set_up_model(simplify=False, to_python=False) optimtest.set_up_model(simplify=True, to_python=False)
def default_solver(self): """ Return default solver based on whether model is ODE model or DAE model. There are bugs with KLU on the lead-acid models. """ if len(self.algebraic) == 0: return pybamm.ScipySolver() elif pybamm.have_scikits_odes(): return pybamm.ScikitsDaeSolver() else: # pragma: no cover return pybamm.CasadiSolver(mode="safe")
class TestLeadAcidFullSurfaceForm(unittest.TestCase): def test_basic_processing_differential(self): options = {"surface form": "differential"} model = pybamm.lead_acid.Full(options) modeltest = tests.StandardModelTest(model) modeltest.test_all() @unittest.skipIf(pybamm.have_scikits_odes(), "scikits.odes not installed") def test_basic_processing_algebraic(self): options = {"surface form": "algebraic"} model = pybamm.lead_acid.Full(options) modeltest = tests.StandardModelTest(model) modeltest.test_all() def test_optimisations(self): options = {"surface form": "differential"} model = pybamm.lead_acid.Full(options) optimtest = tests.OptimisationsTest(model) original = optimtest.evaluate_model() simplified = optimtest.evaluate_model(simplify=True) using_known_evals = optimtest.evaluate_model(use_known_evals=True) simp_and_known = optimtest.evaluate_model(simplify=True, use_known_evals=True) np.testing.assert_array_almost_equal(original, simplified, decimal=5) np.testing.assert_array_almost_equal(original, using_known_evals) np.testing.assert_array_almost_equal(original, simp_and_known, decimal=5) @unittest.skipIf(pybamm.have_scikits_odes(), "scikits.odes not installed") def test_set_up(self): options = {"surface form": "differential"} model = pybamm.lead_acid.Full(options) optimtest = tests.OptimisationsTest(model) optimtest.set_up_model(simplify=False, to_python=True) optimtest.set_up_model(simplify=True, to_python=True) optimtest.set_up_model(simplify=False, to_python=False) optimtest.set_up_model(simplify=True, to_python=False)
class TestLeadAcidFull(unittest.TestCase): def test_well_posed(self): model = pybamm.lead_acid.Full() model.check_well_posedness() def test_well_posed_with_convection(self): options = {"thermal": "isothermal", "convection": True} model = pybamm.lead_acid.Full(options) model.check_well_posedness() @unittest.skipIf(pybamm.have_scikits_odes(), "scikits.odes not installed") def test_default_solver(self): model = pybamm.lead_acid.Full() self.assertIsInstance(model.default_solver, pybamm.ScikitsDaeSolver)
class TestLeadAcidLOQSSurfaceForm(unittest.TestCase): def test_well_posed_differential(self): options = {"surface form": "differential"} model = pybamm.lead_acid.LOQS(options) model.check_well_posedness() def test_well_posed_algebraic(self): options = {"surface form": "algebraic"} model = pybamm.lead_acid.LOQS(options) model.check_well_posedness() def test_well_posed_1plus1D(self): options = { "surface form": "differential", "current collector": "potential pair", "dimensionality": 1, } model = pybamm.lead_acid.LOQS(options) model.check_well_posedness() @unittest.skipIf(pybamm.have_scikits_odes(), "scikits.odes not installed") def test_default_solver(self): options = {"surface form": "differential"} model = pybamm.lead_acid.LOQS(options) self.assertIsInstance(model.default_solver, pybamm.ScipySolver) options = { "surface form": "differential", "current collector": "potential pair", "dimensionality": 1, } model = pybamm.lead_acid.LOQS(options) self.assertIsInstance(model.default_solver, pybamm.ScikitsDaeSolver) options = {"surface form": "algebraic"} model = pybamm.lead_acid.LOQS(options) self.assertIsInstance(model.default_solver, pybamm.ScikitsDaeSolver) def test_default_geometry(self): options = {"surface form": "differential"} model = pybamm.lead_acid.LOQS(options) self.assertIn("current collector", model.default_geometry) options.update({"current collector": "potential pair", "dimensionality": 1}) model = pybamm.lead_acid.LOQS(options) self.assertIn("current collector", model.default_geometry)
class TestLeadAcidFullSurfaceForm(unittest.TestCase): def test_well_posed_differential(self): options = {"surface form": "differential"} model = pybamm.lead_acid.Full(options) model.check_well_posedness() def test_well_posed_differential_1plus1d(self): options = {"surface form": "differential", "dimensionality": 1} model = pybamm.lead_acid.Full(options) model.check_well_posedness() def test_well_posed_algebraic(self): options = {"surface form": "algebraic"} model = pybamm.lead_acid.Full(options) model.check_well_posedness() @unittest.skipIf(pybamm.have_scikits_odes(), "scikits.odes not installed") def test_default_solver(self): options = {"surface form": "differential"} model = pybamm.lead_acid.Full(options) self.assertIsInstance(model.default_solver, pybamm.ScipySolver) options = {"surface form": "algebraic"} model = pybamm.lead_acid.Full(options) self.assertIsInstance(model.default_solver, pybamm.ScikitsDaeSolver)
class TestAsymptoticConvergence(unittest.TestCase): @unittest.skipIf(pybamm.have_scikits_odes(), "scikits.odes not installed") def test_leading_order_convergence(self): """ Check that the leading-order model solution converges linearly in C_e to the full model solution """ # Create models leading_order_model = pybamm.lead_acid.LOQS() composite_model = pybamm.lead_acid.Composite() full_model = pybamm.lead_acid.Full() # Same parameters, same geometry parameter_values = full_model.default_parameter_values parameter_values.process_model(leading_order_model) parameter_values.process_model(composite_model) parameter_values.process_model(full_model) geometry = full_model.default_geometry parameter_values.process_geometry(geometry) # Discretise (same mesh, create different discretisations) var = pybamm.standard_spatial_vars var_pts = {var.x_n: 3, var.x_s: 3, var.x_p: 3} mesh = pybamm.Mesh(geometry, full_model.default_submesh_types, var_pts) loqs_disc = pybamm.Discretisation(mesh, full_model.default_spatial_methods) loqs_disc.process_model(leading_order_model) comp_disc = pybamm.Discretisation(mesh, full_model.default_spatial_methods) comp_disc.process_model(composite_model) full_disc = pybamm.Discretisation(mesh, full_model.default_spatial_methods) full_disc.process_model(full_model) def get_max_error(current): pybamm.logger.info("current = {}".format(current)) # Update current (and hence C_e) in the parameters param = pybamm.ParameterValues( chemistry=pybamm.parameter_sets.Sulzer2019) param.update({"Typical current [A]": current}) param.update_model(leading_order_model, loqs_disc) param.update_model(composite_model, comp_disc) param.update_model(full_model, full_disc) # Solve, make sure times are the same and use tight tolerances t_eval = np.linspace(0, 0.6) solver_loqs = leading_order_model.default_solver solver_loqs.rtol = 1e-8 solver_loqs.atol = 1e-8 solution_loqs = solver_loqs.solve(leading_order_model, t_eval) solver_comp = composite_model.default_solver solver_comp.rtol = 1e-8 solver_comp.atol = 1e-8 solution_comp = solver_comp.solve(composite_model, t_eval) solver_full = full_model.default_solver solver_full.rtol = 1e-8 solver_full.atol = 1e-8 solution_full = solver_full.solve(full_model, t_eval) # Post-process variables t_loqs, y_loqs = solution_loqs.t, solution_loqs.y t_comp, y_comp = solution_comp.t, solution_comp.y t_full, y_full = solution_full.t, solution_full.y voltage_loqs = pybamm.ProcessedVariable( leading_order_model.variables["Terminal voltage"], t_loqs, y_loqs, loqs_disc.mesh, ) voltage_comp = pybamm.ProcessedVariable( composite_model.variables["Terminal voltage"], t_comp, y_comp, comp_disc.mesh, ) voltage_full = pybamm.ProcessedVariable( full_model.variables["Terminal voltage"], t_full, y_full, full_disc.mesh) # Compare t = t_full[:np.min([len(t_loqs), len(t_comp), len(t_full)])] loqs_error = np.max(np.abs(voltage_loqs(t) - voltage_full(t))) comp_error = np.max(np.abs(voltage_comp(t) - voltage_full(t))) return (loqs_error, comp_error) # Get errors currents = 0.5 / (2**np.arange(3)) errs = np.array([get_max_error(current) for current in currents]) loqs_errs, comp_errs = [np.array(err) for err in zip(*errs)] # Get rates: expect linear convergence for loqs, quadratic for composite loqs_rates = np.log2(loqs_errs[:-1] / loqs_errs[1:]) np.testing.assert_array_less(0.99 * np.ones_like(loqs_rates), loqs_rates) # Composite not converging as expected comp_rates = np.log2(comp_errs[:-1] / comp_errs[1:]) np.testing.assert_array_less(0.99 * np.ones_like(comp_rates), comp_rates) # Check composite more accurate than loqs np.testing.assert_array_less(comp_errs, loqs_errs)
# # Tests for the Scikits Solver classes # import pybamm import numpy as np import unittest import warnings from tests import get_mesh_for_testing, get_discretisation_for_testing import sys @unittest.skipIf(not pybamm.have_scikits_odes(), "scikits.odes not installed") class TestScikitsSolvers(unittest.TestCase): def test_init(self): # linsolver deprecated with self.assertRaisesRegex(ValueError, "linsolver has been deprecated"): pybamm.ScikitsOdeSolver(linsolver="lapackdense") def test_model_ode_integrate_failure(self): # Turn off warnings to ignore sqrt error warnings.simplefilter("ignore") model = pybamm.BaseModel() var = pybamm.Variable("var") model.rhs = {var: -pybamm.sqrt(var)} model.initial_conditions = {var: 1} disc = pybamm.Discretisation() disc.process_model(model) t_eval = np.linspace(0, 3, 100)
class TestSPM(unittest.TestCase): def test_basic_processing(self): options = {"thermal": "isothermal"} model = pybamm.lithium_ion.SPM(options) modeltest = tests.StandardModelTest(model) modeltest.test_all() @unittest.skipIf(pybamm.have_scikits_odes(), "scikits.odes not installed") def test_basic_processing_1plus1D(self): options = {"current collector": "potential pair", "dimensionality": 1} model = pybamm.lithium_ion.SPM(options) var = pybamm.standard_spatial_vars var_pts = { var.x_n: 5, var.x_s: 5, var.x_p: 5, var.r_n: 5, var.r_p: 5, var.y: 5, var.z: 5, } modeltest = tests.StandardModelTest(model, var_pts=var_pts) modeltest.test_all(skip_output_tests=True) @unittest.skipIf(pybamm.have_scikits_odes(), "scikits.odes not installed") def test_basic_processing_2plus1D(self): options = {"current collector": "potential pair", "dimensionality": 2} model = pybamm.lithium_ion.SPM(options) var = pybamm.standard_spatial_vars var_pts = { var.x_n: 5, var.x_s: 5, var.x_p: 5, var.r_n: 5, var.r_p: 5, var.y: 5, var.z: 5, } modeltest = tests.StandardModelTest(model, var_pts=var_pts) modeltest.test_all(skip_output_tests=True) def test_optimisations(self): options = {"thermal": "isothermal"} model = pybamm.lithium_ion.SPM(options) optimtest = tests.OptimisationsTest(model) original = optimtest.evaluate_model() simplified = optimtest.evaluate_model(simplify=True) using_known_evals = optimtest.evaluate_model(use_known_evals=True) simp_and_known = optimtest.evaluate_model(simplify=True, use_known_evals=True) simp_and_python = optimtest.evaluate_model(simplify=True, to_python=True) np.testing.assert_array_almost_equal(original, simplified) np.testing.assert_array_almost_equal(original, using_known_evals) np.testing.assert_array_almost_equal(original, simp_and_known) np.testing.assert_array_almost_equal(original, simp_and_python) def test_set_up(self): model = pybamm.lithium_ion.SPM() optimtest = tests.OptimisationsTest(model) optimtest.set_up_model(simplify=False, to_python=True) optimtest.set_up_model(simplify=True, to_python=True) optimtest.set_up_model(simplify=False, to_python=False) optimtest.set_up_model(simplify=True, to_python=False) def test_charge(self): options = {"thermal": "isothermal"} model = pybamm.lithium_ion.SPM(options) parameter_values = model.default_parameter_values parameter_values.update({"Typical current [A]": -1}) modeltest = tests.StandardModelTest(model, parameter_values=parameter_values) modeltest.test_all() def test_zero_current(self): options = {"thermal": "isothermal"} model = pybamm.lithium_ion.SPM(options) parameter_values = model.default_parameter_values parameter_values.update( {"Current function": pybamm.GetConstantCurrent(current=0)}) modeltest = tests.StandardModelTest(model, parameter_values=parameter_values) modeltest.test_all() def test_thermal(self): options = {"thermal": "x-lumped"} model = pybamm.lithium_ion.SPM(options) modeltest = tests.StandardModelTest(model) modeltest.test_all() options = {"thermal": "x-full"} model = pybamm.lithium_ion.SPM(options) modeltest = tests.StandardModelTest(model) modeltest.test_all() def test_particle_fast_diffusion(self): options = {"particle": "fast diffusion"} model = pybamm.lithium_ion.SPM(options) modeltest = tests.StandardModelTest(model) modeltest.test_all()
class TestQuickPlot(unittest.TestCase): """ Tests that QuickPlot is created correctly """ @unittest.skipIf(pybamm.have_scikits_odes(), "scikits.odes not installed") def test_plot_lithium_ion(self): spm = pybamm.lithium_ion.SPM() spme = pybamm.lithium_ion.SPMe() geometry = spm.default_geometry param = spm.default_parameter_values param.process_model(spm) param.process_model(spme) param.process_geometry(geometry) mesh = pybamm.Mesh(geometry, spme.default_submesh_types, spme.default_var_pts) disc_spm = pybamm.Discretisation(mesh, spm.default_spatial_methods) disc_spme = pybamm.Discretisation(mesh, spme.default_spatial_methods) disc_spm.process_model(spm) disc_spme.process_model(spme) t_eval = np.linspace(0, 2, 100) solution_spm = spm.default_solver.solve(spm, t_eval) solution_spme = spme.default_solver.solve(spme, t_eval) quick_plot = pybamm.QuickPlot([spm, spme], mesh, [solution_spm, solution_spme]) quick_plot.plot(0) # update the axis new_axis = [0, 0.5, 0, 1] quick_plot.axis.update({("Electrolyte concentration",): new_axis}) self.assertEqual(quick_plot.axis[("Electrolyte concentration",)], new_axis) # and now reset them quick_plot.reset_axis() self.assertNotEqual(quick_plot.axis[("Electrolyte concentration",)], new_axis) # check dynamic plot loads quick_plot.dynamic_plot(testing=True) quick_plot.update(0.01) # Update parameters, solve, plot again param.update({"Current function": pybamm.GetConstantCurrent(current=0)}) param.update_model(spm, disc_spm) solution_spm = spm.default_solver.solve(spm, t_eval) quick_plot = pybamm.QuickPlot(spm, mesh, solution_spm) quick_plot.plot(0) # Test with different output variables output_vars = [ "Negative particle surface concentration", "Electrolyte concentration", "Positive particle surface concentration", ] quick_plot = pybamm.QuickPlot(spm, mesh, solution_spm, output_vars) self.assertEqual(len(quick_plot.axis), 3) quick_plot.plot(0) # update the axis new_axis = [0, 0.5, 0, 1] quick_plot.axis.update({("Electrolyte concentration",): new_axis}) self.assertEqual(quick_plot.axis[("Electrolyte concentration",)], new_axis) # and now reset them quick_plot.reset_axis() self.assertNotEqual(quick_plot.axis[("Electrolyte concentration",)], new_axis) # check dynamic plot loads quick_plot.dynamic_plot(testing=True) quick_plot.update(0.01) @unittest.skipIf(pybamm.have_scikits_odes(), "scikits.odes not installed") def test_plot_lead_acid(self): loqs = pybamm.lead_acid.LOQS() geometry = loqs.default_geometry param = loqs.default_parameter_values param.process_model(loqs) param.process_geometry(geometry) mesh = pybamm.Mesh(geometry, loqs.default_submesh_types, loqs.default_var_pts) disc_loqs = pybamm.Discretisation(mesh, loqs.default_spatial_methods) disc_loqs.process_model(loqs) t_eval = np.linspace(0, 1, 100) solution_loqs = loqs.default_solver.solve(loqs, t_eval) pybamm.QuickPlot(loqs, mesh, solution_loqs)
# solve model t_eval = np.linspace(0, 3600, 100) casadi_sol = pybamm.CasadiSolver(atol=1e-8, rtol=1e-8).solve(model, t_eval) solutions = [casadi_sol] if pybamm.have_idaklu(): klu_sol = pybamm.IDAKLUSolver(atol=1e-8, rtol=1e-8).solve(model, t_eval) solutions.append(klu_sol) else: pybamm.logger.error( """ Cannot solve model with IDA KLU solver as solver is not installed. Please consult installation instructions on GitHub. """ ) if pybamm.have_scikits_odes(): scikits_sol = pybamm.ScikitsDaeSolver(atol=1e-8, rtol=1e-8).solve(model, t_eval) solutions.append(scikits_sol) else: pybamm.logger.error( """ Cannot solve model with Scikits DAE solver as solver is not installed. Please consult installation instructions on GitHub. """ ) # plot plot = pybamm.QuickPlot(solutions) plot.dynamic_plot()
class TestSPMe(unittest.TestCase): def test_well_posed(self): options = {"thermal": "isothermal"} model = pybamm.lithium_ion.SPMe(options) model.check_well_posedness() def test_default_geometry(self): options = {"thermal": "isothermal"} model = pybamm.lithium_ion.SPMe(options) self.assertIsInstance(model.default_geometry, pybamm.Geometry) self.assertTrue("negative particle" in model.default_geometry) options = {"current collector": "potential pair", "dimensionality": 1} model = pybamm.lithium_ion.SPMe(options) self.assertIn("current collector", model.default_geometry) options = {"current collector": "potential pair", "dimensionality": 2} model = pybamm.lithium_ion.SPMe(options) self.assertIn("current collector", model.default_geometry) def test_well_posed_2plus1D(self): options = {"current collector": "potential pair", "dimensionality": 1} model = pybamm.lithium_ion.SPMe(options) model.check_well_posedness() options = {"current collector": "potential pair", "dimensionality": 2} model = pybamm.lithium_ion.SPMe(options) model.check_well_posedness() options = { "current collector": "single particle potential pair", "dimensionality": 2, } model = pybamm.lithium_ion.SPMe(options) model.check_well_posedness() options = {"bc_options": {"dimensionality": 5}} with self.assertRaises(pybamm.OptionError): model = pybamm.lithium_ion.SPMe(options) def test_x_full_thermal_model_no_current_collector(self): options = {"thermal": "x-full"} model = pybamm.lithium_ion.SPMe(options) model.check_well_posedness() # Not implemented with current collectors options = {"thermal": "x-full", "thermal current collector": True} with self.assertRaises(NotImplementedError): model = pybamm.lithium_ion.SPMe(options) @unittest.skipIf(pybamm.have_scikits_odes(), "scikits.odes not installed") def test_x_full_Nplus1D_not_implemented(self): # 1plus1D options = { "current collector": "potential pair", "dimensionality": 1, "thermal": "x-full", } with self.assertRaises(NotImplementedError): pybamm.lithium_ion.SPMe(options) # 2plus1D options = { "current collector": "potential pair", "dimensionality": 2, "thermal": "x-full", } with self.assertRaises(NotImplementedError): pybamm.lithium_ion.SPMe(options) def test_x_lumped_thermal_model_no_Current_collector(self): options = {"thermal": "x-lumped"} model = pybamm.lithium_ion.SPMe(options) model.check_well_posedness() # xyz-lumped returns the same as x-lumped options = {"thermal": "xyz-lumped"} model = pybamm.lithium_ion.SPMe(options) model.check_well_posedness() def test_x_lumped_thermal_model_0D_current_collector(self): options = {"thermal": "x-lumped", "thermal current collector": True} model = pybamm.lithium_ion.SPMe(options) model.check_well_posedness() # xyz-lumped returns the same as x-lumped options = {"thermal": "xyz-lumped", "thermal current collector": True} model = pybamm.lithium_ion.SPMe(options) model.check_well_posedness() options = {"thermal": "lumped"} model = pybamm.lithium_ion.SPMe(options) model.check_well_posedness() @unittest.skipIf(pybamm.have_scikits_odes(), "scikits.odes not installed") def test_xyz_lumped_thermal_1D_current_collector(self): options = { "current collector": "potential pair", "dimensionality": 1, "thermal": "xyz-lumped", } model = pybamm.lithium_ion.SPMe(options) model.check_well_posedness() options = { "current collector": "potential pair", "dimensionality": 1, "thermal": "lumped", } model = pybamm.lithium_ion.SPMe(options) model.check_well_posedness() @unittest.skipIf(pybamm.have_scikits_odes(), "scikits.odes not installed") def test_xyz_lumped_thermal_2D_current_collector(self): options = { "current collector": "potential pair", "dimensionality": 2, "thermal": "xyz-lumped", } model = pybamm.lithium_ion.SPMe(options) model.check_well_posedness() @unittest.skipIf(pybamm.have_scikits_odes(), "scikits.odes not installed") def test_x_lumped_thermal_1D_current_collector(self): options = { "current collector": "potential pair", "dimensionality": 1, "thermal": "x-lumped", } model = pybamm.lithium_ion.SPMe(options) model.check_well_posedness() options = { "current collector": "potential pair", "dimensionality": 2, "thermal": "lumped", } model = pybamm.lithium_ion.SPMe(options) model.check_well_posedness() @unittest.skipIf(pybamm.have_scikits_odes(), "scikits.odes not installed") def test_x_lumped_thermal_2D_current_collector(self): options = { "current collector": "potential pair", "dimensionality": 2, "thermal": "x-lumped", } model = pybamm.lithium_ion.SPMe(options) model.check_well_posedness() @unittest.skipIf(pybamm.have_scikits_odes(), "scikits.odes not installed") def test_default_solver(self): options = {"thermal": "isothermal"} model = pybamm.lithium_ion.SPMe(options) self.assertIsInstance(model.default_solver, pybamm.ScipySolver) options = {"current collector": "potential pair", "dimensionality": 2} model = pybamm.lithium_ion.SPMe(options) self.assertIsInstance(model.default_solver, pybamm.ScikitsDaeSolver) def test_particle_fast_diffusion(self): options = {"particle": "fast diffusion"} model = pybamm.lithium_ion.SPMe(options) model.check_well_posedness()