Ejemplo n.º 1
0
    def test_processed_variable_ode_pde_solution(self):
        # without space
        model = pybamm.BaseBatteryModel()
        c = pybamm.Variable("conc")
        model.rhs = {c: -c}
        model.initial_conditions = {c: 1}
        model.variables = {"c": c}
        modeltest = tests.StandardModelTest(model)
        modeltest.test_all()
        t_sol, y_sol = modeltest.solution.t, modeltest.solution.y
        processed_vars = pybamm.post_process_variables(model.variables, t_sol,
                                                       y_sol)
        np.testing.assert_array_almost_equal(processed_vars["c"](t_sol),
                                             np.exp(-t_sol))

        # with space
        # set up and solve model
        whole_cell = ["negative electrode", "separator", "positive electrode"]
        model = pybamm.BaseBatteryModel()
        c = pybamm.Variable("conc", domain=whole_cell)
        c_s = pybamm.Variable(
            "particle conc",
            domain="negative particle",
            auxiliary_domains={"secondary": ["negative electrode"]},
        )
        model.rhs = {c: -c, c_s: 1 - c_s}
        model.initial_conditions = {c: 1, c_s: 0.5}
        model.boundary_conditions = {
            c: {
                "left": (0, "Neumann"),
                "right": (0, "Neumann")
            },
            c_s: {
                "left": (0, "Neumann"),
                "right": (0, "Neumann")
            },
        }
        model.variables = {
            "c": c,
            "N": pybamm.grad(c),
            "c_s": c_s,
            "N_s": pybamm.grad(c_s),
        }
        modeltest = tests.StandardModelTest(model)
        modeltest.test_all()
        # set up testing
        t_sol, y_sol = modeltest.solution.t, modeltest.solution.y
        x = pybamm.SpatialVariable("x", domain=whole_cell)
        x_sol = modeltest.disc.process_symbol(x).entries[:, 0]
        processed_vars = pybamm.post_process_variables(model.variables, t_sol,
                                                       y_sol,
                                                       modeltest.disc.mesh)

        # test
        np.testing.assert_array_almost_equal(
            processed_vars["c"](t_sol, x_sol),
            np.ones_like(x_sol)[:, np.newaxis] * np.exp(-t_sol),
        )
Ejemplo n.º 2
0
    def __init__(self, model, parameter_values, disc, solution):
        # Process variables
        model.variables = pybamm.post_process_variables(
            model.variables, solution.t, solution.y, disc.mesh
        )

        # Assign attributes
        self.model = model
        self.parameter_values = parameter_values
        self.disc = disc
        self.solution = solution

        if isinstance(self.model, pybamm.lithium_ion.BaseModel):
            self.chemistry = "Lithium-ion"
        elif isinstance(self.model, pybamm.lead_acid.BaseModel):
            self.chemistry = "Lead acid"

        # Only for constant current
        current_sign = np.sign(
            parameter_values["Current function"].parameters_eval["Current [A]"]
        )

        if current_sign == 1:
            self.operating_condition = "discharge"
        elif current_sign == -1:
            self.operating_condition = "charge"
        else:
            self.operating_condition = "off"
Ejemplo n.º 3
0
def model_comparison(models, Crates, t_eval, extra_parameter_values=None):
    " Solve models at a range of Crates "
    # load parameter values and geometry
    geometry = models[0].default_geometry
    extra_parameter_values = extra_parameter_values or {}
    param = models[0].default_parameter_values
    param.update(extra_parameter_values)

    # Process parameters (same parameters for all models)
    for model in models:
        param.process_model(model)
    param.process_geometry(geometry)

    # set mesh
    var = pybamm.standard_spatial_vars
    var_pts = {var.x_n: 20, var.x_s: 20, var.x_p: 20}
    mesh = pybamm.Mesh(geometry, models[-1].default_submesh_types, var_pts)

    # discretise models
    discs = {}
    for model in models:
        disc = pybamm.Discretisation(mesh, model.default_spatial_methods)
        disc.process_model(model)
        # Store discretisation
        discs[model] = disc

    # solve model for range of Crates
    all_variables = {}
    for Crate in Crates:
        all_variables[Crate] = {}
        current = Crate * 17
        pybamm.logger.info("Setting typical current to {} A".format(current))
        param.update({"Typical current [A]": current})
        for model in models:
            param.update_model(model, discs[model])
            solution = model.default_solver.solve(model, t_eval)
            variables = pybamm.post_process_variables(
                model.variables, solution.t, solution.y, mesh
            )
            variables["solution"] = solution
            all_variables[Crate][model.name] = variables

    return all_variables, t_eval
