Ejemplo n.º 1
0
    def simulate(self, nd_param_dict,time_vec ,*args):
        for key in self.dim_keys:
            self.pybam_val_dict[key]=nd_param_dict[key]


        if self.simulation_options["method"]!="dcv":
            self.solver=pybamm.CasadiSolver(mode="fast", rtol=1e-7)
        else:
            self.solver=pybamm.ScipySolver()
        self.solver=pybamm.ScipySolver()
        solution=self.solver.solve(self.model, time_vec, inputs=self.pybam_val_dict)
        return solution.y[0]
Ejemplo n.º 2
0
    def test_integrate_with_event(self):
        # Constant
        solver = pybamm.ScipySolver(rtol=1e-8, atol=1e-8, method="RK45")

        def constant_growth(t, y):
            return 0.5 * np.ones_like(y)

        def y_eq_2(t, y):
            return y - 2

        y0 = np.array([0])
        t_eval = np.linspace(0, 10, 100)
        solution = solver.integrate(constant_growth,
                                    y0,
                                    t_eval,
                                    events=[y_eq_2])
        self.assertLess(len(solution.t), len(t_eval))
        np.testing.assert_allclose(0.5 * solution.t, solution.y[0])
        np.testing.assert_allclose(solution.t_event, 4)
        np.testing.assert_allclose(solution.y_event, 2)
        self.assertEqual(solution.termination, "event")

        # Exponential decay
        solver = pybamm.ScipySolver(rtol=1e-8, atol=1e-8, method="BDF")

        def exponential_growth(t, y):
            return y

        def y_eq_5(t, y):
            return np.max(y - 5)

        def t_eq_6(t, y):
            return t - 6

        y0 = np.array([1, 2])
        t_eval = np.linspace(0, 7, 100)
        solution = solver.integrate(exponential_growth,
                                    y0,
                                    t_eval,
                                    events=[y_eq_5, t_eq_6])
        np.testing.assert_allclose(solution.y[0],
                                   np.exp(solution.t),
                                   rtol=1e-6)
        np.testing.assert_allclose(solution.y[1],
                                   2 * np.exp(solution.t),
                                   rtol=1e-6)
        np.testing.assert_array_less(solution.t, 6)
        np.testing.assert_array_less(solution.y, 5)
        np.testing.assert_allclose(solution.t_event, np.log(5 / 2), rtol=1e-6)
        np.testing.assert_allclose(solution.y_event[0], 5 / 2, rtol=1e-6)
        np.testing.assert_allclose(solution.y_event[1], 5, rtol=1e-6)
Ejemplo n.º 3
0
    def test_model_solver_python(self):
        # Create model
        model = pybamm.BaseModel()
        model.convert_to_format = "python"
        domain = ["negative electrode", "separator", "positive electrode"]
        var = pybamm.Variable("var", domain=domain)
        model.rhs = {var: 0.1 * var}
        model.initial_conditions = {var: 1}
        # No need to set parameters; can use base discretisation (no spatial operators)

        # create discretisation
        mesh = get_mesh_for_testing()
        spatial_methods = {"macroscale": pybamm.FiniteVolume()}
        disc = pybamm.Discretisation(mesh, spatial_methods)
        disc.process_model(model)
        # Solve
        # Make sure that passing in extra options works
        solver = pybamm.ScipySolver(rtol=1e-8,
                                    atol=1e-8,
                                    method="RK45",
                                    extra_options={"first_step": 1e-4})
        t_eval = np.linspace(0, 1, 80)
        solution = solver.solve(model, t_eval)
        np.testing.assert_array_equal(solution.t, t_eval)
        np.testing.assert_allclose(solution.y[0], np.exp(0.1 * solution.t))

        # Test time
        self.assertEqual(solution.total_time,
                         solution.solve_time + solution.set_up_time)
        self.assertEqual(solution.termination, "final time")
