Example #1
0
    def test_current_functions(self):
        # create current functions
        dimensional_current_density = (pybamm.standard_parameters_lead_acid.
                                       dimensional_current_density_with_time)
        dimensionless_current_density = (
            pybamm.standard_parameters_lead_acid.current_with_time)

        # process
        parameter_values = pybamm.ParameterValues({
            "Electrode height [m]":
            0.1,
            "Electrode width [m]":
            0.1,
            "Negative electrode thickness [m]":
            1,
            "Separator thickness [m]":
            1,
            "Positive electrode thickness [m]":
            1,
            "Typical electrolyte concentration [mol.m-3]":
            1,
            "Number of electrodes connected in parallel to make a cell":
            8,
            "Typical current [A]":
            2,
            "Current function":
            pybamm.GetConstantCurrent(),
        })
        dimensional_current_density_eval = parameter_values.process_symbol(
            dimensional_current_density)
        dimensionless_current_density_eval = parameter_values.process_symbol(
            dimensionless_current_density)
        self.assertAlmostEqual(dimensional_current_density_eval.evaluate(t=3),
                               2 / (8 * 0.1 * 0.1))
        self.assertEqual(dimensionless_current_density_eval.evaluate(t=3), 1)
Example #2
0
def self_discharge_states(compute):
    save_file = "self_discharge_data.pickle"
    if compute:
        models = [
            pybamm.lead_acid.Full(name="Full, without oxygen"),
            pybamm.lead_acid.Full(
                {"side reactions": ["oxygen"]}, name="Full, with oxygen"
            ),
            pybamm.lead_acid.LOQS(
                {"surface form": "algebraic", "side reactions": ["oxygen"]},
                name="LOQS, with oxygen",
            ),
        ]
        extra_parameter_values = {
            "Current function": pybamm.GetConstantCurrent(current=0)
        }
        t_eval = np.linspace(0, 1000, 100)
        all_variables, t_eval = model_comparison(
            models, [1], t_eval, extra_parameter_values=extra_parameter_values
        )
        with open(save_file, "wb") as f:
            data = (all_variables, t_eval)
            pickle.dump(data, f, pickle.HIGHEST_PROTOCOL)
    else:
        try:
            with open(save_file, "rb") as f:
                (all_variables, t_eval) = pickle.load(f)
        except FileNotFoundError:
            raise FileNotFoundError(
                "Run script with '--compute' first to generate results"
            )
    plot_voltages(all_variables, t_eval)
    def test_update_model(self):
        # test on simple lithium-ion model
        model1 = pybamm.lithium_ion.SPM()
        modeltest1 = tests.StandardModelTest(model1)
        t_eval = np.linspace(0, 0.1)

        modeltest1.test_all(t_eval=t_eval, skip_output_tests=True)
        Y1 = modeltest1.solution.y

        # double initial conditions
        model2 = pybamm.lithium_ion.SPM()
        # process and solve the model a first time
        modeltest2 = tests.StandardModelTest(model2)
        modeltest2.test_all(skip_output_tests=True)
        self.assertEqual(
            model2.variables["Current [A]"].function.parameters_eval["Current [A]"],
            0.68,
        )
        # process and solve with updated parameter values
        parameter_values_update = pybamm.ParameterValues(
            chemistry=pybamm.parameter_sets.Marquis2019
        )
        parameter_values_update.update({"Typical current [A]": 2})
        modeltest2.test_update_parameters(parameter_values_update)
        self.assertEqual(
            model2.variables["Current [A]"].function.parameters_eval["Current [A]"], 2
        )
        modeltest2.test_solving(t_eval=t_eval)
        Y2 = modeltest2.solution.y

        # results should be different
        self.assertNotEqual(np.linalg.norm(Y1 - Y2), 0)

        # test with new current function
        model3 = pybamm.lithium_ion.SPM()
        modeltest3 = tests.StandardModelTest(model3)
        modeltest3.test_all(skip_output_tests=True)
        parameter_values_update = pybamm.ParameterValues(
            chemistry=pybamm.parameter_sets.Marquis2019
        )
        parameter_values_update.update(
            {"Current function": pybamm.GetConstantCurrent(current=pybamm.Scalar(0))}
        )
        modeltest3.test_update_parameters(parameter_values_update)
        modeltest3.test_solving(t_eval=t_eval)
        Y3 = modeltest3.solution.y

        # function.parameters should be pybamm.Scalar(0), but parameters_eval s
        # should be a float
        self.assertIsInstance(
            model3.variables["Current [A]"].function.parameters["Current [A]"],
            pybamm.Scalar,
        )
        self.assertEqual(
            model3.variables["Current [A]"].function.parameters_eval["Current [A]"], 0.0
        )

        # results should be different
        self.assertNotEqual(np.linalg.norm(Y1 - Y3), 0)
    def test_constant_current(self):
        function = pybamm.GetConstantCurrent(current=4)
        assert isinstance(function(0), numbers.Number)
        assert isinstance(function(np.zeros(3)), numbers.Number)
        assert isinstance(function(np.zeros([3, 3])), numbers.Number)

        # test simplify
        current = pybamm.electrical_parameters.current_with_time
        parameter_values = pybamm.ParameterValues(
            {
                "Typical current [A]": 2,
                "Typical timescale [s]": 1,
                "Current function": pybamm.GetConstantCurrent(),
            }
        )
        processed_current = parameter_values.process_symbol(current)
        self.assertIsInstance(processed_current.simplify(), pybamm.Scalar)
