Source code for tests.test_ODE

""" Test the properties of ODE solvers

.. autosummary::
    :toctree: _generated/
    :template: tests-formatting/base.rst
    :nosignatures:

    test_Implicit_ODE
    test_Explicit_ODE

"""

import pytest
from .test_config import *
import numpy as np
import choreo

[docs] @ParametrizeDocstrings @pytest.mark.parametrize(("method_x", "method_v"), [(method_x, method_v) for (method_x, method_v) in SymplecticImplicitRKMethodPairs]) @pytest.mark.parametrize("nsteps", Small_orders) @pytest.mark.parametrize("ivp", [pytest.param(define_ODE_ivp(eq_name), id=eq_name) for eq_name in all_eq_names]) @pytest.mark.parametrize("fun_type", all_fun_types) @pytest.mark.parametrize("vector_calls", [True, False]) @pytest.mark.parametrize("DoEFT", [True, False]) def test_Implicit_ODE(float64_tols, method_x, method_v, nsteps, ivp, fun_type, vector_calls, DoEFT): """Tests the accuracy of implicit ODE solvers. """ rk_x = choreo.scipy_plus.multiprec_tables.ComputeImplicitRKTable_Gauss(nsteps, method = method_x) rk_v = choreo.scipy_plus.multiprec_tables.ComputeImplicitRKTable_Gauss(nsteps, method = method_v) fgun = ivp["fgun"].get((fun_type, vector_calls)) if fgun is None: return fun, gun = fgun t_span = ivp["t_span"] ex_sol_x = ivp["ex_sol_x"] ex_sol_v = ivp["ex_sol_v"] nint_OK = ivp["nint"](rk_x.th_cvg_rate) if nint_OK is None: nint = 1 else: nint = nint_OK x0 = ex_sol_x(t_span[0]) v0 = ex_sol_v(t_span[0]) xf, vf = choreo.scipy_plus.ODE.ImplicitSymplecticIVP( fun , gun , t_span , x0 , v0 , rk_x = rk_x , rk_v = rk_v , vector_calls = vector_calls , nint = nint , DoEFT = DoEFT , ) xf_ex = ex_sol_x(t_span[1]) vf_ex = ex_sol_v(t_span[1]) print(np.linalg.norm(xf-xf_ex)) if nint_OK is not None: assert np.allclose(xf, xf_ex, rtol = float64_tols.rtol, atol = float64_tols.atol) print(np.linalg.norm(vf-vf_ex)) if nint_OK is not None: assert np.allclose(vf, vf_ex, rtol = float64_tols.rtol, atol = float64_tols.atol)
[docs] @ParametrizeDocstrings @pytest.mark.parametrize("rk", [pytest.param(rk, id=name) for name, rk in Explicit_tables_dict.items()]) @pytest.mark.parametrize("ivp", [pytest.param(define_ODE_ivp(eq_name), id=eq_name) for eq_name in all_eq_names]) @pytest.mark.parametrize("fun_type", all_fun_types) @pytest.mark.parametrize("DoEFT", [True, False]) def test_Explicit_ODE(float64_tols, rk, ivp, fun_type, DoEFT): """Tests the accuracy of explicit ODE solvers. """ fgun = ivp["fgun"].get((fun_type, False)) if fgun is None: return fun, gun = fgun t_span = ivp["t_span"] ex_sol_x = ivp["ex_sol_x"] ex_sol_v = ivp["ex_sol_v"] nint_OK = ivp["nint"](rk.th_cvg_rate) if nint_OK is None: nint = 1 else: nint = nint_OK x0 = ex_sol_x(t_span[0]) v0 = ex_sol_v(t_span[0]) xf, vf = choreo.scipy_plus.ODE.ExplicitSymplecticIVP( fun , gun , t_span , x0 , v0 , rk = rk , nint = nint , DoEFT = DoEFT , ) xf_ex = ex_sol_x(t_span[1]) vf_ex = ex_sol_v(t_span[1]) print(np.linalg.norm(xf-xf_ex)) if nint_OK is not None: assert np.allclose(xf, xf_ex, rtol = float64_tols.rtol, atol = float64_tols.atol) print(np.linalg.norm(vf-vf_ex)) if nint_OK is not None: assert np.allclose(vf, vf_ex, rtol = float64_tols.rtol, atol = float64_tols.atol)