Esempio n. 1
0
    def test_compare_full(self):
        basic_full = pybamm.lead_acid.BasicFull()
        full = pybamm.lead_acid.Full({"convection": "uniform transverse"})

        parameter_values = pybamm.ParameterValues(
            chemistry=pybamm.parameter_sets.Sulzer2019
        )
        parameter_values["Current function [A]"] = 10

        # Solve basic Full mode
        basic_sim = pybamm.Simulation(
            basic_full, solver=pybamm.CasadiSolver(), parameter_values=parameter_values
        )
        t_eval = np.linspace(0, 400)
        basic_sim.solve(t_eval)
        basic_sol = basic_sim.solution

        # Solve main Full model
        sim = pybamm.Simulation(
            full, solver=pybamm.CasadiSolver(), parameter_values=parameter_values
        )
        t_eval = np.linspace(0, 400)
        sim.solve(t_eval)
        sol = sim.solution

        # Compare solution data
        # np.testing.assert_array_almost_equal(basic_sol.y, sol.y, decimal=4)
        np.testing.assert_array_almost_equal(basic_sol.t, sol.t, decimal=4)
        # Compare variables
        for name in basic_full.variables:
            np.testing.assert_array_almost_equal(
                basic_sol[name].entries, sol[name].entries, decimal=4
            )
Esempio n. 2
0
    def test_solve(self):

        sim = pybamm.Simulation(pybamm.lithium_ion.SPM())
        sim.solve([0, 600])
        self.assertFalse(sim._solution is None)
        for val in list(sim.built_model.rhs.values()):
            self.assertFalse(val.has_symbol_of_classes(pybamm.Parameter))
            # skip test for scalar variables (e.g. discharge capacity)
            if val.size > 1:
                self.assertTrue(val.has_symbol_of_classes(pybamm.Matrix))

        # test solve without check
        sim = pybamm.Simulation(pybamm.lithium_ion.SPM())
        sol = sim.solve(t_eval=[0, 600], check_model=False)
        for val in list(sim.built_model.rhs.values()):
            self.assertFalse(val.has_symbol_of_classes(pybamm.Parameter))
            # skip test for scalar variables (e.g. discharge capacity)
            if val.size > 1:
                self.assertTrue(val.has_symbol_of_classes(pybamm.Matrix))

        # Test options that are only available when simulating an experiment
        with self.assertRaisesRegex(ValueError, "save_at_cycles"):
            sim.solve(save_at_cycles=2)
        with self.assertRaisesRegex(ValueError, "starting_solution"):
            sim.solve(starting_solution=sol)
Esempio n. 3
0
 def test_model_with_inputs(self):
     chemistry = pybamm.parameter_sets.Chen2020
     parameter_values = pybamm.ParameterValues(chemistry=chemistry)
     model = pybamm.lithium_ion.SPMe()
     parameter_values.update({"Electrode height [m]": "[input]"})
     solver = pybamm.CasadiSolver(mode="safe")
     sim1 = pybamm.Simulation(model,
                              parameter_values=parameter_values,
                              solver=solver)
     inputs1 = {"Electrode height [m]": 1.00}
     sol1 = sim1.solve(t_eval=np.linspace(0, 1000, 101), inputs=inputs1)
     sim2 = pybamm.Simulation(model,
                              parameter_values=parameter_values,
                              solver=solver)
     inputs2 = {"Electrode height [m]": 2.00}
     sol2 = sim2.solve(t_eval=np.linspace(0, 1000, 101), inputs=inputs2)
     output_variables = [
         "Terminal voltage [V]",
         "Current [A]",
         "Negative electrode potential [V]",
         "Positive electrode potential [V]",
         "Electrolyte potential [V]",
         "Electrolyte concentration",
         "Negative particle surface concentration",
         "Positive particle surface concentration",
     ]
     quick_plot = pybamm.QuickPlot(solutions=[sol1, sol2],
                                   output_variables=output_variables)
     quick_plot.dynamic_plot(testing=True)
     quick_plot.slider_update(1)
     pybamm.close_plots()