Ejemplo n.º 4
0
    def __init__(self, models, discs, solutions):
        # Process variables
        for model in models:
            disc = discs[model]
            solution = solutions[model]
            model.variables = pybamm.post_process_variables(
                model.variables, solution.t, solution.y, disc.mesh)

        self.models = models
        self.discs = discs
        self.solutions = solutions

        if isinstance(self.models[0], pybamm.lithium_ion.BaseModel):
            self.chemistry = "Lithium-ion"
        elif isinstance(self.models[0], pybamm.lead_acid.BaseModel):
            self.chemistry = "Lead acid"

        self.t = self.get_output_times()
        self.mesh = self.get_mesh()
Ejemplo n.º 5
0
    def set_output_variables(self, output_variables, solutions, models, meshes):
        # Set up output variables
        self.variables = {}
        self.spatial_variable = {}

        # Calculate subplot positions based on number of variables supplied
        self.subplot_positions = {}
        self.n_rows = int(len(output_variables) // np.sqrt(len(output_variables)))
        self.n_cols = int(np.ceil(len(output_variables) / self.n_rows))

        # Process output variables into a form that can be plotted
        processed_variables = {}
        for i, model in enumerate(models):
            variables_to_process = {}
            for variable_list in output_variables:
                # Make sure we always have a list of lists of variables
                if isinstance(variable_list, str):
                    variable_list = [variable_list]
                # Add all variables to the list of variables that should be processed
                variables_to_process.update(
                    {var: model.variables[var] for var in variable_list}
                )
            processed_variables[model] = pybamm.post_process_variables(
                variables_to_process, solutions[i].t, solutions[i].y, meshes[i]
            )

        # Prepare dictionary of variables
        for k, variable_list in enumerate(output_variables):
            # Make sure we always have a list of lists of variables
            if isinstance(variable_list, str):
                variable_list = [variable_list]

            # Prepare list of variables
            key = tuple(variable_list)
            self.variables[key] = [None] * len(models)

            # process each variable in variable_list for each model
            for i, model in enumerate(models):
                # self.variables is a dictionary of lists of lists
                self.variables[key][i] = [
                    processed_variables[model][var] for var in variable_list
                ]

            # Make sure variables have the same dimensions and domain
            domain = self.variables[key][0][0].domain
            for variable in self.variables[key][0]:
                if variable.domain != domain:
                    raise ValueError("mismatching variable domains")

            # Set the x variable for any two-dimensional variables
            if self.variables[key][0][0].dimensions == 2:
                variable_key = self.variables[key][0][0].spatial_var_name
                variable_value = meshes[0].combine_submeshes(*domain)[0].edges
                self.spatial_variable[key] = (variable_key, variable_value)

            # Don't allow 3D variables
            elif any(var.dimensions == 3 for var in self.variables[key][0]):
                raise NotImplementedError("cannot plot 3D variables")

            # Define subplot position
            self.subplot_positions[key] = (self.n_rows, self.n_cols, k + 1)
Ejemplo n.º 6
0
        var.x_p: 5,
        var.r_n: 5,
        var.r_p: 5,
        var.y: 5,
        var.z: 5,
    }
    mesh = pybamm.Mesh(geometry, model.default_submesh_types, var_pts)
    disc = pybamm.Discretisation(mesh, model.default_spatial_methods)
    disc.process_model(model)

# solve model
solutions = [None] * len(models)
t_eval = np.linspace(0, 3, 1000)
for i, model in enumerate(models):
    solution = model.default_solver.solve(model, t_eval)
    solutions[i] = solution
    pybamm.post_process_variables(model.variables, solution.t, solution.y, mesh=mesh)

# plot
output_variables = [
    "Local current collector potential difference [V]",
    "Negative current collector potential [V]",
    "Positive current collector potential [V]",
    "X-averaged electrolyte concentration",
    # "Leading-order current collector current density",
    "Current collector current density",
    "Terminal voltage [V]",
]
plot = pybamm.QuickPlot(models, mesh, solutions, output_variables)
plot.dynamic_plot()