Ejemplo n.º 4
0
    def test_model_solver_with_external(self):
        # Create model
        model = pybamm.BaseModel()
        domain = ["negative electrode", "separator", "positive electrode"]
        var1 = pybamm.Variable("var1", domain=domain)
        var2 = pybamm.Variable("var2", domain=domain)
        model.rhs = {var1: -var2}
        model.initial_conditions = {var1: 1}
        model.external_variables = [var2]
        model.variables = {"var2": var2}
        # No need to set parameters; can use base discretisation (no spatial
        # operators)

        # create discretisation
        mesh = get_mesh_for_testing()
        spatial_methods = {"macroscale": pybamm.FiniteVolume()}
        disc = pybamm.Discretisation(mesh, spatial_methods)
        disc.process_model(model)
        # Solve
        solver = pybamm.ScipySolver(rtol=1e-8, atol=1e-8)
        t_eval = np.linspace(0, 10, 100)
        solution = solver.solve(
            model, t_eval, external_variables={"var2": 0.5 * np.ones(100)})
        np.testing.assert_allclose(solution.y[0],
                                   1 - 0.5 * solution.t,
                                   rtol=1e-06)
Ejemplo n.º 5
0
    def test_model_step(self):
        # Create model
        model = pybamm.BaseModel()
        domain = ["negative electrode", "separator", "positive electrode"]
        var = pybamm.Variable("var", domain=domain)
        model.rhs = {var: 0.1 * var}
        model.initial_conditions = {var: 1}
        # No need to set parameters; can use base discretisation (no spatial operators)

        # create discretisation
        mesh = get_mesh_for_testing()
        spatial_methods = {"macroscale": pybamm.FiniteVolume}
        disc = pybamm.Discretisation(mesh, spatial_methods)
        disc.process_model(model)

        solver = pybamm.ScipySolver(rtol=1e-8, atol=1e-8, method="RK45")

        # Step once
        dt = 0.1
        step_sol = solver.step(model, dt)
        np.testing.assert_array_equal(step_sol.t, [0, dt])
        np.testing.assert_allclose(step_sol.y[0], np.exp(0.1 * step_sol.t))

        # Step again (return 5 points)
        step_sol_2 = solver.step(model, dt, npts=5)
        np.testing.assert_array_equal(step_sol_2.t, np.linspace(dt, 2 * dt, 5))
        np.testing.assert_allclose(step_sol_2.y[0], np.exp(0.1 * step_sol_2.t))

        # append solutions
        step_sol.append(step_sol_2)

        # Check steps give same solution as solve
        t_eval = step_sol.t
        solution = solver.solve(model, t_eval)
        np.testing.assert_allclose(solution.y[0], step_sol.y[0])
Ejemplo n.º 6
0
    def test_model_solver_inputs_in_initial_conditions(self):
        # Create model
        model = pybamm.BaseModel()
        var1 = pybamm.Variable("var1")
        model.rhs = {var1: pybamm.InputParameter("rate") * var1}
        model.initial_conditions = {
            var1: pybamm.InputParameter("ic 1"),
        }

        # Solve
        solver = pybamm.ScipySolver(rtol=1e-8, atol=1e-8)
        t_eval = np.linspace(0, 5, 100)
        solution = solver.solve(model,
                                t_eval,
                                inputs={
                                    "rate": -1,
                                    "ic 1": 0.1
                                })
        np.testing.assert_array_almost_equal(solution.y[0],
                                             0.1 * np.exp(-solution.t),
                                             decimal=5)

        # Solve again with different initial conditions
        solution = solver.solve(model,
                                t_eval,
                                inputs={
                                    "rate": -0.1,
                                    "ic 1": 1
                                })
        np.testing.assert_array_almost_equal(solution.y[0],
                                             1 * np.exp(-0.1 * solution.t),
                                             decimal=5)