Esempio n. 4
0
    def test_save_load(self):
        model = pybamm.lead_acid.LOQS()
        model.use_jacobian = True
        sim = pybamm.Simulation(model)

        sim.save("test.pickle")
        sim_load = pybamm.load_sim("test.pickle")
        self.assertEqual(sim.model.name, sim_load.model.name)

        # save after solving
        sim.solve([0, 600])
        sim.save("test.pickle")
        sim_load = pybamm.load_sim("test.pickle")
        self.assertEqual(sim.model.name, sim_load.model.name)

        # with python formats
        model.convert_to_format = None
        sim = pybamm.Simulation(model)
        sim.solve([0, 600])
        sim.save("test.pickle")
        model.convert_to_format = "python"
        sim = pybamm.Simulation(model)
        sim.solve([0, 600])
        with self.assertRaisesRegex(
                NotImplementedError,
                "Cannot save simulation if model format is python"):
            sim.save("test.pickle")
Esempio n. 5
0
 def time_setup_SPMe_simulation(self, with_experiment):
     self.model = pybamm.lithium_ion.SPMe()
     if with_experiment:
         exp = pybamm.Experiment([
             "Discharge at 0.1C until 3.105 V",
         ])
         pybamm.Simulation(self.model,
                           parameter_values=self.param,
                           experiment=exp)
     else:
         pybamm.Simulation(self.model,
                           parameter_values=self.param,
                           C_rate=1)
Esempio n. 6
0
    def test_set_defaults2(self):
        model = pybamm.lithium_ion.SPM()

        # make simulation with silly options (should this be allowed?)
        sim = pybamm.Simulation(
            model,
            geometry={},
            parameter_values={},
            submesh_types={},
            var_pts={},
            spatial_methods={},
            solver={},
            quick_plot_vars=[],
        )

        # reset and check
        sim.set_defaults()
        # Not sure of best way to test nested dicts?
        self.assertEqual(
            sim._parameter_values._dict_items,
            model.default_parameter_values._dict_items,
        )
        for domain, submesh in model.default_submesh_types.items():
            self.assertEqual(sim._submesh_types[domain].submesh_type,
                             submesh.submesh_type)
        self.assertEqual(sim._var_pts, model.default_var_pts)
        for domain, method in model.default_spatial_methods.items():
            self.assertIsInstance(sim._spatial_methods[domain], type(method))
        self.assertIsInstance(sim._solver, type(model.default_solver))
        self.assertEqual(sim._quick_plot_vars, None)
Esempio n. 7
0
 def test_solve_with_inputs(self):
     model = pybamm.lithium_ion.SPM()
     param = model.default_parameter_values
     param.update({"Current function [A]": "[input]"})
     sim = pybamm.Simulation(model, parameter_values=param)
     sim.solve(inputs={"Current function [A]": 1})
     np.testing.assert_array_equal(sim.solution.inputs["Current function [A]"], 1)
Esempio n. 8
0
    def test_step(self):

        dt = 0.001
        model = pybamm.lithium_ion.SPM()
        sim = pybamm.Simulation(model)

        sim.step(dt)  # 1 step stores first two points
        tau = sim.model.timescale.evaluate()
        self.assertEqual(sim.solution.t.size, 2)
        self.assertEqual(sim.solution.y.full()[0, :].size, 2)
        self.assertEqual(sim.solution.t[0], 0)
        self.assertEqual(sim.solution.t[1], dt / tau)
        saved_sol = sim.solution

        sim.step(dt)  # automatically append the next step
        self.assertEqual(sim.solution.t.size, 3)
        self.assertEqual(sim.solution.y.full()[0, :].size, 3)
        self.assertEqual(sim.solution.t[0], 0)
        self.assertEqual(sim.solution.t[1], dt / tau)
        self.assertEqual(sim.solution.t[2], 2 * dt / tau)

        sim.step(dt, save=False)  # now only store the two end step points
        self.assertEqual(sim.solution.t.size, 2)
        self.assertEqual(sim.solution.y.full()[0, :].size, 2)
        self.assertEqual(sim.solution.t[0], 2 * dt / tau)
        self.assertEqual(sim.solution.t[1], 3 * dt / tau)

        # Start from saved solution
        sim.step(dt, starting_solution=saved_sol
                 )  # now only store the two end step points
        self.assertEqual(sim.solution.t.size, 3)
        self.assertEqual(sim.solution.y.full()[0, :].size, 3)
        self.assertEqual(sim.solution.t[0], 0)
        self.assertEqual(sim.solution.t[1], dt / tau)
        self.assertEqual(sim.solution.t[2], 2 * dt / tau)
