// 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()); } }
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 }
Scalar AbsoluteError(geometry::Point<Scalar> const& expected, geometry::Point<Scalar> const& actual) { geometry::Point<Scalar> const origin; return AbsoluteError(expected - origin, actual - origin); }
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); }
Scalar AbsoluteError(geometry::R3Element<Scalar> const& expected, geometry::R3Element<Scalar> const& actual) { return AbsoluteError(expected, actual, &geometry::R3Element<Scalar>::Norm); }
quantities::Quantity<Dimensions> AbsoluteError( quantities::Quantity<Dimensions> const& expected, quantities::Quantity<Dimensions> const& actual) { return AbsoluteError(expected, actual, &quantities::Abs<Dimensions>); }
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)); }
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); }; }; }