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 )
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)
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()
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")
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)
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)
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)
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)
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 )
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)
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) )
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
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)
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])
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))
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()
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))
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()
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)
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)
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)
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))
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)
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]"])
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)
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()
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", ),
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()