Esempio n. 9
0
 def test_step_with_inputs(self):
     dt = 0.001
     model = pybamm.lithium_ion.SPM()
     param = model.default_parameter_values
     param.update({"Current function [A]": "[input]"})
     sim = pybamm.Simulation(model, parameter_values=param)
     sim.step(
         dt, inputs={"Current function [A]": 1}
     )  # 1 step stores first two points
     tau = sim.model.timescale.evaluate()
     self.assertEqual(sim.solution.t.size, 2)
     self.assertEqual(sim.solution.y.full()[0, :].size, 2)
     self.assertEqual(sim.solution.t[0], 0)
     self.assertEqual(sim.solution.t[1], dt / tau)
     np.testing.assert_array_equal(
         sim.solution.all_inputs[0]["Current function [A]"], 1
     )
     sim.step(
         dt, inputs={"Current function [A]": 2}
     )  # automatically append the next step
     self.assertEqual(sim.solution.t.size, 3)
     self.assertEqual(sim.solution.y.full()[0, :].size, 3)
     self.assertEqual(sim.solution.t[0], 0)
     self.assertEqual(sim.solution.t[1], dt / tau)
     self.assertEqual(sim.solution.t[2], 2 * dt / tau)
     np.testing.assert_array_equal(
         sim.solution.all_inputs[1]["Current function [A]"], 2
     )
Esempio n. 10
0
    def test_on_dfn(self):
        e_height = 0.25

        model = pybamm.lithium_ion.DFN()
        geometry = model.default_geometry
        param = model.default_parameter_values
        param.update({"Electrode height [m]": "[input]"})
        param.process_model(model)
        param.process_geometry(geometry)
        inputs = {"Electrode height [m]": e_height}
        var = pybamm.standard_spatial_vars
        var_pts = {
            var.x_n: 5,
            var.x_s: 5,
            var.x_p: 5,
            var.r_n: 10,
            var.r_p: 10
        }
        spatial_methods = model.default_spatial_methods

        solver = pybamm.CasadiSolver()
        sim = pybamm.Simulation(
            model=model,
            geometry=geometry,
            parameter_values=param,
            var_pts=var_pts,
            spatial_methods=spatial_methods,
            solver=solver,
        )
        sim.solve(t_eval=np.linspace(0, 3600, 100), inputs=inputs)
 def test_model_shape(self):
     for spatial_discretisation in pybamm.KNOWN_SPATIAL_DISCRETISATIONS:
         solver = pybamm.Solver(
             spatial_discretisation=spatial_discretisation)
         sim = pybamm.Simulation(self.model, solver=solver)
         y, dydt = pdes_io(sim.model)
         self.assertEqual(y.shape, dydt.shape)
Esempio n. 12
0
    def test_model_physics(self):
        sim = pybamm.Simulation(self.model, self.param, self.mesh)
        solver = pybamm.Solver(
            integrator="BDF", spatial_discretisation="Finite Volumes"
        )

        sim.run(solver)

        interface = pybamm.Interface()
        interface.set_simulation(self.param, self.mesh)
        cn = np.ones((len(self.mesh.xcn), len(sim.vars.t)))
        cp = np.ones((len(self.mesh.xcp), len(sim.vars.t)))
        sim.vars.jn = interface.butler_volmer("xcn", cn, sim.vars.en)
        sim.vars.jp = interface.butler_volmer("xcp", cp, sim.vars.ep)

        sim.average()

        # integral of en is known
        jn_avg_expected = self.param.icell(sim.vars.t) / self.param.ln
        jp_avg_expected = -self.param.icell(sim.vars.t) / self.param.lp

        self.assertTrue(
            np.allclose(sim.vars.jn_avg[1:], jn_avg_expected[1:], atol=1e-15)
        )
        self.assertTrue(
            np.allclose(sim.vars.jp_avg[1:], jp_avg_expected[1:], atol=1e-15)
        )
