Source code for pybamm.batch_study

#
# BatchStudy class
#
import pybamm
from itertools import product


[docs] class BatchStudy: """ A BatchStudy class for comparison of different PyBaMM simulations. Parameters ---------- models : dict A dictionary of models to be simulated experiments : dict (optional) A dictionary of experimental conditions under which to solve the model. Default is None geometries : dict (optional) A dictionary of geometries upon which to solve the model parameter_values : dict (optional) A dictionary of parameters and their corresponding numerical values. Default is None submesh_types : dict (optional) A dictionary of the types of submesh to use on each subdomain. Default is None var_pts : dict (optional) A dictionary of the number of points used by each spatial variable. Default is None spatial_methods : dict (optional) A dictionary of the types of spatial method to use on each domain. Default is None solvers : dict (optional) A dictionary of solvers to use to solve the model. Default is None output_variables : dict (optional) A dictionary of variables to plot automatically. Default is None C_rates : dict (optional) A dictionary of C-rates at which you would like to run a constant current (dis)charge. Default is None repeats : int (optional) The number of times `solve` should be called. Default is 1 permutations : bool (optional) If False runs first model with first solver, first experiment and second model with second solver, second experiment etc. If True runs a cartesian product of models, solvers and experiments. Default is False """ INPUT_LIST = [ "experiments", "geometries", "parameter_values", "submesh_types", "var_pts", "spatial_methods", "solvers", "output_variables", "C_rates", ] def __init__( self, models, experiments=None, geometries=None, parameter_values=None, submesh_types=None, var_pts=None, spatial_methods=None, solvers=None, output_variables=None, C_rates=None, repeats=1, permutations=False, ): self.models = models self.experiments = experiments self.geometries = geometries self.parameter_values = parameter_values self.submesh_types = submesh_types self.var_pts = var_pts self.spatial_methods = spatial_methods self.solvers = solvers self.output_variables = output_variables self.C_rates = C_rates self.repeats = repeats self.permutations = permutations self.quick_plot = None if not self.permutations: for name in self.INPUT_LIST: if getattr(self, name) and ( len(self.models) != len(getattr(self, name)) ): raise ValueError( f"Either provide no {name} or an equal number of {name}" f" as the models ({len(self.models)} models given)" f" if permutations=False" )
[docs] def solve( self, t_eval=None, solver=None, save_at_cycles=None, calc_esoh=True, starting_solution=None, initial_soc=None, **kwargs, ): """ For more information on the parameters used in the solve, See :meth:`pybamm.Simulation.solve` """ self.sims = [] iter_func = product if self.permutations else zip # Instantiate items in INPUT_LIST based on the value of self.permutations inp_values = [] for name in self.INPUT_LIST: if getattr(self, name): inp_value = getattr(self, name).values() elif self.permutations: inp_value = [None] else: inp_value = [None] * len(self.models) inp_values.append(inp_value) for ( model, experiment, geometry, parameter_value, submesh_type, var_pt, spatial_method, solver, output_variable, C_rate, ) in iter_func(self.models.values(), *inp_values): sim = pybamm.Simulation( model, experiment=experiment, geometry=geometry, parameter_values=parameter_value, submesh_types=submesh_type, var_pts=var_pt, spatial_methods=spatial_method, solver=solver, output_variables=output_variable, C_rate=C_rate, ) # Repeat to get average solve time and integration time solve_time = 0 integration_time = 0 for _ in range(self.repeats): sol = sim.solve( t_eval, solver, save_at_cycles, calc_esoh, starting_solution, initial_soc, **kwargs, ) solve_time += sol.solve_time integration_time += sol.integration_time sim.solution.solve_time = solve_time / self.repeats sim.solution.integration_time = integration_time / self.repeats self.sims.append(sim)
[docs] def plot(self, output_variables=None, **kwargs): """ For more information on the parameters used in the plot, See :meth:`pybamm.Simulation.plot` """ self.quick_plot = pybamm.dynamic_plot( self.sims, output_variables=output_variables, **kwargs ) return self.quick_plot
[docs] def create_gif(self, number_of_images=80, duration=0.1, output_filename="plot.gif"): """ Generates x plots over a time span of t_eval and compiles them to create a GIF. For more information see :meth:`pybamm.QuickPlot.create_gif` Parameters ---------- number_of_images : int, optional Number of images/plots to be compiled for a GIF. duration : float, optional Duration of visibility of a single image/plot in the created GIF. output_filename : str, optional Name of the generated GIF file. """ if not hasattr(self, "sims"): raise ValueError("The simulations have not been solved yet.") if self.quick_plot is None: self.quick_plot = pybamm.QuickPlot(self.sims) self.quick_plot.create_gif( number_of_images=number_of_images, duration=duration, output_filename=output_filename, )