Ejemplo n.º 7
0
    def test_model_solver_with_event_python(self):
        # Create model
        model = pybamm.BaseModel()
        model.convert_to_format = "python"
        domain = ["negative electrode", "separator", "positive electrode"]
        var = pybamm.Variable("var", domain=domain)
        model.rhs = {var: -0.1 * var}
        model.initial_conditions = {var: 1}
        # needs to work with multiple events (to avoid bug where only last event is
        # used)
        model.events = [
            pybamm.Event("var=0.5", pybamm.min(var - 0.5)),
            pybamm.Event("var=-0.5", pybamm.min(var + 0.5)),
        ]
        # No need to set parameters; can use base discretisation (no spatial operators)

        # create discretisation
        mesh = get_mesh_for_testing()
        spatial_methods = {"macroscale": pybamm.FiniteVolume()}
        disc = pybamm.Discretisation(mesh, spatial_methods)
        disc.process_model(model)
        # Solve
        solver = pybamm.ScipySolver(rtol=1e-8, atol=1e-8, method="RK45")
        t_eval = np.linspace(0, 10, 100)
        solution = solver.solve(model, t_eval)
        self.assertLess(len(solution.t), len(t_eval))
        np.testing.assert_array_equal(solution.t, t_eval[:len(solution.t)])
        np.testing.assert_allclose(solution.y[0], np.exp(-0.1 * solution.t))
Ejemplo n.º 8
0
    def test_solver_citations(self):
        # Test that solving each solver adds the right citations
        citations = pybamm.citations

        citations._reset()
        self.assertNotIn("virtanen2020scipy", citations._papers_to_cite)
        pybamm.ScipySolver()
        self.assertIn("virtanen2020scipy", citations._papers_to_cite)

        citations._reset()
        self.assertNotIn("virtanen2020scipy", citations._papers_to_cite)
        pybamm.AlgebraicSolver()
        self.assertIn("virtanen2020scipy", citations._papers_to_cite)

        if pybamm.have_scikits_odes():
            citations._reset()
            self.assertNotIn("scikits-odes", citations._papers_to_cite)
            pybamm.ScikitsOdeSolver()
            self.assertIn("scikits-odes", citations._papers_to_cite)

            citations._reset()
            self.assertNotIn("scikits-odes", citations._papers_to_cite)
            pybamm.ScikitsDaeSolver()
            self.assertIn("scikits-odes", citations._papers_to_cite)

        if pybamm.have_idaklu():
            citations._reset()
            self.assertNotIn("hindmarsh2005sundials",
                             citations._papers_to_cite)
            pybamm.IDAKLUSolver()
            self.assertIn("hindmarsh2005sundials", citations._papers_to_cite)
Ejemplo n.º 9
0
    def test_model_solver_multiple_inputs_jax_format_error(self):
        # Create model
        model = pybamm.BaseModel()
        model.convert_to_format = "jax"
        domain = ["negative electrode", "separator", "positive electrode"]
        var = pybamm.Variable("var", domain=domain)
        model.rhs = {var: -pybamm.InputParameter("rate") * var}
        model.initial_conditions = {var: 2 * pybamm.InputParameter("rate")}
        # No need to set parameters; can use base discretisation (no spatial
        # operators)
        # create discretisation
        mesh = get_mesh_for_testing()
        spatial_methods = {"macroscale": pybamm.FiniteVolume()}
        disc = pybamm.Discretisation(mesh, spatial_methods)
        disc.process_model(model)

        solver = pybamm.ScipySolver(rtol=1e-8, atol=1e-8, method="RK45")
        t_eval = np.linspace(0, 10, 100)
        ninputs = 8
        inputs_list = [{"rate": 0.01 * (i + 1)} for i in range(ninputs)]

        with self.assertRaisesRegex(
            pybamm.SolverError,
            (
                "Cannot solve list of inputs with multiprocessing "
                'when model in format "jax".'
            ),
        ):
            solver.solve(model, t_eval, inputs=inputs_list, nproc=2)