Esempio n. 13
0
def compare_models(models, param, Crates, temperature, filename=None):
    fig, axes = plt.subplots(2, 2, figsize=(5.5, 4))

    param["Ambient temperature [K]"] = 273.15 + temperature
    param["Initial temperature [K]"] = 273.15 + temperature

    for Crate in Crates:
        simulations = [None] * len(models)
        solutions = [None] * len(models)

        for i, model in enumerate(models):
            sim = pybamm.Simulation(
                model,
                parameter_values=param,
                C_rate=Crate,
            )
            sim.solve([0, 3700 / Crate])
            solutions[i] = sim.solution
            simulations[i] = sim

        # Compute and print error
        error = compute_error(solutions)
        print_error(error, Crate, temperature, filename=filename)

        # Plot voltage and error
        axes = add_plot(axes, solutions, error, Crate)

    fig.suptitle("Ambient temperature: {} °C".format(temperature))

    fig.tight_layout()
    fig.subplots_adjust(top=0.88)

    return fig
Esempio n. 14
0
    def test_known_solution(self):
        model = pybamm.lithium_ion.ElectrodeSOH()

        param = pybamm.LithiumIonParameters()
        parameter_values = pybamm.ParameterValues(
            chemistry=pybamm.parameter_sets.Mohtat2020)
        sim = pybamm.Simulation(model, parameter_values=parameter_values)

        V_min = 3
        V_max = 4.2
        C_n = parameter_values.evaluate(param.C_n_init)
        C_p = parameter_values.evaluate(param.C_p_init)
        n_Li = parameter_values.evaluate(param.n_Li_particles_init)

        # Solve the model and check outputs
        sol = sim.solve(
            [0],
            inputs={
                "V_min": V_min,
                "V_max": V_max,
                "C_n": C_n,
                "C_p": C_p,
                "n_Li": n_Li,
            },
        )
        self.assertAlmostEqual(sol["Up(y_100) - Un(x_100)"].data[0],
                               V_max,
                               places=5)
        self.assertAlmostEqual(sol["Up(y_0) - Un(x_0)"].data[0],
                               V_min,
                               places=5)
        self.assertAlmostEqual(sol["n_Li_100"].data[0], n_Li, places=5)
        self.assertAlmostEqual(sol["n_Li_0"].data[0], n_Li, places=5)
Esempio n. 15
0
    def test_known_solutions(self):
        model = pybamm.lithium_ion.ElectrodeSOH()

        param = pybamm.LithiumIonParameters()
        parameter_values = pybamm.ParameterValues(
            chemistry=pybamm.parameter_sets.Mohtat2020)
        sim = pybamm.Simulation(model, parameter_values=parameter_values)

        V_min = parameter_values.evaluate(param.voltage_low_cut_dimensional)
        V_max = parameter_values.evaluate(param.voltage_high_cut_dimensional)
        C_n = parameter_values.evaluate(param.C_n_init)
        C_p = parameter_values.evaluate(param.C_p_init)
        n_Li = parameter_values.evaluate(param.n_Li_particles_init)

        # Solve the model and check outputs
        esoh_sol = sim.solve(
            [0],
            inputs={
                "V_min": V_min,
                "V_max": V_max,
                "C_n": C_n,
                "C_p": C_p,
                "n_Li": n_Li,
            },
        )

        x, y = pybamm.lithium_ion.get_initial_stoichiometries(
            1, parameter_values)
        self.assertAlmostEqual(x, esoh_sol["x_100"].data[0])
        self.assertAlmostEqual(y, esoh_sol["y_100"].data[0])
        x, y = pybamm.lithium_ion.get_initial_stoichiometries(
            0, parameter_values)
        self.assertAlmostEqual(x, esoh_sol["x_0"].data[0])
        self.assertAlmostEqual(y, esoh_sol["y_0"].data[0])
