TEST_F(VanishesBeforeTest, Dimensionless) { double const y = 3000.0 * std::numeric_limits<double>::epsilon(); EXPECT_THAT(y, VanishesBefore(1000.0, 6)); EXPECT_THAT(2 * y, Not(VanishesBefore(1000.0, 6))); double const δy = e / 100.0; double e_accumulated = 0.0; for (int i = 1; i <= 100.0; ++i) { e_accumulated += δy; } EXPECT_THAT(e_accumulated, Ne(e)); EXPECT_THAT(e_accumulated - e, Not(VanishesBefore(e, 4))); EXPECT_THAT(e_accumulated - e, VanishesBefore(e, 1)); }
TEST_F(VanishesBeforeTest, Quantity) { Speed v1 = 1 * Knot; Speed const v2 = 3 * v1 * std::numeric_limits<double>::epsilon(); EXPECT_THAT(v2, VanishesBefore(v1, 3)); EXPECT_THAT(2 * v2, Not(VanishesBefore(v1, 3))); Speed const δv = v1 / 100; Speed v_accumulated; for (int i = 1; i <= 100; ++i) { v_accumulated += δv; } EXPECT_THAT(v_accumulated, Ne(v1)); EXPECT_THAT(v_accumulated - v1, Not(VanishesBefore(v1, 8))); EXPECT_THAT(v_accumulated - v1, VanishesBefore(v1, 4)); }
TEST_F(VanishesBeforeTest, Describe) { Speed v1 = 1 * SIUnit<Speed>(); { std::ostringstream out; VanishesBefore(v1, 2, 6).impl().DescribeTo(&out); EXPECT_EQ("vanishes before +1.00000000000000000e+00 m s^-1 " "to within 2 to 6 ULPs", out.str()); } { std::ostringstream out; VanishesBefore(v1, 2, 6).impl().DescribeNegationTo(&out); EXPECT_EQ("does not vanish before +1.00000000000000000e+00 m s^-1 " "to within 2 to 6 ULP", out.str()); } }
void TestTimeReversibility(Integrator const& integrator) { Length const q_initial = 1 * Metre; Speed const v_initial = 0 * Metre / Second; Speed const v_amplitude = 1 * Metre / Second; Instant const t_initial; Instant const t_final = t_initial + 100 * Second; Time const step = 1 * Second; std::vector<ODE::SystemState> solution; ODE harmonic_oscillator; harmonic_oscillator.compute_acceleration = std::bind(ComputeHarmonicOscillatorAcceleration, _1, _2, _3, /*evaluations=*/nullptr); IntegrationProblem<ODE> problem; problem.equation = harmonic_oscillator; ODE::SystemState const initial_state = {{q_initial}, {v_initial}, t_initial}; ODE::SystemState final_state; problem.initial_state = &initial_state; problem.t_final = t_final; problem.append_state = [&final_state](ODE::SystemState const& state) { final_state = state; }; integrator.Solve(problem, step); problem.initial_state = &final_state; problem.t_final = t_initial; integrator.Solve(problem, -step); EXPECT_EQ(t_initial, final_state.time.value); if (integrator.time_reversible) { EXPECT_THAT(final_state.positions[0].value, AlmostEquals(q_initial, 0, 8)); EXPECT_THAT(final_state.velocities[0].value, VanishesBefore(v_amplitude, 0, 16)); } else { EXPECT_THAT(AbsoluteError(q_initial, final_state.positions[0].value), Gt(1e-4 * Metre)); EXPECT_THAT(AbsoluteError(v_initial, final_state.velocities[0].value), Gt(1e-4 * Metre / Second)); } }
// The test point is at the origin and in motion. The acceleration is purely // due to Coriolis. TEST_F(BodySurfaceDynamicFrameTest, CoriolisAcceleration) { Instant const t = t0_ + 0 * Second; // The velocity is opposed to the motion and away from the centre. DegreesOfFreedom<MockFrame> const point_dof = {Displacement<MockFrame>({0 * Metre, 0 * Metre, 0 * Metre}) + MockFrame::origin, Velocity<MockFrame>({10 * Metre / Second, 20 * Metre / Second, 30 * Metre / Second})}; DegreesOfFreedom<ICRFJ2000Equator> const centre_dof = {Displacement<ICRFJ2000Equator>({0 * Metre, 0 * Metre, 0 * Metre}) + ICRFJ2000Equator::origin, Velocity<ICRFJ2000Equator>()}; EXPECT_CALL(mock_centre_trajectory_, EvaluateDegreesOfFreedom(t, _)) .Times(2) .WillRepeatedly(Return(centre_dof)); { InSequence s; EXPECT_CALL(*mock_ephemeris_, ComputeGravitationalAccelerationOnMassiveBody( check_not_null(massive_centre_), t)) .WillOnce(Return(Vector<Acceleration, ICRFJ2000Equator>({ 0 * Metre / Pow<2>(Second), 0 * Metre / Pow<2>(Second), 0 * Metre / Pow<2>(Second)}))); EXPECT_CALL(*mock_ephemeris_, ComputeGravitationalAccelerationOnMasslessBody(_, t)) .WillOnce(Return(Vector<Acceleration, ICRFJ2000Equator>())); } // The Coriolis acceleration is towards the centre and opposed to the motion. EXPECT_THAT(mock_frame_->GeometricAcceleration(t, point_dof).coordinates(), Componentwise(AlmostEquals(400 * Metre / Pow<2>(Second), 1), AlmostEquals(-200 * Metre / Pow<2>(Second), 0), VanishesBefore(1 * Metre / Pow<2>(Second), 110))); }