Ejemplo n.º 10
0
    def test_model_solver_multiple_inputs_discontinuity_error(self):
        # Create model
        model = pybamm.BaseModel()
        model.convert_to_format = "casadi"
        domain = ["negative electrode", "separator", "positive electrode"]
        var = pybamm.Variable("var", domain=domain)
        model.rhs = {var: -pybamm.InputParameter("rate") * var}
        model.initial_conditions = {var: 1}
        # create discretisation
        mesh = get_mesh_for_testing()
        spatial_methods = {"macroscale": pybamm.FiniteVolume()}
        disc = pybamm.Discretisation(mesh, spatial_methods)
        disc.process_model(model)

        solver = pybamm.ScipySolver(rtol=1e-8, atol=1e-8, method="RK45")
        t_eval = np.linspace(0, 10, 100)
        ninputs = 8
        inputs_list = [{"rate": 0.01 * (i + 1)} for i in range(ninputs)]

        model.events = [
            pybamm.Event(
                "discontinuity",
                pybamm.Scalar(t_eval[-1] / 2),
                event_type=pybamm.EventType.DISCONTINUITY,
            )
        ]
        with self.assertRaisesRegex(
            pybamm.SolverError,
            (
                "Cannot solve for a list of input parameters"
                " sets with discontinuities"
            ),
        ):
            solver.solve(model, t_eval, inputs=inputs_list, nproc=2)
Ejemplo n.º 11
0
    def test_model_solver_multiple_inputs_happy_path(self):
        for convert_to_format in ["python", "casadi"]:
            # Create model
            model = pybamm.BaseModel()
            model.convert_to_format = convert_to_format
            domain = ["negative electrode", "separator", "positive electrode"]
            var = pybamm.Variable("var", domain=domain)
            model.rhs = {var: -pybamm.InputParameter("rate") * var}
            model.initial_conditions = {var: 1}
            # create discretisation
            mesh = get_mesh_for_testing()
            spatial_methods = {"macroscale": pybamm.FiniteVolume()}
            disc = pybamm.Discretisation(mesh, spatial_methods)
            disc.process_model(model)

            solver = pybamm.ScipySolver(rtol=1e-8, atol=1e-8, method="RK45")
            t_eval = np.linspace(0, 10, 100)
            ninputs = 8
            inputs_list = [{"rate": 0.01 * (i + 1)} for i in range(ninputs)]

            solutions = solver.solve(model, t_eval, inputs=inputs_list, nproc=2)
            for i in range(ninputs):
                with self.subTest(i=i):
                    solution = solutions[i]
                    np.testing.assert_array_equal(solution.t, t_eval)
                    np.testing.assert_allclose(
                        solution.y[0], np.exp(-0.01 * (i + 1) * solution.t)
                    )
Ejemplo n.º 12
0
    def test_step_different_model(self):
        disc = pybamm.Discretisation()

        # Create and discretise model1
        model1 = pybamm.BaseModel()
        var = pybamm.Variable("var")
        var2 = pybamm.Variable("var2")
        model1.rhs = {var: 0.1 * var}
        model1.initial_conditions = {var: 1}
        model1.variables = {"var": var, "mul_var": 2 * var, "var2": var}
        disc.process_model(model1)

        # Create and discretise model2, which is slightly different
        model2 = pybamm.BaseModel()
        var = pybamm.Variable("var")
        var2 = pybamm.Variable("var2")
        model2.rhs = {var: 0.2 * var, var2: -0.5 * var2}
        model2.initial_conditions = {var: 1, var2: 1}
        model2.variables = {"var": var, "mul_var": 3 * var, "var2": var2}
        disc.process_model(model2)

        solver = pybamm.ScipySolver(rtol=1e-8, atol=1e-8, method="RK45")

        # Step once
        dt = 1
        step_sol1 = solver.step(None, model1, dt)
        np.testing.assert_array_equal(step_sol1.t, [0, dt])
        np.testing.assert_array_almost_equal(step_sol1.y[0], np.exp(0.1 * step_sol1.t))

        # Step again, the model has changed
        step_sol2 = solver.step(step_sol1, model2, dt)
        np.testing.assert_array_equal(step_sol2.t, [0, dt, 2 * dt])
        np.testing.assert_array_almost_equal(
            step_sol2.all_ys[0][0], np.exp(0.1 * step_sol1.t)
        )
