// Check that the small body has the right degrees of freedom in the frame of
// the big body.
TEST_F(BodyCentredNonRotatingDynamicFrameTest, SmallBodyInBigFrame) {
  int const kSteps = 100;
  Bivector<double, ICRFJ2000Equator> const axis({0, 0, 1});

  RelativeDegreesOfFreedom<ICRFJ2000Equator> const initial_big_to_small =
      small_initial_state_ - big_initial_state_;
  ContinuousTrajectory<ICRFJ2000Equator>::Hint hint;
  for (Instant t = t0_; t < t0_ + 1 * period_; t += period_ / kSteps) {
    DegreesOfFreedom<ICRFJ2000Equator> const small_in_inertial_frame_at_t =
        solar_system_.trajectory(*ephemeris_, kSmall).
            EvaluateDegreesOfFreedom(t, &hint);

    auto const rotation_in_big_frame_at_t =
        Rotation<ICRFJ2000Equator, Big>(-2 * π * (t - t0_) * Radian / period_,
                                        axis);
    DegreesOfFreedom<Big> const small_in_big_frame_at_t(
        rotation_in_big_frame_at_t(initial_big_to_small.displacement()) +
            Big::origin,
        rotation_in_big_frame_at_t(initial_big_to_small.velocity()));

    auto const to_big_frame_at_t = big_frame_->ToThisFrameAtTime(t);
    EXPECT_THAT(AbsoluteError(
                    to_big_frame_at_t(small_in_inertial_frame_at_t).position(),
                    small_in_big_frame_at_t.position()),
                Lt(0.3 * Milli(Metre)));
    EXPECT_THAT(AbsoluteError(
                    to_big_frame_at_t(small_in_inertial_frame_at_t).velocity(),
                    small_in_big_frame_at_t.velocity()),
                Lt(4 * Milli(Metre) / Second));
  }
}
void Test1000SecondsAt1Millisecond(
    Integrator const& integrator,
    Length const& expected_position_error,
    Speed const& expected_velocity_error) {
  Length const q_initial = 1 * Metre;
  Speed const v_initial = 0 * Metre / Second;
  Speed const v_amplitude = 1 * Metre / Second;
  AngularFrequency const ω = 1 * Radian / Second;
  Instant const t_initial;
#if defined(_DEBUG)
  Instant const t_final = t_initial + 1 * Second;
#else
  Instant const t_final = t_initial + 1000 * Second;
#endif
  Time const step = 1 * Milli(Second);
  int const steps = static_cast<int>((t_final - t_initial) / step) - 1;

  int evaluations = 0;

  std::vector<ODE::SystemState> solution;
  ODE harmonic_oscillator;
  harmonic_oscillator.compute_acceleration =
      std::bind(ComputeHarmonicOscillatorAcceleration,
                _1, _2, _3, &evaluations);
  IntegrationProblem<ODE> problem;
  problem.equation = harmonic_oscillator;
  ODE::SystemState const initial_state = {{q_initial}, {v_initial}, t_initial};
  problem.initial_state = &initial_state;
  auto append_state = [&solution](ODE::SystemState const& state) {
    solution.push_back(state);
  };

  auto const instance =
      integrator.NewInstance(problem, std::move(append_state), step);
  integrator.Solve(t_final, *instance);

  EXPECT_EQ(steps, solution.size());
  Length q_error;
  Speed v_error;
  for (int i = 0; i < steps; ++i) {
    Length const q = solution[i].positions[0].value;
    Speed const v = solution[i].velocities[0].value;
    Time const t = solution[i].time.value - t_initial;
    EXPECT_THAT(t, AlmostEquals((i + 1) * step, 0));
    // TODO(egg): we may need decent trig functions for this sort of thing.
    q_error = std::max(q_error, AbsoluteError(q_initial * Cos(ω * t), q));
    v_error = std::max(v_error, AbsoluteError(-v_amplitude * Sin(ω * t), v));
  }
#if !defined(_DEBUG)
  EXPECT_EQ(expected_position_error, q_error);
  EXPECT_EQ(expected_velocity_error, v_error);
#endif
}
TEST_F(BodyCentredNonRotatingDynamicFrameTest, GeometricAcceleration) {
  int const kSteps = 10;
  RelativeDegreesOfFreedom<ICRFJ2000Equator> const initial_big_to_small =
      small_initial_state_ - big_initial_state_;
  Length const big_to_small = initial_big_to_small.displacement().Norm();
  Acceleration const small_on_big =
      small_gravitational_parameter_ / (big_to_small * big_to_small);
  for (Length y = big_to_small / kSteps;
       y < big_to_small;
       y += big_to_small / kSteps) {
    Position<Big> const position(Big::origin +
                                     Displacement<Big>({0 * Kilo(Metre),
                                                        y,
                                                        0 * Kilo(Metre)}));
    Acceleration const big_on_position =
        -big_gravitational_parameter_ / (y * y);
    Acceleration const small_on_position =
        small_gravitational_parameter_ /
            ((big_to_small - y) * (big_to_small - y));
    Vector<Acceleration, Big> const expected_acceleration(
                  {0 * SIUnit<Acceleration>(),
                   small_on_position + big_on_position - small_on_big,
                   0 * SIUnit<Acceleration>()});
    EXPECT_THAT(AbsoluteError(
                    big_frame_->GeometricAcceleration(
                        t0_,
                        DegreesOfFreedom<Big>(position, Velocity<Big>())),
                    expected_acceleration),
                Lt(1E-10 * SIUnit<Acceleration>()));
  }
}
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));
  }
}
void TestSymplecticity(Integrator const& integrator,
                       Energy const& expected_energy_error) {
  Length const q_initial = 1 * Metre;
  Speed const v_initial = 0 * Metre / Second;
  Instant const t_initial;
  Instant const t_final = t_initial + 500 * Second;
  Time const step = 0.2 * Second;

  Mass const m = 1 * Kilogram;
  Stiffness const k = SIUnit<Stiffness>();
  Energy const initial_energy =
      0.5 * m * Pow<2>(v_initial) + 0.5 * k * Pow<2>(q_initial);

  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};
  problem.initial_state = &initial_state;
  auto append_state = [&solution](ODE::SystemState const& state) {
    solution.push_back(state);
  };

  auto const instance =
      integrator.NewInstance(problem, std::move(append_state), step);
  integrator.Solve(t_final, *instance);

  std::size_t const length = solution.size();
  std::vector<Energy> energy_error(length);
  std::vector<Time> time(length);
  Energy max_energy_error;
  for (std::size_t i = 0; i < length; ++i) {
    Length const q_i   = solution[i].positions[0].value;
    Speed const v_i = solution[i].velocities[0].value;
    time[i] = solution[i].time.value - t_initial;
    energy_error[i] =
        AbsoluteError(initial_energy,
                      0.5 * m * Pow<2>(v_i) + 0.5 * k * Pow<2>(q_i));
    max_energy_error = std::max(energy_error[i], max_energy_error);
  }
  double const correlation =
      PearsonProductMomentCorrelationCoefficient(time, energy_error);
  LOG(INFO) << "Correlation between time and energy error : " << correlation;
  EXPECT_THAT(correlation, Lt(1e-2));
  Power const slope = Slope(time, energy_error);
  LOG(INFO) << "Slope                                     : " << slope;
  EXPECT_THAT(Abs(slope), Lt(2e-6 * SIUnit<Power>()));
  LOG(INFO) << "Maximum energy error                      : " <<
      max_energy_error;
  EXPECT_EQ(expected_energy_error, max_energy_error);
}
TEST_F(EmbeddedExplicitRungeKuttaNyströmIntegratorTest,
       MaxSteps) {
  AdaptiveStepSizeIntegrator<ODE> const& integrator =
      DormandElMikkawyPrince1986RKN434FM<Length>();
  Length const x_initial = 1 * Metre;
  Speed const v_initial = 0 * Metre / Second;
  Speed const v_amplitude = 1 * Metre / Second;
  Time const period = 2 * π * Second;
  AngularFrequency const ω = 1 * Radian / Second;
  Instant const t_initial;
  Instant const t_final = t_initial + 10 * period;
  Length const length_tolerance = 1 * Milli(Metre);
  Speed const speed_tolerance = 1 * Milli(Metre) / Second;
  // The number of steps if no step limit is set.
  std::int64_t const steps_forward = 132;

  int evaluations = 0;
  auto const step_size_callback = [](bool tolerable) {};

  std::vector<ODE::SystemState> solution;
  ODE harmonic_oscillator;
  harmonic_oscillator.compute_acceleration =
      std::bind(ComputeHarmonicOscillatorAcceleration,
                _1, _2, _3, &evaluations);
  IntegrationProblem<ODE> problem;
  problem.equation = harmonic_oscillator;
  ODE::SystemState const initial_state = {{x_initial}, {v_initial}, t_initial};
  problem.initial_state = &initial_state;
  problem.t_final = t_final;
  problem.append_state = [&solution](ODE::SystemState const& state) {
    solution.push_back(state);
  };
  AdaptiveStepSize<ODE> adaptive_step_size;
  adaptive_step_size.first_time_step = t_final - t_initial;
  adaptive_step_size.safety_factor = 0.9;
  adaptive_step_size.tolerance_to_error_ratio =
      std::bind(HarmonicOscillatorToleranceRatio,
                _1, _2, length_tolerance, speed_tolerance, step_size_callback);
  adaptive_step_size.max_steps = 100;

  auto const outcome = integrator.Solve(problem, adaptive_step_size);
  EXPECT_EQ(termination_condition::ReachedMaximalStepCount, outcome.error());
  EXPECT_THAT(AbsoluteError(
                  x_initial * Cos(ω * (solution.back().time.value - t_initial)),
                      solution.back().positions[0].value),
              AllOf(Ge(8e-4 * Metre), Le(9e-4 * Metre)));
  EXPECT_THAT(AbsoluteError(
                  -v_amplitude *
                      Sin(ω * (solution.back().time.value - t_initial)),
                  solution.back().velocities[0].value),
              AllOf(Ge(1e-3 * Metre / Second), Le(2e-3 * Metre / Second)));
  EXPECT_THAT(solution.back().time.value, Lt(t_final));
  EXPECT_EQ(100, solution.size());

  // Check that a |max_steps| greater than or equal to the unconstrained number
  // of steps has no effect.
  for (std::int64_t const max_steps :
       {steps_forward, steps_forward + 1234}) {
    solution.clear();
    adaptive_step_size.max_steps = steps_forward;
    auto const outcome = integrator.Solve(problem, adaptive_step_size);
    EXPECT_EQ(termination_condition::Done, outcome.error());
    EXPECT_THAT(AbsoluteError(x_initial, solution.back().positions[0].value),
                AllOf(Ge(3e-4 * Metre), Le(4e-4 * Metre)));
    EXPECT_THAT(AbsoluteError(v_initial, solution.back().velocities[0].value),
                AllOf(Ge(2e-3 * Metre / Second), Le(3e-3 * Metre / Second)));
    EXPECT_EQ(t_final, solution.back().time.value);
    EXPECT_EQ(steps_forward, solution.size());
  }
}
Пример #7
0
void
Triangle_Processor::Process( Stack<AtomicRegion>&  Offspring)
  {
  TimesCalled ++;
  if (TimesCalled == 1)
    {
    TheRule->Apply(LocalIntegrand(),Geometry(),Integral(),AbsoluteError());
    Offspring.MakeEmpty();
    return;
    };
  if(TimesCalled == 2)
    {
    real NewVolume
          = Geometry().Volume()/2;
    Stack<Triangle> Parts;
    Vector<unsigned int> DiffOrder(Diffs.Size());
    const real difffac = real(1)/real(0.45);    
    const real difftreshold = 1e-3;

    TheRule->ComputeDiffs(LocalIntegrand(),Geometry(),Diffs); 

    // Sort the differences in descending order.
    for (unsigned int ik=0 ; ik<=2 ; ik++)  { DiffOrder[ik] = ik; }
    for (unsigned int i=0 ; i<=1 ; i++)  
      {
     for (unsigned int k=i+1 ; k<=2 ; k++)
         if (Diffs[DiffOrder[k]]>Diffs[DiffOrder[i]])
            {
            unsigned int h = DiffOrder[i];
            DiffOrder[i] = DiffOrder[k];
            DiffOrder[k] = h;
            }
      }

    if (Diffs[DiffOrder[0]] < difftreshold)
      {
      TheDivisor4->Apply(Geometry(),Parts,DiffOrder);
      NewVolume /=2;
      }
    else 
      {
      if (Diffs[DiffOrder[0]]>difffac*Diffs[DiffOrder[2]])
        {
        TheDivisor2->Apply (Geometry(),Parts,DiffOrder);
        }
      else 
        { 
        TheDivisor4->Apply(Geometry(),Parts,DiffOrder);
        NewVolume /=2;
        }	
      };

    unsigned int N = Parts.Size();
    for (unsigned int ii =0;ii<N;ii++)
      {
      Triangle* g = Parts.Pop();
      g->Volume(NewVolume);
      Processor<Triangle>* p = Descendant();
      Atomic<Triangle>* a = new Atomic<Triangle>(g,p);
      a->LocalIntegrand(&LocalIntegrand());
      Offspring.Push(a);
      };
    return;
    };
   Error(TimesCalled > 2,
     "Triangle_Processor : more than two calls of Process()");
   }