Esempio n. 16
0
    def test_drive_cycle_data(self):
        model = pybamm.lithium_ion.SPM()
        param = model.default_parameter_values
        param["Current function [A]"] = "[current data]US06"

        drive_cycle = pd.read_csv(
            pybamm.get_parameters_filepath(
                os.path.join("input", "drive_cycles", "US06.csv")),
            comment="#",
            skip_blank_lines=True,
            header=None,
        )
        time_data = drive_cycle.values[:, 0]

        sim = pybamm.Simulation(model, parameter_values=param)

        # check solution is returned at the times in the data
        sim.solve()
        tau = sim.model.timescale.evaluate()
        np.testing.assert_array_almost_equal(sim.solution.t, time_data / tau)

        # check warning raised if the largest gap in t_eval is bigger than the
        # smallest gap in the data
        sim.reset()
        with self.assertWarns(pybamm.SolverWarning):
            sim.solve(t_eval=np.linspace(0, 1, 100))

        # check warning raised if t_eval doesnt contain time_data , but has a finer
        # resolution (can still solve, but good for users to know they dont have
        # the solution returned at the data points)
        sim.reset()
        with self.assertWarns(pybamm.SolverWarning):
            sim.solve(t_eval=np.linspace(0, time_data[-1], 800))
Esempio n. 17
0
    def test_electrolyte_conductivity(self):
        root = pybamm.root_dir()
        p = "pybamm/input/parameters/lithium-ion/electrolytes/lipf6_Landesfeind2019"
        k_path = os.path.join(root, p)
        files = [
            f for f in os.listdir(k_path)
            if ".py" in f and "_base" not in f and "conductivity" in f
        ]
        files.sort()
        funcs = [pybamm.load_function(os.path.join(k_path, f)) for f in files]
        T_ref = 298.15
        T = T_ref + 30.0
        c = 1000.0
        k = [np.around(f(c, T).value, 6) for f in funcs]
        self.assertEqual(k, [1.839786, 1.361015, 0.750259])
        T += 20
        k = [np.around(f(c, T).value, 6) for f in funcs]
        self.assertEqual(k, [2.292425, 1.664438, 0.880755])

        chemistry = pybamm.parameter_sets.Chen2020
        param = pybamm.ParameterValues(chemistry=chemistry)
        param["Electrolyte conductivity [S.m-1]"] = funcs[0]
        model = pybamm.lithium_ion.SPM()
        sim = pybamm.Simulation(model, parameter_values=param)
        sim.set_parameters()
        sim.build()
Esempio n. 18
0
    def test_solve(self):

        sim = pybamm.Simulation(pybamm.lithium_ion.SPM())
        sim.solve()
        self.assertFalse(sim._solution is None)
        for val in list(sim.built_model.rhs.values()):
            self.assertFalse(val.has_symbol_of_classes(pybamm.Parameter))
            # skip test for scalar variables (e.g. discharge capacity)
            if val.size > 1:
                self.assertTrue(val.has_symbol_of_classes(pybamm.Matrix))

        sim.reset()
        self.assertEqual(sim.model_with_set_params, None)
        self.assertEqual(sim.built_model, None)
        for val in list(sim.model.rhs.values()):
            self.assertTrue(val.has_symbol_of_classes(pybamm.Parameter))
            self.assertFalse(val.has_symbol_of_classes(pybamm.Matrix))

        self.assertEqual(sim._solution, None)

        # test solve without check
        sim.reset()
        sim.solve(check_model=False)
        for val in list(sim.built_model.rhs.values()):
            self.assertFalse(val.has_symbol_of_classes(pybamm.Parameter))
            # skip test for scalar variables (e.g. discharge capacity)
            if val.size > 1:
                self.assertTrue(val.has_symbol_of_classes(pybamm.Matrix))