Ejemplo n.º 13
0
    def test_model_solver_with_event_with_casadi(self):
        # Create model
        model = pybamm.BaseModel()
        for use_jacobian in [True, False]:
            model.use_jacobian = use_jacobian
            model.convert_to_format = "casadi"
            domain = ["negative electrode", "separator", "positive electrode"]
            var = pybamm.Variable("var", domain=domain)
            model.rhs = {var: -0.1 * var}
            model.initial_conditions = {var: 1}
            model.events = {"var=0.5": pybamm.min(var - 0.5)}
            # No need to set parameters; can use base discretisation (no spatial
            # operators)

            # create discretisation
            mesh = get_mesh_for_testing()
            spatial_methods = {"macroscale": pybamm.FiniteVolume}
            disc = pybamm.Discretisation(mesh, spatial_methods)
            disc.process_model(model)
            # Solve
            solver = pybamm.ScipySolver(rtol=1e-8, atol=1e-8, method="RK45")
            t_eval = np.linspace(0, 10, 100)
            solution = solver.solve(model, t_eval)
            self.assertLess(len(solution.t), len(t_eval))
            np.testing.assert_array_equal(solution.t, t_eval[:len(solution.t)])
            np.testing.assert_allclose(solution.y[0],
                                       np.exp(-0.1 * solution.t))
Ejemplo n.º 14
0
 def test_ode_solver_fail_with_dae(self):
     model = pybamm.BaseModel()
     a = pybamm.Scalar(1)
     model.algebraic = {a: a}
     model.concatenated_initial_conditions = pybamm.Scalar(0)
     solver = pybamm.ScipySolver()
     with self.assertRaisesRegex(pybamm.SolverError, "Cannot use ODE solver"):
         solver.set_up(model)
Ejemplo n.º 15
0
 def default_solver(self):
     "Return default solver based on whether model is ODE model or DAE model"
     if len(self.algebraic) == 0:
         return pybamm.ScipySolver()
     elif pybamm.have_idaklu() and self.use_jacobian is True:
         # KLU solver requires jacobian to be provided
         return pybamm.IDAKLUSolver()
     else:
         return pybamm.CasadiSolver(mode="safe")
Ejemplo n.º 16
0
    def default_solver(self):
        """
        Create and return the default solver for this model
        """

        if (self.options["current collector"] != "uniform"
                or self.options["surface form"] == "algebraic"):
            return pybamm.ScikitsDaeSolver()
        else:
            return pybamm.ScipySolver()
Ejemplo n.º 17
0
 def default_solver(self):
     """
     Create and return the default solver for this model
     """
     # Different solver depending on whether we solve ODEs or DAEs
     if (self.options["surface form"] == "differential"
             and self.options["current collector"] == "uniform"):
         return pybamm.ScipySolver()
     else:
         return pybamm.ScikitsDaeSolver()
Ejemplo n.º 18
0
 def default_solver(self):
     """
     Create and return the default solver for this model
     """
     # Different solver depending on whether we solve ODEs or DAEs
     dimensionality = self.options["dimensionality"]
     if dimensionality == 0:
         return pybamm.ScipySolver()
     else:
         return pybamm.ScikitsDaeSolver()
Ejemplo n.º 19
0
 def default_solver(self):
     """
     Return default solver based on whether model is ODE model or DAE model.
     There are bugs with KLU on the lead-acid models.
     """
     if len(self.algebraic) == 0:
         return pybamm.ScipySolver()
     elif pybamm.have_scikits_odes():
         return pybamm.ScikitsDaeSolver()
     else:  # pragma: no cover
         return pybamm.CasadiSolver(mode="safe")