Example #5
0
 def test_zero_current(self):
     model = pybamm.lead_acid.LOQS()
     parameter_values = model.default_parameter_values
     parameter_values.update(
         {"Current function": pybamm.GetConstantCurrent(current=0)})
     modeltest = tests.StandardModelTest(model,
                                         parameter_values=parameter_values)
     modeltest.test_all()
Example #6
0
 def test_zero_current(self):
     options = {"thermal": "isothermal"}
     model = pybamm.lithium_ion.SPM(options)
     parameter_values = model.default_parameter_values
     parameter_values.update(
         {"Current function": pybamm.GetConstantCurrent(current=0)})
     modeltest = tests.StandardModelTest(model,
                                         parameter_values=parameter_values)
     modeltest.test_all()
Example #7
0
 def test_basic_processing_zero_current(self):
     options = {"side reactions": ["oxygen"], "surface form": "differential"}
     model = pybamm.lead_acid.Full(options)
     parameter_values = model.default_parameter_values
     parameter_values.update(
         {"Current function": pybamm.GetConstantCurrent(current=0)}
     )
     modeltest = tests.StandardModelTest(model, parameter_values=parameter_values)
     modeltest.test_all(skip_output_tests=True)
Example #8
0
# process variables for later plotting
time1 = pybamm.ProcessedVariable(model.variables["Time [h]"], solution1.t,
                                 solution1.y)
voltage1 = pybamm.ProcessedVariable(model.variables["Terminal voltage [V]"],
                                    solution1.t,
                                    solution1.y,
                                    mesh=mesh)
current1 = pybamm.ProcessedVariable(model.variables["Current [A]"],
                                    solution1.t,
                                    solution1.y,
                                    mesh=mesh)

# solve again with zero current, using last step of solution1 as initial conditions
# update the current to be zero
param["Current function"] = pybamm.GetConstantCurrent(current=pybamm.Scalar(0))
param.update_model(model, disc)
# Note: need to update model.concatenated_initial_conditions *after* update_model,
# as update_model updates model.concatenated_initial_conditions, by concatenting
# the (unmodified) initial conditions for each variable
model.concatenated_initial_conditions = solution1.y[:, -1][:, np.newaxis]

# simulate 1 hour of rest
t_start = solution1.t[-1]
t_end = t_start + 3600 / tau.evaluate(0)
t_eval2 = np.linspace(t_start, t_end, 120)
solution2 = model.default_solver.solve(model, t_eval2)

# process variables for later plotting
time2 = pybamm.ProcessedVariable(model.variables["Time [h]"], solution2.t,
                                 solution2.y)
Example #9
0
    def test_plot_lithium_ion(self):
        spm = pybamm.lithium_ion.SPM()
        spme = pybamm.lithium_ion.SPMe()
        geometry = spm.default_geometry
        param = spm.default_parameter_values
        param.process_model(spm)
        param.process_model(spme)
        param.process_geometry(geometry)
        mesh = pybamm.Mesh(geometry, spme.default_submesh_types, spme.default_var_pts)
        disc_spm = pybamm.Discretisation(mesh, spm.default_spatial_methods)
        disc_spme = pybamm.Discretisation(mesh, spme.default_spatial_methods)
        disc_spm.process_model(spm)
        disc_spme.process_model(spme)
        t_eval = np.linspace(0, 2, 100)
        solution_spm = spm.default_solver.solve(spm, t_eval)
        solution_spme = spme.default_solver.solve(spme, t_eval)
        quick_plot = pybamm.QuickPlot([spm, spme], mesh, [solution_spm, solution_spme])
        quick_plot.plot(0)

        # update the axis
        new_axis = [0, 0.5, 0, 1]
        quick_plot.axis.update({("Electrolyte concentration",): new_axis})
        self.assertEqual(quick_plot.axis[("Electrolyte concentration",)], new_axis)

        # and now reset them
        quick_plot.reset_axis()
        self.assertNotEqual(quick_plot.axis[("Electrolyte concentration",)], new_axis)

        # check dynamic plot loads
        quick_plot.dynamic_plot(testing=True)

        quick_plot.update(0.01)

        # Update parameters, solve, plot again
        param.update({"Current function": pybamm.GetConstantCurrent(current=0)})
        param.update_model(spm, disc_spm)
        solution_spm = spm.default_solver.solve(spm, t_eval)
        quick_plot = pybamm.QuickPlot(spm, mesh, solution_spm)
        quick_plot.plot(0)

        # Test with different output variables
        output_vars = [
            "Negative particle surface concentration",
            "Electrolyte concentration",
            "Positive particle surface concentration",
        ]
        quick_plot = pybamm.QuickPlot(spm, mesh, solution_spm, output_vars)
        self.assertEqual(len(quick_plot.axis), 3)
        quick_plot.plot(0)

        # update the axis
        new_axis = [0, 0.5, 0, 1]
        quick_plot.axis.update({("Electrolyte concentration",): new_axis})
        self.assertEqual(quick_plot.axis[("Electrolyte concentration",)], new_axis)

        # and now reset them
        quick_plot.reset_axis()
        self.assertNotEqual(quick_plot.axis[("Electrolyte concentration",)], new_axis)

        # check dynamic plot loads
        quick_plot.dynamic_plot(testing=True)

        quick_plot.update(0.01)