Esempio n. 19
0
    def test_electrolyte_diffusivity(self):
        root = pybamm.root_dir()
        p = "pybamm/input/parameters/lithium-ion/electrolytes/lipf6_Landesfeind2019"
        d_path = os.path.join(root, p)
        files = [
            f for f in os.listdir(d_path)
            if ".py" in f and "_base" not in f and "diffusivity" in f
        ]
        files.sort()
        funcs = [pybamm.load_function(os.path.join(d_path, f)) for f in files]
        T_ref = 298.15
        T = T_ref + 30.0
        c = 1000.0
        D = [np.around(f(c, T).value, 16) for f in funcs]
        self.assertEqual(D, [5.796505e-10, 5.417881e-10, 5.608856e-10])
        T += 20
        D = [np.around(f(c, T).value, 16) for f in funcs]
        self.assertEqual(D, [8.5992e-10, 7.752815e-10, 7.907549e-10])

        chemistry = pybamm.parameter_sets.Chen2020
        param = pybamm.ParameterValues(chemistry=chemistry)
        param["Electrolyte diffusivity [m2.s-1]"] = funcs[0]
        model = pybamm.lithium_ion.SPM()
        sim = pybamm.Simulation(model, parameter_values=param)
        sim.set_parameters()
        sim.build()
Esempio n. 20
0
    def test_dae_external_temperature(self):

        model_options = {
            "thermal": "x-full",
            "external submodels": ["thermal"],
        }

        model = pybamm.lithium_ion.DFN(model_options)

        neg_pts = 5
        sep_pts = 3
        pos_pts = 5
        tot_pts = neg_pts + sep_pts + pos_pts

        var_pts = {
            pybamm.standard_spatial_vars.x_n: neg_pts,
            pybamm.standard_spatial_vars.x_s: sep_pts,
            pybamm.standard_spatial_vars.x_p: pos_pts,
            pybamm.standard_spatial_vars.r_n: 5,
            pybamm.standard_spatial_vars.r_p: 5,
        }

        solver = pybamm.IDAKLUSolver()
        sim = pybamm.Simulation(model, var_pts=var_pts, solver=solver)
        sim.build()

        t_eval = np.linspace(0, 100, 3)
        x = np.linspace(0, 1, tot_pts)

        for i in np.arange(1, len(t_eval) - 1):
            dt = t_eval[i + 1] - t_eval[i]
            T = (np.sin(2 * np.pi * x) *
                 np.sin(2 * np.pi * 100 * t_eval[i]))[:, np.newaxis]
            external_variables = {"Cell temperature": T}
            sim.step(dt, external_variables=external_variables)
Esempio n. 21
0
 def test_set_crate(self):
     model = pybamm.lithium_ion.SPM()
     current_1C = model.default_parameter_values["Current function [A]"]
     sim = pybamm.Simulation(model, C_rate=2)
     self.assertEqual(sim.parameter_values["Current function [A]"],
                      2 * current_1C)
     self.assertEqual(sim.C_rate, 2)
Esempio n. 22
0
 def test_solution_evals_with_inputs(self):
     model = pybamm.lithium_ion.SPM()
     geometry = model.default_geometry
     param = model.default_parameter_values
     param.update({"Negative electrode conductivity [S.m-1]": "[input]"})
     param.process_model(model)
     param.process_geometry(geometry)
     var = pybamm.standard_spatial_vars
     var_pts = {
         var.x_n: 5,
         var.x_s: 5,
         var.x_p: 5,
         var.r_n: 10,
         var.r_p: 10
     }
     spatial_methods = model.default_spatial_methods
     solver = model.default_solver
     sim = pybamm.Simulation(
         model=model,
         geometry=geometry,
         parameter_values=param,
         var_pts=var_pts,
         spatial_methods=spatial_methods,
         solver=solver,
     )
     inputs = {"Negative electrode conductivity [S.m-1]": 0.1}
     sim.solve(t_eval=np.linspace(0, 10, 10), inputs=inputs)
     time = sim.solution["Time [h]"](sim.solution.t)
     self.assertEqual(len(time), 10)