Ejemplo n.º 20
0
    def test_save(self):
        model = pybamm.BaseModel()
        # create both 1D and 2D variables
        c = pybamm.Variable("c")
        d = pybamm.Variable("d", domain="negative electrode")
        model.rhs = {c: -c, d: 1}
        model.initial_conditions = {c: 1, d: 2}
        model.variables = {"c": c, "d": d, "2c": 2 * c}

        disc = get_discretisation_for_testing()
        disc.process_model(model)
        solution = pybamm.ScipySolver().solve(model, np.linspace(0, 1))

        # test save data
        with self.assertRaises(ValueError):
            solution.save_data("test.pickle")
        # set variables first then save
        solution.update(["c", "d"])
        solution.save_data("test.pickle")
        data_load = pybamm.load("test.pickle")
        np.testing.assert_array_equal(solution.data["c"], data_load["c"])
        np.testing.assert_array_equal(solution.data["d"], data_load["d"])

        # to matlab
        solution.save_data("test.mat", to_format="matlab")
        data_load = loadmat("test.mat")
        np.testing.assert_array_equal(solution.data["c"],
                                      data_load["c"].flatten())
        np.testing.assert_array_equal(solution.data["d"], data_load["d"])

        # to csv
        with self.assertRaisesRegex(ValueError,
                                    "only 0D variables can be saved to csv"):
            solution.save_data("test.csv", to_format="csv")
        # only save "c" and "2c"
        solution.save_data("test.csv", ["c", "2c"], to_format="csv")
        # read csv
        df = pd.read_csv("test.csv")
        np.testing.assert_array_almost_equal(df["c"], solution.data["c"])
        np.testing.assert_array_almost_equal(df["2c"], solution.data["2c"])

        # raise error if format is unknown
        with self.assertRaisesRegex(ValueError,
                                    "format 'wrong_format' not recognised"):
            solution.save_data("test.csv", to_format="wrong_format")

        # test save whole solution
        solution.save("test.pickle")
        solution_load = pybamm.load("test.pickle")
        self.assertEqual(solution.model.name, solution_load.model.name)
        np.testing.assert_array_equal(solution["c"].entries,
                                      solution_load["c"].entries)
        np.testing.assert_array_equal(solution["d"].entries,
                                      solution_load["d"].entries)
Ejemplo n.º 21
0
    def test_ode_integrate_with_jacobian(self):
        # Linear
        solver = pybamm.ScipySolver(rtol=1e-8, atol=1e-8, method="BDF")

        def linear_ode(t, y):
            return np.array([0.5 * np.ones_like(y[0]), 2.0 - y[0]])

        def jacobian(t, y):
            return np.array([[0.0, 0.0], [-1.0, 0.0]])

        y0 = np.array([0.0, 0.0])
        t_eval = np.linspace(0, 1, 100)
        solution = solver.integrate(linear_ode, y0, t_eval, jacobian=jacobian)
        np.testing.assert_array_equal(solution.t, t_eval)
        np.testing.assert_allclose(0.5 * solution.t, solution.y[0])
        np.testing.assert_allclose(2.0 * solution.t - 0.25 * solution.t**2,
                                   solution.y[1],
                                   rtol=1e-4)

        # Nonlinear exponential grwoth
        solver = pybamm.ScipySolver(rtol=1e-8, atol=1e-8, method="BDF")

        def exponential_growth(t, y):
            return np.array([y[0], (1.0 - y[0]) * y[1]])

        def jacobian(t, y):
            return np.array([[1.0, 0.0], [-y[1], 1 - y[0]]])

        y0 = np.array([1.0, 1.0])
        t_eval = np.linspace(0, 1, 100)
        solution = solver.integrate(exponential_growth,
                                    y0,
                                    t_eval,
                                    jacobian=jacobian)
        np.testing.assert_array_equal(solution.t, t_eval)
        np.testing.assert_allclose(np.exp(solution.t),
                                   solution.y[0],
                                   rtol=1e-4)
        np.testing.assert_allclose(np.exp(1 + solution.t - np.exp(solution.t)),
                                   solution.y[1],
                                   rtol=1e-4)