void TestConvergence(Integrator const& integrator,
                     Time const& beginning_of_convergence) {
  Length const q_initial = 1 * Metre;
  Speed const v_initial = 0 * Metre / Second;
  Speed const v_amplitude = 1 * Metre / Second;
  AngularFrequency const ω = 1 * Radian / Second;
  Instant const t_initial;
  Instant const t_final = t_initial + 100 * Second;

  Time step = beginning_of_convergence;
  int const step_sizes = 50;
  double const step_reduction = 1.1;
  std::vector<double> log_step_sizes;
  log_step_sizes.reserve(step_sizes);
  std::vector<double> log_q_errors;
  log_step_sizes.reserve(step_sizes);
  std::vector<double> log_p_errors;
  log_step_sizes.reserve(step_sizes);

  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};
  problem.initial_state = &initial_state;
  ODE::SystemState final_state;
  auto const append_state = [&final_state](ODE::SystemState const& state) {
    final_state = state;
  };

  for (int i = 0; i < step_sizes; ++i, step /= step_reduction) {
    auto const instance = integrator.NewInstance(problem, append_state, step);
    integrator.Solve(t_final, *instance);
    Time const t = final_state.time.value - t_initial;
    Length const& q = final_state.positions[0].value;
    Speed const& v = final_state.velocities[0].value;
    double const log_q_error = std::log10(
        AbsoluteError(q / q_initial, Cos(ω * t)));
    double const log_p_error = std::log10(
        AbsoluteError(v / v_amplitude, -Sin(ω * t)));
    if (log_q_error <= -13 || log_p_error <= -13) {
      // If we keep going the effects of finite precision will drown out
      // convergence.
      break;
    }
    log_step_sizes.push_back(std::log10(step / Second));
    log_q_errors.push_back(log_q_error);
    log_p_errors.push_back(log_p_error);
  }
  double const q_convergence_order = Slope(log_step_sizes, log_q_errors);
  double const q_correlation =
      PearsonProductMomentCorrelationCoefficient(log_step_sizes, log_q_errors);
  LOG(INFO) << "Convergence order in q : " << q_convergence_order;
  LOG(INFO) << "Correlation            : " << q_correlation;

