def test_termination(self): experiment = pybamm.Experiment(["Discharge at 1 C for 20 seconds"]) self.assertEqual(experiment.termination, {}) experiment = pybamm.Experiment(["Discharge at 1 C for 20 seconds"], termination="80.7% capacity") self.assertEqual(experiment.termination, {"capacity": (80.7, "%")}) experiment = pybamm.Experiment(["Discharge at 1 C for 20 seconds"], termination="80.7 % capacity") self.assertEqual(experiment.termination, {"capacity": (80.7, "%")}) experiment = pybamm.Experiment(["Discharge at 1 C for 20 seconds"], termination="4.1Ah capacity") self.assertEqual(experiment.termination, {"capacity": (4.1, "Ah")}) experiment = pybamm.Experiment(["Discharge at 1 C for 20 seconds"], termination="4.1 A.h capacity") self.assertEqual(experiment.termination, {"capacity": (4.1, "Ah")}) with self.assertRaisesRegex(ValueError, "Only capacity"): experiment = pybamm.Experiment(["Discharge at 1 C for 20 seconds"], termination="bla bla capacity bla") with self.assertRaisesRegex(ValueError, "Only capacity"): experiment = pybamm.Experiment(["Discharge at 1 C for 20 seconds"], termination="4 A.h something else") with self.assertRaisesRegex(ValueError, "Capacity termination"): experiment = pybamm.Experiment(["Discharge at 1 C for 20 seconds"], termination="1 capacity")
def __init__( self, models_for_comp, chemistry, is_experiment, params, cycle=None, number=None, param_to_vary_info=None, varied_values_override=None, ): self.models_for_comp = models_for_comp self.chemistry = chemistry self.is_experiment = is_experiment self.cycle = cycle self.number = number self.param_to_vary = (list(param_to_vary_info.keys())[0] if param_to_vary_info is not None else None) self.bounds = (list(param_to_vary_info.values())[0]["bounds"] if param_to_vary_info is not None else None) self.print_name = (list(param_to_vary_info.values())[0]["print_name"] if param_to_vary_info is not None else None) self.parameter_values = pybamm.ParameterValues(self.chemistry) self.experiment = (dict( list(enumerate([pybamm.Experiment(self.cycle * self.number)]))) if self.cycle is not None else None) self.comparison_dict = {} self.params = params self.varied_values_override = varied_values_override
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 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_run_experiment_termination(self): # with percent experiment = pybamm.Experiment( [ ( "Discharge at 1C until 3V", "Charge at 1C until 4.2 V", "Hold at 4.2V until C/10", ), ] * 10, termination="99% capacity", ) model = pybamm.lithium_ion.SPM({"SEI": "ec reaction limited"}) param = pybamm.ParameterValues( chemistry=pybamm.parameter_sets.Chen2020) param["SEI kinetic rate constant [m.s-1]"] = 1e-14 sim = pybamm.Simulation(model, experiment=experiment, parameter_values=param) sol = sim.solve(solver=pybamm.CasadiSolver()) C = sol.summary_variables["Capacity [A.h]"] np.testing.assert_array_less(np.diff(C), 0) # all but the last value should be above the termination condition np.testing.assert_array_less(0.99 * C[0], C[:-1]) # with Ah value experiment = pybamm.Experiment( [ ( "Discharge at 1C until 3V", "Charge at 1C until 4.2 V", "Hold at 4.2V until C/10", ), ] * 10, termination="5.04Ah capacity", ) model = pybamm.lithium_ion.SPM({"SEI": "ec reaction limited"}) param = pybamm.ParameterValues( chemistry=pybamm.parameter_sets.Chen2020) param["SEI kinetic rate constant [m.s-1]"] = 1e-14 sim = pybamm.Simulation(model, experiment=experiment, parameter_values=param) sol = sim.solve(solver=pybamm.CasadiSolver()) # all but the last value should be above the termination condition np.testing.assert_array_less(5.04, C[:-1])
def test_read_strings(self): experiment = pybamm.Experiment( [ "Discharge at 1C for 0.5 hours", "Discharge at C/20 for 0.5 hours", "Charge at 0.5 C for 45 minutes", "Discharge at 1 A for 0.5 hours", "Charge at 200 mA for 45 minutes (1 minute period)", "Discharge at 1W for 0.5 hours", "Charge at 200 mW for 45 minutes", "Rest for 10 minutes (5 minute period)", "Hold at 1V for 20 seconds", "Charge at 1 C until 4.1V", "Hold at 4.1 V until 50mA", "Hold at 3V until C/50", "Discharge at C/3 for 2 hours or until 2.5 V", ], {"test": "test"}, period="20 seconds", ) self.assertEqual( experiment.operating_conditions, [ (1, "C", 1800.0, 20.0), (0.05, "C", 1800.0, 20.0), (-0.5, "C", 2700.0, 20.0), (1, "A", 1800.0, 20.0), (-0.2, "A", 2700.0, 60.0), (1, "W", 1800.0, 20.0), (-0.2, "W", 2700.0, 20.0), (0, "A", 600.0, 300.0), (1, "V", 20.0, 20.0), (-1, "C", None, 20.0), (4.1, "V", None, 20.0), (3, "V", None, 20.0), (1 / 3, "C", 7200.0, 20.0), ], ) self.assertEqual( experiment.events, [ None, None, None, None, None, None, None, None, None, (4.1, "V"), (0.05, "A"), (0.02, "C"), (2.5, "V"), ], ) self.assertEqual(experiment.parameters, {"test": "test"}) self.assertEqual(experiment.period, 20)
def test_experiment_generator_with_rest(self): cycle = experiment_generator({"rest1": True, "rest2": True}) self.assertEqual(len(cycle[0]), 5) self.assertEqual(cycle[0][0][:9], "Discharge") self.assertEqual(cycle[0][1][:4], "Rest") self.assertEqual(cycle[0][2][:6], "Charge") self.assertEqual(cycle[0][3][:4], "Hold") self.assertEqual(cycle[0][4][:4], "Rest") pybamm.Experiment(cycle)
def test_run_experiment_breaks_early(self): experiment = pybamm.Experiment(["Discharge at 2 C for 1 hour"]) model = pybamm.lithium_ion.SPM() sim = pybamm.Simulation(model, experiment=experiment) pybamm.set_logging_level("ERROR") # giving the time, should get ignored t_eval = [0, 1] sim.solve(t_eval, solver=pybamm.CasadiSolver()) pybamm.set_logging_level("WARNING") self.assertEqual(sim._solution, None)
def test_run_experiment(self): experiment = pybamm.Experiment([ "Discharge at C/20 for 1 hour", "Charge at 1 A until 4.1 V", "Hold at 4.1 V until C/2", "Discharge at 2 W for 1 hour", ]) model = pybamm.lithium_ion.SPM() sim = pybamm.Simulation(model, experiment=experiment) sim.solve(solver=pybamm.CasadiSolver()) self.assertEqual(sim._solution.termination, "final time")
def test_dfn_half_cell_simulation_with_experiment_error(self): options = {"working electrode": "negative"} model = pybamm.lithium_ion.BasicDFNHalfCell(options=options) experiment = pybamm.Experiment([ ("Discharge at C/10 for 10 hours or until 3.5 V") ]) with self.assertRaisesRegex( NotImplementedError, "BasicDFNHalfCell is not compatible with experiment simulations yet." ): pybamm.Simulation(model, experiment=experiment)
def test_str_repr(self): conds = [ "Discharge at 1 C for 20 seconds", "Charge at 0.5 W for 10 minutes" ] experiment = pybamm.Experiment(conds) self.assertEqual(str(experiment), str(conds)) self.assertEqual( repr(experiment), "pybamm.Experiment(['Discharge at 1 C for 20 seconds'" + ", 'Charge at 0.5 W for 10 minutes'])", )
def test_infeasible(self): experiment = pybamm.Experiment([ ("Discharge at 1C for 0.5 hours", ), ] * 4) model = pybamm.lithium_ion.SPM() sim = pybamm.Simulation(model, experiment=experiment, solver=pybamm.CasadiSolver()) sol = sim.solve() # this experiment fails during the third cycle (i.e. is infeasible) # so we should just return the successful cycles (2 in this case) self.assertEqual(len(sol.cycles), 2)
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 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, :], data_conc = 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) error = compute_error(solution, data_conc) idx = filename.index(".") new_filename = filename[:idx] + "_" + model.name + filename[idx:] print_error(error, Crate, temperature, filename=new_filename) fig.suptitle("Ambient temperature: {} °C".format(temperature)) fig.tight_layout() fig.subplots_adjust(left=0.15, top=0.92) return fig
def test_read_strings_repeat(self): experiment = pybamm.Experiment( ["Discharge at 10 mA for 0.5 hours"] + ["Charge at 0.5 C for 45 minutes", "Hold at 1 V for 20 seconds"] * 2) self.assertEqual( experiment.operating_conditions, [ (0.01, "A", 1800.0, 60), (-0.5, "C", 2700.0, 60), (1, "V", 20.0, 60), (-0.5, "C", 2700.0, 60), (1, "V", 20.0, 60), ], ) self.assertEqual(experiment.period, 60)
def test_gitt(self): experiment = pybamm.Experiment( ["Discharge at C/20 for 1 hour", "Rest for 1 hour"] * 10, period="6 minutes") model = pybamm.lithium_ion.SPM() sim = pybamm.Simulation(model, experiment=experiment, solver=pybamm.CasadiSolver()) sim.solve() np.testing.assert_array_almost_equal(sim._solution["Time [h]"].entries, np.arange(0, 20.01, 0.1)) cap = model.default_parameter_values["Cell capacity [A.h]"] np.testing.assert_array_almost_equal( sim._solution["Current [A]"].entries, [cap / 20] * 11 + [0] * 10 + ([cap / 20] * 10 + [0] * 10) * 9, )
def test_run_experiment_old_setup_type(self): experiment = pybamm.Experiment( [ ( "Discharge at C/20 for 1 hour", "Charge at 1 A until 4.1 V", "Hold at 4.1 V until C/2", "Discharge at 2 W for 1 hour", ), ], use_simulation_setup_type="old", ) model = pybamm.lithium_ion.SPM() sim = pybamm.Simulation(model, experiment=experiment) solution1 = sim.solve(solver=pybamm.CasadiSolver()) self.assertEqual(solution1.termination, "final time")
def test_cycle_unpacking(self): experiment = pybamm.Experiment([ ("Discharge at C/20 for 0.5 hours", "Charge at C/5 for 45 minutes"), ("Discharge at C/20 for 0.5 hours"), "Charge at C/5 for 45 minutes", ]) self.assertEqual( experiment.operating_conditions, [ (0.05, "C", 1800.0, 60.0), (-0.2, "C", 2700.0, 60.0), (0.05, "C", 1800.0, 60.0), (-0.2, "C", 2700.0, 60.0), ], ) self.assertEqual(experiment.cycle_lengths, [2, 1, 1])
def test_inputs(self): experiment = pybamm.Experiment( ["Discharge at C/2 for 1 hour", "Rest for 1 hour"] ) model = pybamm.lithium_ion.SPM() # Change a parameter to an input param = pybamm.ParameterValues(chemistry=pybamm.parameter_sets.Marquis2019) param["Negative electrode diffusivity [m2.s-1]"] = ( pybamm.InputParameter("Dsn") * 3.9e-14 ) # Solve a first time sim = pybamm.Simulation(model, experiment=experiment, parameter_values=param) sim.solve(inputs={"Dsn": 1}) np.testing.assert_array_equal(sim.solution.inputs["Dsn"], 1) # Solve again, input should change sim.solve(inputs={"Dsn": 2}) np.testing.assert_array_equal(sim.solution.inputs["Dsn"], 2)
def test_rest_discharge_rest(self): # An experiment which requires recomputing consistent states experiment = pybamm.Experiment( [ "Rest for 5 minutes", "Discharge at 0.1C until 3V", "Rest for 30 minutes" ], period="1 minute", ) parameter_values = pybamm.ParameterValues( chemistry=pybamm.parameter_sets.Chen2020) model = pybamm.lithium_ion.DFN() sim = pybamm.Simulation( model, parameter_values=parameter_values, experiment=experiment, solver=pybamm.CasadiSolver(), ) sol = sim.solve() np.testing.assert_array_almost_equal(sol["Current [A]"].data[:5], 0) np.testing.assert_array_almost_equal(sol["Current [A]"].data[-29:], 0)
def test_discharge_rest_charge(self): experiment = pybamm.Experiment( [ "Discharge at C/2 for 1 hour", "Rest for 1 hour", "Charge at C/2 for 1 hour", ], period="0.25 hours", ) model = pybamm.lithium_ion.SPM() sim = pybamm.Simulation(model, experiment=experiment, solver=pybamm.CasadiSolver()) sim.solve() np.testing.assert_array_almost_equal(sim._solution["Time [h]"].entries, np.linspace(0, 3, 13)) cap = model.default_parameter_values["Cell capacity [A.h]"] np.testing.assert_array_almost_equal( sim._solution["Current [A]"].entries, [cap / 2] * 5 + [0] * 4 + [-cap / 2] * 4, )
def test_bad_strings(self): with self.assertRaisesRegex(TypeError, "Operating conditions should be strings"): pybamm.Experiment([1, 2, 3]) with self.assertRaisesRegex(ValueError, "Operating conditions must contain"): pybamm.Experiment(["Discharge at 1 A at 2 hours"]) with self.assertRaisesRegex(ValueError, "instruction must be"): pybamm.Experiment(["Run at 1 A for 2 hours"]) with self.assertRaisesRegex( ValueError, "Instruction 'Run at at 1 A' not recognized"): pybamm.Experiment(["Run at at 1 A for 2 hours"]) with self.assertRaisesRegex(ValueError, "units must be"): pybamm.Experiment(["Discharge at 1 B for 2 hours"]) with self.assertRaisesRegex(ValueError, "time units must be"): pybamm.Experiment(["Discharge at 1 A for 2 years"]) with self.assertRaisesRegex( TypeError, "experimental parameters should be a dictionary"): pybamm.Experiment([], "not a dictionary")
def test_cycles(self): model = pybamm.lithium_ion.SPM() experiment = pybamm.Experiment([ ("Discharge at C/20 for 0.5 hours", "Charge at C/20 for 15 minutes"), ("Discharge at C/20 for 0.5 hours", "Charge at C/20 for 15 minutes"), ]) sim = pybamm.Simulation(model, experiment=experiment) sol = sim.solve() self.assertEqual(len(sol.cycles), 2) len_cycle_1 = len(sol.cycles[0].t) self.assertIsInstance(sol.cycles[0], pybamm.Solution) np.testing.assert_array_equal(sol.cycles[0].t, sol.t[:len_cycle_1]) np.testing.assert_array_equal(sol.cycles[0].y, sol.y[:, :len_cycle_1]) self.assertIsInstance(sol.cycles[1], pybamm.Solution) np.testing.assert_array_equal(sol.cycles[1].t, sol.t[len_cycle_1 - 1:]) np.testing.assert_array_equal(sol.cycles[1].y, sol.y[:, len_cycle_1 - 1:])
def setUp(self): self.model = pybamm.lithium_ion.SPM( options={"SEI": "electron-migration limited"}) self.cycle = [( "Discharge at 2 C until 3.6 V", "Charge at 3 C until 3.8 V", "Hold at 3.8 V until 98 mA", "Rest for 4 minutes", )] self.number = 2 self.experiment = pybamm.Experiment(self.cycle * self.number) self.is_experiment = False self.degradation_parameter = "Inner SEI open-circuit potential [V]" self.varied_values = [0.09, 0.05] self.param_values_mohtat = [] for i in range(2): self.param_values_mohtat.append( pybamm.ParameterValues(pybamm.parameter_sets.Mohtat2020)) self.param_values_mohtat[i][ "Inner SEI open-circuit potential [V]"] = self.varied_values[i] self.chemistry = pybamm.parameter_sets.Mohtat2020 self.parameter_values = pybamm.ParameterValues(self.chemistry)
def test_experiment_generator_with_random_experiment(self): cycle = experiment_generator() self.assertTrue( len(cycle[0]) == 5 or len(cycle[0]) == 3 or len(cycle[0]) == 4) self.assertEqual(cycle[0][0][:9], "Discharge") if len(cycle[0]) == 3: self.assertEqual(cycle[0][1][:6], "Charge") self.assertEqual(cycle[0][2][:4], "Hold") elif len(cycle[0]) == 4: if cycle[0][1][:4] == "Rest": self.assertEqual(cycle[0][2][:6], "Charge") self.assertEqual(cycle[0][3][:4], "Hold") elif cycle[0][3][:4] == "Rest": self.assertEqual(cycle[0][1][:6], "Charge") self.assertEqual(cycle[0][2][:4], "Hold") elif len(cycle[0]) == 5: self.assertEqual(cycle[0][1][:4], "Rest") self.assertEqual(cycle[0][2][:6], "Charge") self.assertEqual(cycle[0][3][:4], "Hold") self.assertEqual(cycle[0][4][:4], "Rest") pybamm.Experiment(cycle)
def test_interpolant_extrapolate(self): model = pybamm.lithium_ion.DFN() param = pybamm.ParameterValues( chemistry=pybamm.parameter_sets.NCA_Kim2011) experiment = pybamm.Experiment(["Charge at 1C until 4.6 V"], period="10 seconds") param["Upper voltage cut-off [V]"] = 4.8 sim = pybamm.Simulation( model, parameter_values=param, experiment=experiment, solver=pybamm.CasadiSolver( mode="safe", dt_max=0.001, extrap_tol=1e-3, extra_options_setup={"max_num_steps": 500}, ), ) with self.assertRaisesRegex(pybamm.SolverError, "interpolation bounds"): sim.solve() ci = param["Initial concentration in positive electrode [mol.m-3]"] param[ "Initial concentration in positive electrode [mol.m-3]"] = 0.8 * ci sim = pybamm.Simulation( model, parameter_values=param, experiment=experiment, solver=pybamm.CasadiSolver(mode="safe", dt_max=0.05), ) with self.assertRaisesRegex(pybamm.SolverError, "interpolation bounds"): sim.solve()
def test_run_experiment(self): experiment = pybamm.Experiment([( "Discharge at C/20 for 1 hour", "Charge at 1 A until 4.1 V", "Hold at 4.1 V until C/2", "Discharge at 2 W for 1 hour", )]) model = pybamm.lithium_ion.DFN() sim = pybamm.Simulation(model, experiment=experiment) sol = sim.solve() self.assertEqual(sol.termination, "final time") self.assertEqual(len(sol.cycles), 1) for i, step in enumerate(sol.cycles[0].steps[:-1]): len_rhs = sol.all_models[0].concatenated_rhs.size y_left = step.all_ys[-1][:len_rhs, -1] if isinstance(y_left, casadi.DM): y_left = y_left.full() y_right = sol.cycles[0].steps[i + 1].all_ys[0][:len_rhs, 0] if isinstance(y_right, casadi.DM): y_right = y_right.full() np.testing.assert_array_equal(y_left.flatten(), y_right.flatten()) # Solve again starting from solution sol2 = sim.solve(starting_solution=sol) self.assertEqual(sol2.termination, "final time") self.assertGreater(sol2.t[-1], sol.t[-1]) self.assertEqual(sol2.cycles[0], sol.cycles[0]) self.assertEqual(len(sol2.cycles), 2) # Check starting solution is unchanged self.assertEqual(len(sol.cycles), 1) # save sol2.save("test_experiment.sav") sol3 = pybamm.load("test_experiment.sav") self.assertEqual(len(sol3.cycles), 2) os.remove("test_experiment.sav")
# # Constant-current constant-voltage charge # import pybamm import matplotlib.pyplot as plt pybamm.set_logging_level("INFO") experiment = pybamm.Experiment( [ "Discharge at C/10 for 13 hours or until 3.3 V", "Rest for 1 hour", "Charge at 1 A until 4.1 V", "Hold at 4.1 V until 50 mA", "Rest for 1 hour", ] * 3, period="2 minutes", ) model = pybamm.lithium_ion.DFN( ) # use {"thermal": "x-lumped"} for thermal effects sim = pybamm.Simulation(model, experiment=experiment, solver=pybamm.CasadiSolver()) sim.solve() # Plot voltages from the discharge segments only fig, ax = plt.subplots() for i in range(3): # Extract sub solutions sol = sim.solution.sub_solutions[i * 5] # Extract variables t = sol["Time [h]"].entries
experiment = pb.Experiment([( "Charge at 1 C until 4.2 V", "Hold at 4.2 V until C/10", "Rest for 5 minutes", "Discharge at 1 C until 2.8 V", "Rest for 5 minutes", )] * 2 + [ ( "Charge at 1 C until 4.2 V", "Hold at 4.2 V until C/20", "Rest for 30 minutes", "Discharge at C/3 until 2.8 V", ), ( "Charge at 1 C until 4.2 V", "Hold at 4.2 V until C/20", "Rest for 30 minutes", "Discharge at 1 C until 2.8 V", ), # ( # "Charge at 1 C until 4.2 V", # "Hold at 4.2 V until C/20", # "Rest for 30 minutes", # "Discharge at 2 C until 2.8 V", # ), # ( # "Charge at 1 C until 4.2 V", # "Hold at 4.2 V until C/20", # "Rest for 30 minutes", # "Discharge at 3 C until 2.8 V", # ), ])
def test_set_up(self): experiment = pybamm.Experiment([ "Discharge at C/20 for 1 hour", "Charge at 1 A until 4.1 V", "Hold at 4.1 V until 50 mA", "Discharge at 2 W for 1 hour", ]) model = pybamm.lithium_ion.DFN() sim = pybamm.Simulation(model, experiment=experiment) self.assertEqual(sim.experiment, experiment) self.assertEqual( sim._experiment_inputs[0]["Current input [A]"], 1 / 20 * model.default_parameter_values["Nominal cell capacity [A.h]"], ) self.assertEqual(sim._experiment_inputs[0]["Current switch"], 1) self.assertEqual(sim._experiment_inputs[0]["Voltage switch"], 0) self.assertEqual(sim._experiment_inputs[0]["Power switch"], 0) self.assertEqual(sim._experiment_inputs[0]["Current cut-off [A]"], -1e10) self.assertEqual(sim._experiment_inputs[0]["Voltage cut-off [V]"], -1e10) self.assertEqual(sim._experiment_inputs[1]["Current input [A]"], -1) self.assertEqual(sim._experiment_inputs[1]["Current switch"], 1) self.assertEqual(sim._experiment_inputs[1]["Voltage switch"], 0) self.assertEqual(sim._experiment_inputs[1]["Power switch"], 0) self.assertEqual(sim._experiment_inputs[1]["Current cut-off [A]"], -1e10) self.assertEqual(sim._experiment_inputs[1]["Voltage cut-off [V]"], 4.1) self.assertEqual(sim._experiment_inputs[2]["Current switch"], 0) self.assertEqual(sim._experiment_inputs[2]["Voltage switch"], 1) self.assertEqual(sim._experiment_inputs[2]["Power switch"], 0) self.assertEqual(sim._experiment_inputs[2]["Voltage input [V]"], 4.1) self.assertEqual(sim._experiment_inputs[2]["Current cut-off [A]"], 0.05) self.assertEqual(sim._experiment_inputs[2]["Voltage cut-off [V]"], -1e10) self.assertEqual(sim._experiment_inputs[3]["Current switch"], 0) self.assertEqual(sim._experiment_inputs[3]["Voltage switch"], 0) self.assertEqual(sim._experiment_inputs[3]["Power switch"], 1) self.assertEqual(sim._experiment_inputs[3]["Power input [W]"], 2) self.assertEqual(sim._experiment_inputs[3]["Current cut-off [A]"], -1e10) self.assertEqual(sim._experiment_inputs[3]["Voltage cut-off [V]"], -1e10) Crate = 1 / model.default_parameter_values[ "Nominal cell capacity [A.h]"] self.assertEqual(sim._experiment_times, [3600, 3 / Crate * 3600, 24 * 3600, 3600]) model_I = sim.op_conds_to_model_and_param[(-1.0, "A")][0] model_V = sim.op_conds_to_model_and_param[(4.1, "V")][0] self.assertIn( "Current cut-off (positive) [A] [experiment]", [event.name for event in model_V.events], ) self.assertIn( "Current cut-off (negative) [A] [experiment]", [event.name for event in model_V.events], ) self.assertIn( "Voltage cut-off [V] [experiment]", [event.name for event in model_I.events], ) # fails if trying to set up with something that isn't an experiment with self.assertRaisesRegex(TypeError, "experiment must be"): pybamm.Simulation(model, experiment=0)