Ejemplo n.º 22
0
    def test_model_solver_ode_with_jacobian(self):
        # Create model
        model = pybamm.BaseModel()
        whole_cell = ["negative electrode", "separator", "positive electrode"]
        var1 = pybamm.Variable("var1", domain=whole_cell)
        var2 = pybamm.Variable("var2", domain=whole_cell)
        model.rhs = {var1: var1, var2: 1 - var1}
        model.initial_conditions = {var1: 1.0, var2: -1.0}
        model.variables = {"var1": var1, "var2": var2}

        # create discretisation
        mesh = get_mesh_for_testing()
        spatial_methods = {"macroscale": pybamm.FiniteVolume}
        disc = pybamm.Discretisation(mesh, spatial_methods)
        disc.process_model(model)

        # Add user-supplied Jacobian to model
        combined_submesh = mesh.combine_submeshes("negative electrode",
                                                  "separator",
                                                  "positive electrode")
        N = combined_submesh[0].npts

        # construct jacobian in order of model.rhs
        J = []
        for var in model.rhs.keys():
            if var.id == var1.id:
                J.append([np.eye(N), np.zeros((N, N))])
            else:
                J.append([-1.0 * np.eye(N), np.zeros((N, N))])

        J = np.block(J)

        def jacobian(t, y):
            return J

        model.jacobian = jacobian

        # Solve
        solver = pybamm.ScipySolver(rtol=1e-9, atol=1e-9)
        t_eval = np.linspace(0, 1, 100)
        solution = solver.solve(model, t_eval)
        np.testing.assert_array_equal(solution.t, t_eval)

        T, Y = solution.t, solution.y
        np.testing.assert_array_almost_equal(
            model.variables["var1"].evaluate(T, Y),
            np.ones((N, T.size)) * np.exp(T[np.newaxis, :]),
        )
        np.testing.assert_array_almost_equal(
            model.variables["var2"].evaluate(T, Y),
            np.ones(
                (N, T.size)) * (T[np.newaxis, :] - np.exp(T[np.newaxis, :])),
        )
Ejemplo n.º 23
0
    def test_plot(self):
        model = pybamm.BaseModel()
        c = pybamm.Variable("c")
        model.rhs = {c: -c}
        model.initial_conditions = {c: 1}
        model.variables["c"] = c
        model.variables["2c"] = 2 * c

        disc = pybamm.Discretisation()
        disc.process_model(model)
        solution = pybamm.ScipySolver().solve(model, np.linspace(0, 1))

        solution.plot(["c", "2c"], testing=True)
Ejemplo n.º 24
0
    def test_solve_non_battery_model(self):

        model = pybamm.BaseModel()
        v = pybamm.Variable("v")
        model.rhs = {v: -v}
        model.initial_conditions = {v: 1}
        model.variables = {"v": v}
        sim = pybamm.Simulation(model,
                                solver=pybamm.ScipySolver(rtol=1e-10,
                                                          atol=1e-10))

        sim.solve(np.linspace(0, 1, 100))
        np.testing.assert_array_equal(sim.solution.t, np.linspace(0, 1, 100))
        np.testing.assert_array_almost_equal(sim.solution["v"].entries,
                                             np.exp(-np.linspace(0, 1, 100)))
Ejemplo n.º 25
0
    def test_integrate(self):
        # Constant
        solver = pybamm.ScipySolver(rtol=1e-8, atol=1e-8, method="RK45")

        def constant_growth(t, y):
            return 0.5 * np.ones_like(y)

        y0 = np.array([0])
        t_eval = np.linspace(0, 1, 100)
        solution = solver.integrate(constant_growth, y0, t_eval)
        np.testing.assert_array_equal(solution.t, t_eval)
        np.testing.assert_allclose(0.5 * solution.t, solution.y[0])

        # Exponential decay
        solver = pybamm.ScipySolver(rtol=1e-8, atol=1e-8, method="BDF")

        def exponential_decay(t, y):
            return -0.1 * y

        y0 = np.array([1])
        t_eval = np.linspace(0, 1, 100)
        solution = solver.integrate(exponential_decay, y0, t_eval)
        np.testing.assert_allclose(solution.y[0], np.exp(-0.1 * solution.t))
        self.assertEqual(solution.termination, "final time")
Ejemplo n.º 26
0
    def test_root_method_init(self):
        solver = pybamm.BaseSolver(root_method="casadi")
        self.assertIsInstance(solver.root_method, pybamm.CasadiAlgebraicSolver)

        solver = pybamm.BaseSolver(root_method="lm")
        self.assertIsInstance(solver.root_method, pybamm.AlgebraicSolver)
        self.assertEqual(solver.root_method.method, "lm")

        root_solver = pybamm.AlgebraicSolver()
        solver = pybamm.BaseSolver(root_method=root_solver)
        self.assertEqual(solver.root_method, root_solver)

        with self.assertRaisesRegex(pybamm.SolverError,
                                    "Root method must be an algebraic solver"):
            pybamm.BaseSolver(root_method=pybamm.ScipySolver())