Esempio n. 23
0
    def test_basic_ops(self):

        model = pybamm.lithium_ion.SPM()
        sim = pybamm.Simulation(model)

        self.assertEqual(model.__class__, sim._model_class)

        # check that the model is unprocessed
        self.assertEqual(sim._mesh, None)
        self.assertEqual(sim._disc, None)
        for val in list(sim.model.rhs.values()):
            self.assertTrue(val.has_symbol_of_classes(pybamm.Parameter))
            self.assertFalse(val.has_symbol_of_classes(pybamm.Matrix))

        sim.set_parameters()
        self.assertEqual(sim._mesh, None)
        self.assertEqual(sim._disc, None)
        for val in list(sim.model_with_set_params.rhs.values()):
            self.assertFalse(val.has_symbol_of_classes(pybamm.Parameter))
            self.assertFalse(val.has_symbol_of_classes(pybamm.Matrix))
        # Make sure model is unchanged
        self.assertNotEqual(sim.model, model)
        for val in list(model.rhs.values()):
            self.assertTrue(val.has_symbol_of_classes(pybamm.Parameter))
            self.assertFalse(val.has_symbol_of_classes(pybamm.Matrix))

        sim.build()
        self.assertFalse(sim._mesh is None)
        self.assertFalse(sim._disc is None)
        for val in list(sim.built_model.rhs.values()):
            self.assertFalse(val.has_symbol_of_classes(pybamm.Parameter))
            # skip test for scalar variables (e.g. discharge capacity)
            if val.size > 1:
                self.assertTrue(val.has_symbol_of_classes(pybamm.Matrix))
Esempio n. 24
0
    def test_drive_cycle_data(self):
        model = pybamm.lithium_ion.SPM()
        param = model.default_parameter_values
        param["Current function [A]"] = "[current data]US06"

        with self.assertRaisesRegex(NotImplementedError, "Drive cycle from data"):
            pybamm.Simulation(model, parameter_values=param)
Esempio n. 25
0
    def test_save_at_cycles(self):
        experiment = pybamm.Experiment([
            (
                "Discharge at 1C until 3.3V",
                "Charge at 1C until 4.1 V",
                "Hold at 4.1V until C/10",
            ),
        ] * 10, )
        model = pybamm.lithium_ion.SPM()
        sim = pybamm.Simulation(model, experiment=experiment)
        sol = sim.solve(solver=pybamm.CasadiSolver("fast with events"),
                        save_at_cycles=2)
        # Solution saves "None" for the cycles that are not saved
        for cycle_num in [2, 4, 6, 8]:
            self.assertIsNone(sol.cycles[cycle_num])
        for cycle_num in [0, 1, 3, 5, 7, 9]:
            self.assertIsNotNone(sol.cycles[cycle_num])
        # Summary variables are not None
        self.assertIsNotNone(sol.summary_variables["Capacity [A.h]"])

        sol = sim.solve(solver=pybamm.CasadiSolver("fast with events"),
                        save_at_cycles=[3, 4, 5, 9])
        # Note offset by 1 (0th cycle is cycle 1)
        for cycle_num in [1, 5, 6, 7, 9]:
            self.assertIsNone(sol.cycles[cycle_num])
        for cycle_num in [0, 2, 3, 4, 8]:
            self.assertIsNotNone(sol.cycles[cycle_num])
        # Summary variables are not None
        self.assertIsNotNone(sol.summary_variables["Capacity [A.h]"])
Esempio n. 26
0
    def test_set_external_variable(self):
        model_options = {
            "thermal": "lumped",
            "external submodels": ["thermal", "negative particle"],
        }
        model = pybamm.lithium_ion.SPMe(model_options)
        sim = pybamm.Simulation(model)

        var = pybamm.standard_spatial_vars
        Nr = model.default_var_pts[var.r_n]

        T_av = 0
        c_s_n_av = np.ones((Nr, 1)) * 0.5
        external_variables = {
            "Volume-averaged cell temperature": T_av,
            "X-averaged negative particle concentration": c_s_n_av,
        }

        # Step
        dt = 0.1
        for _ in range(5):
            sim.step(dt, external_variables=external_variables)
        sim.plot(testing=True)

        # Solve
        t_eval = np.linspace(0, 3600)
        sim.solve(t_eval, external_variables=external_variables)
        sim.plot(testing=True)
    def setUp(self):
        self.model = pybamm.lithium_ion.DFN()
        self.parameter_values = self.model.default_parameter_values
        self.sim = pybamm.Simulation(
            self.model,
            parameter_values=self.parameter_values
        )
        self.sim.solve([0, 3700])
        self.solution = self.sim.solution

        self.t = self.solution["Time [s]"]
        self.final_time = int(self.t.entries[len(self.t.entries) - 1])
        self.time_array = np.linspace(0, self.final_time, num=3)

        self.images = []
        self.image_files = []
        for val in self.time_array:
            self.plot = pybamm.QuickPlot(self.sim, time_unit="seconds")
            self.plot.plot(val)
            self.images.append("plot" + str(val) + ".png")
            self.plot.fig.savefig("plot" + str(val) + ".png", dpi=200)
            plt.close()

        for image in self.images:
            self.image_files.append(imageio.imread(image))
        imageio.mimsave('plot.gif', self.image_files, duration=0.1)

        for image in self.images:
            os.remove(image)