#if !defined(_DEBUG)
  EXPECT_THAT(RelativeError(integrator.order, q_convergence_order),
              Lt(0.05));
  EXPECT_THAT(q_correlation, AllOf(Gt(0.99), Lt(1.01)));
#endif
  double const v_convergence_order = Slope(log_step_sizes, log_p_errors);
  double const v_correlation =
      PearsonProductMomentCorrelationCoefficient(log_step_sizes, log_p_errors);
  LOG(INFO) << "Convergence order in p : " << v_convergence_order;
  LOG(INFO) << "Correlation            : " << v_correlation;
#if !defined(_DEBUG)
  // SPRKs with odd convergence order have a higher convergence order in p.
  EXPECT_THAT(
      RelativeError(integrator.order + (integrator.order % 2),
                    v_convergence_order),
      Lt(0.03));
  EXPECT_THAT(v_correlation, AllOf(Gt(0.99), Lt(1.01)));
#endif
}
Пример #9
0
Scalar AbsoluteError(geometry::Point<Scalar> const& expected,
                     geometry::Point<Scalar> const& actual) {
  geometry::Point<Scalar> const origin;
  return AbsoluteError(expected - origin, actual - origin);
}
Пример #10
0
Scalar AbsoluteError(
    geometry::Point<geometry::Multivector<Scalar, Frame, 1>> const& expected,
    geometry::Point<geometry::Multivector<Scalar, Frame, 1>> const& actual) {
  geometry::Point<geometry::Multivector<Scalar, Frame, 1>> const origin;
  return AbsoluteError(expected - origin, actual - origin);
}
Пример #11
0
Scalar AbsoluteError(geometry::R3Element<Scalar> const& expected,
                     geometry::R3Element<Scalar> const& actual) {
  return AbsoluteError(expected, actual, &geometry::R3Element<Scalar>::Norm);
}
Пример #12
0
quantities::Quantity<Dimensions> AbsoluteError(
    quantities::Quantity<Dimensions> const& expected,
    quantities::Quantity<Dimensions> const& actual) {
  return AbsoluteError(expected, actual, &quantities::Abs<Dimensions>);
}
Пример #13
0
TEST_F(ManœuvreTest, Apollo8SIVB) {
    // Data from NASA's Saturn V Launch Vehicle, Flight Evaluation Report AS-503,
    // Apollo 8 Mission (1969),
    // http://ntrs.nasa.gov/archive/nasa/casi.ntrs.nasa.gov/19690015314.pdf.
    // We use the reconstructed or actual values.

    // Table 2-2. Significant Event Times Summary.
    Instant const range_zero;
    Instant const s_ivb_1st_90_percent_thrust = range_zero +    530.53 * Second;
    Instant const s_ivb_1st_eco               = range_zero +    684.98 * Second;
    // Initiate S-IVB Restart Sequence and Start of Time Base 6 (T6).
    Instant const t6                          = range_zero +   9659.54 * Second;
    Instant const s_ivb_2nd_90_percent_thrust = range_zero + 10'240.02 * Second;
            Instant const s_ivb_2nd_eco               = range_zero + 10'555.51 * Second;

    // From Table 7-2. S-IVB Steady State Performance - First Burn.
    Force thrust_1st                  = 901'557 * Newton;
                                        Speed specific_impulse_1st        = 4'204.1 * Newton * Second / Kilogram;
    Variation<Mass> lox_flowrate_1st  = 178.16 * Kilogram / Second;
    Variation<Mass> fuel_flowrate_1st = 36.30 * Kilogram / Second;

    // From Table 7-7. S-IVB Steady State Performance - Second Burn.
    Force thrust_2nd                  = 897'548 * Newton;
                                        Speed specific_impulse_2nd        = 4199.2 * Newton * Second / Kilogram;
                                        Variation<Mass> lox_flowrate_2nd  = 177.70 * Kilogram / Second;
                                        Variation<Mass> fuel_flowrate_2nd = 36.01 * Kilogram / Second;

                                        // Table 21-5. Total Vehicle Mass, S-IVB First Burn Phase, Kilograms.
                                        Mass total_vehicle_at_s_ivb_1st_90_percent_thrust = 161143 * Kilogram;
                                        Mass total_vehicle_at_s_ivb_1st_eco               = 128095 * Kilogram;

                                        // Table 21-7. Total Vehicle Mass, S-IVB Second Burn Phase, Kilograms.
                                        Mass total_vehicle_at_s_ivb_2nd_90_percent_thrust = 126780 * Kilogram;
                                        Mass total_vehicle_at_s_ivb_2nd_eco               =  59285 * Kilogram;

                                        // An arbitrary direction, we're not testing this.
                                        Vector<double, World> e_y({0, 1, 0});

    Manœuvre<World> first_burn(thrust_1st,
                                total_vehicle_at_s_ivb_1st_90_percent_thrust,
                                specific_impulse_1st, e_y);
    EXPECT_THAT(RelativeError(lox_flowrate_1st + fuel_flowrate_1st,
                              first_burn.mass_flow()),
                Lt(1E-4));

    first_burn.set_duration(s_ivb_1st_eco - s_ivb_1st_90_percent_thrust);
    EXPECT_THAT(
        RelativeError(total_vehicle_at_s_ivb_1st_eco, first_burn.final_mass()),
        Lt(1E-3));

    first_burn.set_initial_time(s_ivb_1st_90_percent_thrust);
    EXPECT_EQ(s_ivb_1st_eco, first_burn.final_time());

    // Accelerations from Figure 4-4. Ascent Trajectory Acceleration Comparison.
    // Final acceleration from Table 4-2. Comparison of Significant Trajectory
    // Events.
    EXPECT_THAT(
        first_burn.acceleration()(first_burn.initial_time()).Norm(),
        AllOf(Gt(5 * Metre / Pow<2>(Second)), Lt(6.25 * Metre / Pow<2>(Second))));
    EXPECT_THAT(first_burn.acceleration()(range_zero + 600 * Second).Norm(),
                AllOf(Gt(6.15 * Metre / Pow<2>(Second)),
                      Lt(6.35 * Metre / Pow<2>(Second))));
    EXPECT_THAT(first_burn.acceleration()(first_burn.final_time()).Norm(),
                AllOf(Gt(7.03 * Metre / Pow<2>(Second)),
                      Lt(7.05 * Metre / Pow<2>(Second))));

    Manœuvre<World> second_burn(thrust_2nd,
                                 total_vehicle_at_s_ivb_2nd_90_percent_thrust,
                                 specific_impulse_2nd, e_y);
    EXPECT_THAT(RelativeError(lox_flowrate_2nd + fuel_flowrate_2nd,
                              second_burn.mass_flow()),
                Lt(2E-4));

    second_burn.set_duration(s_ivb_2nd_eco - s_ivb_2nd_90_percent_thrust);
    EXPECT_THAT(
        RelativeError(total_vehicle_at_s_ivb_2nd_eco, second_burn.final_mass()),
        Lt(2E-3));

    second_burn.set_initial_time(s_ivb_2nd_90_percent_thrust);
    EXPECT_EQ(s_ivb_2nd_eco, second_burn.final_time());

    // Accelerations from Figure 4-9. Injection Phase Acceleration Comparison.
    // Final acceleration from Table 4-2. Comparison of Significant Trajectory
    // Events.
    EXPECT_THAT(second_burn.acceleration()(second_burn.initial_time()).Norm(),
                AllOf(Gt(7 * Metre / Pow<2>(Second)),
                      Lt(7.5 * Metre / Pow<2>(Second))));
    EXPECT_THAT(second_burn.acceleration()(t6 + 650 * Second).Norm(),
                AllOf(Gt(8 * Metre / Pow<2>(Second)),
                      Lt(8.02 * Metre / Pow<2>(Second))));
    EXPECT_THAT(second_burn.acceleration()(t6 + 700 * Second).Norm(),
                AllOf(Gt(8.8 * Metre / Pow<2>(Second)),
                      Lt(9 * Metre / Pow<2>(Second))));
    EXPECT_THAT(second_burn.acceleration()(t6 + 750 * Second).Norm(),
                AllOf(Gt(9.9 * Metre / Pow<2>(Second)),
                      Lt(10 * Metre / Pow<2>(Second))));
    EXPECT_THAT(second_burn.acceleration()(t6 + 850 * Second).Norm(),
                AllOf(Gt(12.97 * Metre / Pow<2>(Second)),
                      Lt(13 * Metre / Pow<2>(Second))));
    EXPECT_THAT(second_burn.acceleration()(second_burn.final_time()).Norm(),
                AllOf(Gt(15.12 * Metre / Pow<2>(Second)),
                      Lt(15.17 * Metre / Pow<2>(Second))));

    EXPECT_THAT(second_burn.Δv(),
                AllOf(Gt(3 * Kilo(Metre) / Second),
                      Lt(3.25 * Kilo(Metre) / Second)));

    // From the Apollo 8 flight journal.
    EXPECT_THAT(AbsoluteError(10'519.6 * Foot / Second, second_burn.Δv()),
                              Lt(20 * Metre / Second));
                          }
Пример #14
0
void
CircleAdaptive::Process(Stack<AtomicRegion>& Offspring)
  {
  Circle& C = Geometry();
  static unsigned int mxgen=2;
  //if (mxgen == 0)
    //{
      //std::cerr<<"How many times may I apply the circle rule? ";
      //cin>>mxgen;
    //};
  TimesCalled++;
  if(TimesCalled ==1)
    {
    if (GenerationNumber < mxgen)
      {
       TheRule->Apply(LocalIntegrand(),C,Integral(),AbsoluteError());
      }
    else
      {
       Point rv (C.Radius(),0);
       Point bp = C.Center()+rv;
       AtomicRegion* A ;
       A= (AtomicRegion*) POLAR_RECTANGLE(C.Center(),bp,bp);
       A->LocalIntegrand(&(LocalIntegrand()));
       Offspring.Push(A);
      };
    }
  else
    {
    const real CircleRatio = 0.44721359549995793928;
    Point m1(C.Radius()*CircleRatio ,0.);
    Point m2(C.Radius() , 0.);
    Point m3(0.,C.Radius());
    Point m4(0.,C.Radius()*CircleRatio);
    Point origin=C.Center();

    AtomicRegion*
        t1=(AtomicRegion*) POLAR_RECTANGLE(origin+m1,origin+m2,origin+m3);
    AtomicRegion*
        t2=(AtomicRegion*) POLAR_RECTANGLE(origin+m4,origin+m3,origin-m2);
    AtomicRegion*
        t3=(AtomicRegion*) POLAR_RECTANGLE(origin-m1,origin-m2,origin-m3);
    AtomicRegion*
        t4=(AtomicRegion*) POLAR_RECTANGLE(origin-m4,origin-m3,origin+m2);

    Offspring.Push(t1);
    Offspring.Push(t2);
    Offspring.Push(t3);
    Offspring.Push(t4);
    Offspring.IteratorReset();
    while (!Offspring.IteratorAtEnd())
      {
      Offspring.IteratorNext()->LocalIntegrand(&LocalIntegrand());
      };
    if (CircleRatio != 0.0)
      {
       Circle* tmp = new Circle(origin,C.Radius()*CircleRatio);
       Atomic<Circle>* a =new Atomic<Circle>(tmp,Descendant());
       a->LocalIntegrand(&LocalIntegrand());
       Offspring.Push(a);
      };
    };
  }