Ejemplo n.º 27
0
    def test_integrate_failure(self):
        # Turn off warnings to ignore sqrt error
        warnings.simplefilter("ignore")

        def sqrt_decay(t, y):
            return -np.sqrt(y)

        y0 = np.array([1])
        t_eval = np.linspace(0, 3, 100)
        solver = pybamm.ScipySolver(rtol=1e-8, atol=1e-8, method="RK45")
        # Expect solver to fail when y goes negative
        with self.assertRaises(pybamm.SolverError):
            solver.integrate(sqrt_decay, y0, t_eval)

        # Turn warnings back on
        warnings.simplefilter("default")
Ejemplo n.º 28
0
def pybamm1():
    model = pybamm.BaseModel()

    x = pybamm.Variable("x")
    y = pybamm.Variable("y")

    dxdt = 4 * x - 2 * y
    dydt = 3 * x - y

    model.rhs = {x: dxdt, y: dydt}
    model.initial_conditions = {x: pybamm.Scalar(1), y: pybamm.Scalar(2)}
    model.variables = {"x": x, "y": y, "z": x + 4 * y}

    disc = pybamm.Discretisation()  # use the default discretisation
    disc.process_model(model)

    solver = pybamm.ScipySolver()
    t = np.linspace(0, 1, 20)
    solution = solver.solve(model, t)

    t_sol, y_sol = solution.t, solution.y  # get solution times and states
    x = solution["x"]  # extract and process x from the solution
    y = solution["y"]  # extract and process y from the solution

    t_fine = np.linspace(0, t[-1], 1000)

    fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(13, 4))
    ax1.plot(t_fine, 2 * np.exp(t_fine) - np.exp(2 * t_fine), t_sol, x(t_sol),
             "o")
    ax1.set_xlabel("t")
    ax1.legend(["2*exp(t) - exp(2*t)", "x"], loc="best")

    ax2.plot(t_fine, 3 * np.exp(t_fine) - np.exp(2 * t_fine), t_sol, y(t_sol),
             "o")
    ax2.set_xlabel("t")
    ax2.legend(["3*exp(t) - exp(2*t)", "y"], loc="best")

    plt.tight_layout()
    # img = plt.show()

    plt.savefig('foo.png', bbox_inches='tight')  # Saving the graph
Ejemplo n.º 29
0
    def test_model_solver_failure(self):
        # Turn off warnings to ignore sqrt error
        warnings.simplefilter("ignore")
        model = pybamm.BaseModel()
        model.convert_to_format = "python"
        var = pybamm.Variable("var")
        model.rhs = {var: -pybamm.sqrt(var)}
        model.initial_conditions = {var: 1}
        # No need to set parameters; can use base discretisation (no spatial operators)

        # create discretisation
        disc = pybamm.Discretisation()
        disc.process_model(model)

        t_eval = np.linspace(0, 3, 100)
        solver = pybamm.ScipySolver(rtol=1e-8, atol=1e-8, method="RK45")
        # Expect solver to fail when y goes negative
        with self.assertRaises(pybamm.SolverError):
            solver.solve(model, t_eval)

        # Turn warnings back on
        warnings.simplefilter("default")
Ejemplo n.º 30
0
    def test_model_solver_manually_update_initial_conditions(self):
        # Create model
        model = pybamm.BaseModel()
        var1 = pybamm.Variable("var1")
        model.rhs = {var1: -var1}
        model.initial_conditions = {var1: 1}

        # Solve
        solver = pybamm.ScipySolver(rtol=1e-8, atol=1e-8)
        t_eval = np.linspace(0, 5, 100)
        solution = solver.solve(model, t_eval)
        np.testing.assert_array_almost_equal(solution.y[0],
                                             1 * np.exp(-solution.t),
                                             decimal=5)

        # Change initial conditions and solve again
        model.concatenated_initial_conditions = pybamm.NumpyConcatenation(
            pybamm.Vector([[2]]))
        solution = solver.solve(model, t_eval)
        np.testing.assert_array_almost_equal(solution.y[0],
                                             2 * np.exp(-solution.t),
                                             decimal=5)