def test_symplectic_against_undamped_harmonic_oscillator(self, stepper):
        system = SymplecticUndampedSimpleHarmonicOscillatorSystem(
            omega=1.0 * np.pi, init_val=np.array([0.2, 0.8]))
        final_time = 4.0 * np.pi
        n_steps = 2000
        time_stepper = stepper()
        integrate(time_stepper, system, final_time=final_time, n_steps=n_steps)

        # Symplectic systems conserve energy to a certain extent
        assert_allclose(
            *system.compute_energy(final_time),
            rtol=Tolerance.rtol() * 1e1,
            atol=Tolerance.atol(),
        )
    def test_symplectic_steppers(self, symplectic_stepper):
        collective_system = SymplecticUndampedHarmonicOscillatorCollectiveSystem(
        )
        final_time = 1.0
        n_steps = 2000
        stepper = symplectic_stepper()
        integrate(stepper,
                  collective_system,
                  final_time=final_time,
                  n_steps=n_steps)

        for system in collective_system:
            assert_allclose(
                *system.compute_energy(final_time),
                rtol=Tolerance.rtol() * 1e1,
                atol=Tolerance.atol(),
            )
    def test_symplectics_against_ellipse_motion(self, symplectic_stepper):
        from elastica._elastica_numba._systems._analytical import (
            make_simple_system_with_positions_directors,
            SimpleSystemWithPositionsDirectors,
        )

        random_start_position = np.random.randn(3, 1)
        random_end_position = np.random.randn(3, 1)
        random_directors, _ = np.linalg.qr(np.random.randn(3, 3))
        random_directors = random_directors.reshape(3, 3, 1)

        rod_like_system = make_simple_system_with_positions_directors(
            random_start_position, random_end_position, random_directors)
        final_time = 1.0
        n_steps = 1000
        stepper = symplectic_stepper()

        integrate(stepper,
                  rod_like_system,
                  final_time=final_time,
                  n_steps=n_steps)

        assert_allclose(
            rod_like_system.position_collection,
            rod_like_system.analytical_solution("Positions", final_time),
            rtol=Tolerance.rtol() * 1e1,
            atol=Tolerance.atol(),
        )

        assert_allclose(
            rod_like_system.velocity_collection,
            rod_like_system.analytical_solution("Velocity", final_time),
            rtol=Tolerance.rtol() * 1e1,
            atol=Tolerance.atol(),
        )

        # Reshaping done in the director collection to prevent numba from
        # complaining about returning multiple types
        assert_allclose(
            rod_like_system.director_collection.reshape(-1, 1),
            rod_like_system.analytical_solution("Directors", final_time),
            rtol=Tolerance.rtol() * 1e1,
            atol=Tolerance.atol(),
        )
def test_integrate_throws_an_assert_for_negative_total_steps():
    with pytest.raises(AssertionError) as excinfo:
        integrate([], [], np.random.rand(1), -np.random.randint(100, 10000))
    assert "steps is negative" in str(excinfo.value)
def test_integrate_throws_an_assert_for_negative_final_time():
    with pytest.raises(AssertionError) as excinfo:
        integrate([], [], -np.random.rand(1))
    assert "time is negative" in str(excinfo.value)