示例#1
0
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));
}
示例#2
0
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));
}
示例#3
0
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)));
}