Esempio n. 28
0
    def test_specs(self):
        # test can rebuild after setting specs
        sim = pybamm.Simulation(pybamm.lithium_ion.SPM())
        sim.build()

        model_options = {"thermal": "lumped"}
        sim.specs(model_options=model_options)
        sim.build()
        self.assertEqual(sim.model.options["thermal"], "lumped")

        params = sim.parameter_values
        # normally is 0.0001
        params.update({"Negative electrode thickness [m]": 0.0002})
        sim.specs(parameter_values=params)

        self.assertEqual(
            sim.parameter_values["Negative electrode thickness [m]"], 0.0002)
        sim.build()

        sim.specs(geometry=pybamm.battery_geometry(
            current_collector_dimension=1))
        sim.build()

        var_pts = sim.var_pts
        var_pts[pybamm.standard_spatial_vars.x_n] = 5
        sim.specs(var_pts=var_pts)
        sim.build()

        spatial_methods = sim.spatial_methods
        # nothing to change this to at the moment but just reload in
        sim.specs(spatial_methods=spatial_methods)
        sim.build()
Esempio n. 29
0
def compare_data(models, param, Crates, temperature, cells_ignore=None, filename=None):
    fig, axes = plt.subplots(3, 2, figsize=(5.7, 5.5))

    for k, Crate in enumerate(Crates):
        param = set_experiment_parameters(param, Crate, temperature)
        param = set_ambient_temperature(param, Crate, temperature)

        experiment = pybamm.Experiment(
            [
                "Discharge at {}C until 2.5 V (5 seconds period)".format(Crate),
                "Rest for 2 hours",
            ],
            period="30 seconds",
        )

        solutions = []

        axes[k, :], _ = plot_experimental_data(
            axes[k, :], Crate, temperature, cells_ignore
        )

        for model in models:
            simulation = pybamm.Simulation(
                model,
                parameter_values=param,
                experiment=experiment,
            )
            simulation.solve()
            solution = simulation.solution
            solutions.append(solution)

            axes[k, :] = plot_model_solutions(axes[k, :], solution, Crate, temperature)

    fig.suptitle("Ambient temperature: {} °C".format(temperature))

    fig.tight_layout()
    fig.subplots_adjust(left=0.15, top=0.92)

    return fig


# Define models
    pybamm.lithium_ion.SPMe(
        options={
            "thermal": "lumped",
            "dimensionality": 0,
            "cell geometry": "arbitrary",
            "electrolyte conductivity": "integrated",
        },
        name="TSPMe",
    ),
    pybamm.lithium_ion.DFN(
        options={
            "thermal": "lumped",
            "dimensionality": 0,
            "cell geometry": "arbitrary",
        },
        name="TDFN",
    ),
Esempio n. 30
0
 def test_standard_lithium_parameters(self):
     chemistry = pybamm.parameter_sets.Ai2020
     parameter_values = pybamm.ParameterValues(chemistry=chemistry)
     options = {"particle mechanics": "swelling and cracking"}
     model = pybamm.lithium_ion.DFN(options)
     sim = pybamm.Simulation(model, parameter_values=parameter_values)
     sim.set_parameters()
     sim.build()