diff --git a/mathematica/mathematica.hpp b/mathematica/mathematica.hpp index ad40231d13..83458c5f86 100644 --- a/mathematica/mathematica.hpp +++ b/mathematica/mathematica.hpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include "astronomy/orbital_elements.hpp" @@ -221,11 +222,9 @@ template std::string ToMathematica(UnboundedVector const& vector, OptionalExpressIn express_in = std::nullopt); -template().time)>, - typename = std::void_t().degrees_of_freedom)>, +template -std::string ToMathematica(R ref, +std::string ToMathematica(std::pair const& pair, OptionalExpressIn express_in = std::nullopt); template const& vector, return Apply("List", elements); } -template -std::string ToMathematica(R const ref, +template +std::string ToMathematica(std::pair const& pair, OptionalExpressIn express_in) { return Apply("List", std::vector{ - ToMathematica(ref.time, express_in), - ToMathematica(ref.degrees_of_freedom, express_in)}); + ToMathematica(pair.first, express_in), + ToMathematica(pair.second, express_in)}); } template trajectory; + DiscreteTraject0ry trajectory; trajectory.Append( Instant(), DegreesOfFreedom( @@ -213,9 +213,9 @@ TEST_F(MathematicaTest, ToMathematica) { Velocity({-1.0 * Metre / Second, -5.0 * Metre / Second, 8.0 * Metre / Second}))); - EXPECT_EQ(ToMathematica(std::tuple{trajectory.front().time, - trajectory.front().degrees_of_freedom}), - ToMathematica(trajectory.front())); + EXPECT_EQ(ToMathematica(std::pair{trajectory.begin()->first, + trajectory.begin()->second}), + ToMathematica(*trajectory.begin())); } { OrbitalElements::EquinoctialElements elements{ @@ -339,7 +339,7 @@ TEST_F(MathematicaTest, ExpressIn) { ToMathematica(v, ExpressIn(Metre, Second))); } { - DiscreteTrajectory trajectory; + DiscreteTraject0ry trajectory; trajectory.Append( Instant(), DegreesOfFreedom( @@ -352,7 +352,7 @@ TEST_F(MathematicaTest, ExpressIn) { ToMathematica(std::tuple{0.0, std::tuple{std::tuple{2.0, 3.0, -4.0}, std::tuple{-1.0, -5.0, 8.0}}}), - ToMathematica(trajectory.front(), ExpressIn(Metre, Second))); + ToMathematica(*trajectory.begin(), ExpressIn(Metre, Second))); } { OrbitalElements::EquinoctialElements elements{ diff --git a/physics/apsides.hpp b/physics/apsides.hpp index b7a4f1b620..cf171a81c7 100644 --- a/physics/apsides.hpp +++ b/physics/apsides.hpp @@ -4,7 +4,7 @@ #include "absl/status/status.h" #include "base/constant_function.hpp" -#include "physics/discrete_trajectory.hpp" +#include "physics/discrete_traject0ry.hpp" #include "physics/trajectory.hpp" namespace principia { @@ -15,29 +15,31 @@ using base::ConstantFunction; using base::Identically; using geometry::Vector; -// Computes the apsides with respect to |reference| for the discrete trajectory -// segment given by |begin| and |end|. Appends to the given trajectories one -// point for each apsis. +// Computes the apsides with respect to |reference| for the section given by +// |begin| and |end| of |trajectory|. Appends to the given output trajectories +// one point for each apsis. template void ComputeApsides(Trajectory const& reference, - typename DiscreteTrajectory::Iterator begin, - typename DiscreteTrajectory::Iterator end, + DiscreteTraject0ry const& trajectory, + typename DiscreteTraject0ry::iterator begin, + typename DiscreteTraject0ry::iterator end, int max_points, - DiscreteTrajectory& apoapsides, - DiscreteTrajectory& periapsides); + DiscreteTraject0ry& apoapsides, + DiscreteTraject0ry& periapsides); -// Computes the crossings of the discrete trajectory segment given by |begin| -// and |end| with the xy plane. Appends the crossings that go towards the +// Computes the crossings of the section given by |begin| and |end| of +// |trajectory| with the xy plane. Appends the crossings that go towards the // |north| side of the xy plane to |ascending|, and those that go away from the // |north| side to |descending|. // Nodes for which |predicate| returns false are excluded. template> -absl::Status ComputeNodes(typename DiscreteTrajectory::Iterator begin, - typename DiscreteTrajectory::Iterator end, +absl::Status ComputeNodes(DiscreteTraject0ry const& trajectory, + typename DiscreteTraject0ry::iterator begin, + typename DiscreteTraject0ry::iterator end, Vector const& north, int max_points, - DiscreteTrajectory& ascending, - DiscreteTrajectory& descending, + DiscreteTraject0ry& ascending, + DiscreteTraject0ry& descending, Predicate predicate = Identically(true)); // TODO(egg): when we can usefully iterate over an arbitrary |Trajectory|, move @@ -46,10 +48,10 @@ absl::Status ComputeNodes(typename DiscreteTrajectory::Iterator begin, template void ComputeApsides(Trajectory const& trajectory1, Trajectory const& trajectory2, - DiscreteTrajectory& apoapsides1, - DiscreteTrajectory& periapsides1, - DiscreteTrajectory& apoapsides2, - DiscreteTrajectory& periapsides2); + DiscreteTraject0ry& apoapsides1, + DiscreteTraject0ry& periapsides1, + DiscreteTraject0ry& apoapsides2, + DiscreteTraject0ry& periapsides2); #endif } // namespace internal_apsides diff --git a/physics/apsides_body.hpp b/physics/apsides_body.hpp index 1a34397f2e..c3656ca6c3 100644 --- a/physics/apsides_body.hpp +++ b/physics/apsides_body.hpp @@ -29,11 +29,12 @@ using quantities::Variation; template void ComputeApsides(Trajectory const& reference, - typename DiscreteTrajectory::Iterator const begin, - typename DiscreteTrajectory::Iterator const end, + DiscreteTraject0ry const& trajectory, + typename DiscreteTraject0ry::iterator const begin, + typename DiscreteTraject0ry::iterator const end, int const max_points, - DiscreteTrajectory& apoapsides, - DiscreteTrajectory& periapsides) { + DiscreteTraject0ry& apoapsides, + DiscreteTraject0ry& periapsides) { std::optional previous_time; std::optional> previous_degrees_of_freedom; std::optional> previous_squared_distance; @@ -112,13 +113,13 @@ void ComputeApsides(Trajectory const& reference, // 3rd-degree polynomial would yield |squared_distance_approximation|, so // we shouldn't be far from the truth. DegreesOfFreedom const apsis_degrees_of_freedom = - begin.trajectory()->EvaluateDegreesOfFreedom(apsis_time); + trajectory.EvaluateDegreesOfFreedom(apsis_time); if (Sign(squared_distance_derivative).is_negative()) { apoapsides.Append(apsis_time, apsis_degrees_of_freedom); } else { periapsides.Append(apsis_time, apsis_degrees_of_freedom); } - if (apoapsides.Size() >= max_points && periapsides.Size() >= max_points) { + if (apoapsides.size() >= max_points && periapsides.size() >= max_points) { break; } } @@ -131,12 +132,13 @@ void ComputeApsides(Trajectory const& reference, } template -absl::Status ComputeNodes(typename DiscreteTrajectory::Iterator begin, - typename DiscreteTrajectory::Iterator end, +absl::Status ComputeNodes(DiscreteTraject0ry const& trajectory, + typename DiscreteTraject0ry::iterator begin, + typename DiscreteTraject0ry::iterator end, Vector const& north, int const max_points, - DiscreteTrajectory& ascending, - DiscreteTrajectory& descending, + DiscreteTraject0ry& ascending, + DiscreteTraject0ry& descending, Predicate predicate) { static_assert( std::is_convertible::Iterator begin, } DegreesOfFreedom const node_degrees_of_freedom = - begin.trajectory()->EvaluateDegreesOfFreedom(node_time); + trajectory.EvaluateDegreesOfFreedom(node_time); if (predicate(node_degrees_of_freedom)) { if (Sign(InnerProduct(north, Vector({0, 0, 1}))) == Sign(z_speed)) { @@ -195,7 +197,7 @@ absl::Status ComputeNodes(typename DiscreteTrajectory::Iterator begin, } else { descending.Append(node_time, node_degrees_of_freedom); } - if (ascending.Size() >= max_points && descending.Size() >= max_points) { + if (ascending.size() >= max_points && descending.size() >= max_points) { break; } } diff --git a/physics/apsides_test.cpp b/physics/apsides_test.cpp index 0cfefb65da..137076bf97 100644 --- a/physics/apsides_test.cpp +++ b/physics/apsides_test.cpp @@ -56,7 +56,7 @@ class ApsidesTest : public ::testing::Test { #if !defined(_DEBUG) -TEST_F(ApsidesTest, ComputeApsidesDiscreteTrajectory) { +TEST_F(ApsidesTest, ComputeApsidesDiscreteTraject0ry) { Instant const t0; GravitationalParameter const μ = SolarGravitationalParameter; auto const b = new MassiveBody(μ); @@ -89,7 +89,7 @@ TEST_F(ApsidesTest, ComputeApsidesDiscreteTrajectory) { Pow<3>(r_norm * Pow<2>(v_norm) - 2 * μ))); Length const a = -r_norm * μ / (r_norm * Pow<2>(v_norm) - 2 * μ); - DiscreteTrajectory trajectory; + DiscreteTraject0ry trajectory; trajectory.Append(t0, DegreesOfFreedom(World::origin + r, v)); ephemeris.FlowWithAdaptiveStep( @@ -105,9 +105,10 @@ TEST_F(ApsidesTest, ComputeApsidesDiscreteTrajectory) { 1e-3 * Metre / Second), Ephemeris::unlimited_max_ephemeris_steps); - DiscreteTrajectory apoapsides; - DiscreteTrajectory periapsides; + DiscreteTraject0ry apoapsides; + DiscreteTraject0ry periapsides; ComputeApsides(*ephemeris.trajectory(b), + trajectory, trajectory.begin(), trajectory.end(), /*max_points=*/std::numeric_limits::max(), @@ -182,7 +183,7 @@ TEST_F(ApsidesTest, ComputeNodes) { *ephemeris.bodies()[0], MasslessBody{}, elements, t0}; elements = orbit.elements_at_epoch(); - DiscreteTrajectory trajectory; + DiscreteTraject0ry trajectory; trajectory.Append(t0, initial_state[0] + orbit.StateVectors(t0)); ephemeris.FlowWithAdaptiveStep( @@ -200,9 +201,10 @@ TEST_F(ApsidesTest, ComputeNodes) { Vector const north({0, 0, 1}); - DiscreteTrajectory ascending_nodes; - DiscreteTrajectory descending_nodes; - ComputeNodes(trajectory.begin(), + DiscreteTraject0ry ascending_nodes; + DiscreteTraject0ry descending_nodes; + ComputeNodes(trajectory, + trajectory.begin(), trajectory.end(), north, /*max_points=*/std::numeric_limits::max(), @@ -236,20 +238,21 @@ TEST_F(ApsidesTest, ComputeNodes) { previous_time = time; } - EXPECT_THAT(ascending_nodes.Size(), Eq(10)); - EXPECT_THAT(descending_nodes.Size(), Eq(10)); + EXPECT_THAT(ascending_nodes.size(), Eq(10)); + EXPECT_THAT(descending_nodes.size(), Eq(10)); - DiscreteTrajectory south_ascending_nodes; - DiscreteTrajectory south_descending_nodes; + DiscreteTraject0ry south_ascending_nodes; + DiscreteTraject0ry south_descending_nodes; Vector const mostly_south({1, 1, -1}); - ComputeNodes(trajectory.begin(), + ComputeNodes(trajectory, + trajectory.begin(), trajectory.end(), mostly_south, /*max_points=*/std::numeric_limits::max(), south_ascending_nodes, south_descending_nodes); - EXPECT_THAT(south_ascending_nodes.Size(), Eq(10)); - EXPECT_THAT(south_descending_nodes.Size(), Eq(10)); + EXPECT_THAT(south_ascending_nodes.size(), Eq(10)); + EXPECT_THAT(south_descending_nodes.size(), Eq(10)); for (auto south_ascending_it = south_ascending_nodes.begin(), ascending_it = ascending_nodes.begin(), @@ -260,12 +263,20 @@ TEST_F(ApsidesTest, ComputeNodes) { ++ascending_it, ++south_descending_it, ++descending_it) { - EXPECT_THAT(south_ascending_it->degrees_of_freedom, - Eq(descending_it->degrees_of_freedom)); - EXPECT_THAT(south_ascending_it->time, Eq(descending_it->time)); - EXPECT_THAT(south_descending_it->degrees_of_freedom, - Eq(ascending_it->degrees_of_freedom)); - EXPECT_THAT(south_descending_it->time, Eq(ascending_it->time)); + const auto& [ascending_time, + ascending_degrees_of_freedom] = *ascending_it; + const auto& [south_ascending_time, + south_ascending_degrees_of_freedom] = *south_ascending_it; + const auto& [descending_time, + descending_degrees_of_freedom] = *descending_it; + const auto& [south_descending_time, + south_descending_degrees_of_freedom] = *south_descending_it; + EXPECT_THAT(south_ascending_degrees_of_freedom, + Eq(descending_degrees_of_freedom)); + EXPECT_THAT(south_ascending_time, Eq(descending_time)); + EXPECT_THAT(south_descending_degrees_of_freedom, + Eq(ascending_degrees_of_freedom)); + EXPECT_THAT(south_descending_time, Eq(ascending_time)); } } diff --git a/physics/body_centred_body_direction_dynamic_frame_test.cpp b/physics/body_centred_body_direction_dynamic_frame_test.cpp index b9f5aecebf..665cb883e4 100644 --- a/physics/body_centred_body_direction_dynamic_frame_test.cpp +++ b/physics/body_centred_body_direction_dynamic_frame_test.cpp @@ -12,6 +12,7 @@ #include "gtest/gtest.h" #include "integrators/methods.hpp" #include "integrators/symplectic_runge_kutta_nyström_integrator.hpp" +#include "physics/discrete_traject0ry.hpp" #include "physics/ephemeris.hpp" #include "physics/mock_continuous_trajectory.hpp" #include "physics/mock_ephemeris.hpp" @@ -452,7 +453,7 @@ TEST_F(BodyCentredBodyDirectionDynamicFrameTest, ConstructFromOneBody) { // A discrete trajectory that remains motionless at the barycentre. Since // both bodies don't have the same mass, this means it has an intrinsic // acceleration. - DiscreteTrajectory barycentre_trajectory; + DiscreteTraject0ry barycentre_trajectory; for (Time t; t <= period_; t += period_ / 16) { auto const big_dof = ephemeris_->trajectory(big_)->EvaluateDegreesOfFreedom(t0_ + t); diff --git a/physics/ephemeris.hpp b/physics/ephemeris.hpp index 5a2c15dcf1..0226cd12cb 100644 --- a/physics/ephemeris.hpp +++ b/physics/ephemeris.hpp @@ -21,7 +21,7 @@ #include "physics/checkpointer.hpp" #include "physics/continuous_trajectory.hpp" #include "physics/degrees_of_freedom.hpp" -#include "physics/discrete_trajectory.hpp" +#include "physics/discrete_traject0ry.hpp" #include "physics/geopotential.hpp" #include "physics/massive_body.hpp" #include "physics/oblate_body.hpp" @@ -206,7 +206,7 @@ class Ephemeris { virtual not_null< std::unique_ptr::Instance>> NewInstance( - std::vector*>> const& trajectories, + std::vector*>> const& trajectories, IntrinsicAccelerations const& intrinsic_accelerations, FixedStepParameters const& parameters); @@ -214,7 +214,7 @@ class Ephemeris { virtual absl::StatusOr::Instance>>> StoppableNewInstance( - std::vector*>> const& trajectories, + std::vector*>> const& trajectories, IntrinsicAccelerations const& intrinsic_accelerations, FixedStepParameters const& parameters); @@ -224,7 +224,7 @@ class Ephemeris { // Prolongs the ephemeris by at most |max_ephemeris_steps|. Returns OK if and // only if |*trajectory| was integrated until |t|. virtual absl::Status FlowWithAdaptiveStep( - not_null*> trajectory, + not_null*> trajectory, IntrinsicAcceleration intrinsic_acceleration, Instant const& t, AdaptiveStepParameters const& parameters, @@ -232,7 +232,7 @@ class Ephemeris { // Same as above, but uses a generalized integrator. virtual absl::Status FlowWithAdaptiveStep( - not_null*> trajectory, + not_null*> trajectory, GeneralizedIntrinsicAcceleration intrinsic_acceleration, Instant const& t, GeneralizedAdaptiveStepParameters const& parameters, @@ -259,7 +259,7 @@ class Ephemeris { // |trajectory|. virtual Vector ComputeGravitationalAccelerationOnMasslessBody( - not_null*> trajectory, + not_null*> trajectory, Instant const& t) const EXCLUDES(lock_); // Returns the gravitational acceleration on the massive |body| at time |t|. @@ -275,10 +275,10 @@ class Ephemeris { // identical (are similarly for |periapsides1| and |periapsides2|). virtual void ComputeApsides(not_null body1, not_null body2, - DiscreteTrajectory& apoapsides1, - DiscreteTrajectory& periapsides1, - DiscreteTrajectory& apoapsides2, - DiscreteTrajectory& periapsides2); + DiscreteTraject0ry& apoapsides1, + DiscreteTraject0ry& periapsides1, + DiscreteTraject0ry& apoapsides2, + DiscreteTraject0ry& periapsides2); // Returns the index of the given body in the serialization produced by // |WriteToMessage| and read by the |Read...| functions. This index is not @@ -336,7 +336,7 @@ class Ephemeris { std::vector> const& trajectories); static void AppendMasslessBodiesStateToTrajectories( typename NewtonianMotionEquation::SystemState const& state, - std::vector*>> const& trajectories); + std::vector*>> const& trajectories); // Returns an equation suitable for the massive bodies contained in this // ephemeris. @@ -404,7 +404,7 @@ class Ephemeris { template absl::Status FlowODEWithAdaptiveStep( typename ODE::RightHandSideComputation compute_acceleration, - not_null*> trajectory, + not_null*> trajectory, Instant const& t, ODEAdaptiveStepParameters const& parameters, std::int64_t max_ephemeris_steps) EXCLUDES(lock_); diff --git a/physics/ephemeris_body.hpp b/physics/ephemeris_body.hpp index 7306bec0bd..cf4369536f 100644 --- a/physics/ephemeris_body.hpp +++ b/physics/ephemeris_body.hpp @@ -431,7 +431,7 @@ template not_null::NewtonianMotionEquation>::Instance>> Ephemeris::NewInstance( - std::vector*>> const& trajectories, + std::vector*>> const& trajectories, IntrinsicAccelerations const& intrinsic_accelerations, FixedStepParameters const& parameters) { return StoppableNewInstance(trajectories, intrinsic_accelerations, parameters) @@ -442,7 +442,7 @@ template absl::StatusOr::NewtonianMotionEquation>::Instance>>> Ephemeris::StoppableNewInstance( - std::vector*>> const& trajectories, + std::vector*>> const& trajectories, IntrinsicAccelerations const& intrinsic_accelerations, FixedStepParameters const& parameters) { IntegrationProblem problem; @@ -468,12 +468,11 @@ Ephemeris::StoppableNewInstance( }; CHECK(!trajectories.empty()); - auto const trajectory_last_time = (*trajectories.begin())->back().time; + auto const& [trajectory_last_time, _] = *(*trajectories.begin())->rbegin(); problem.initial_state.time = DoublePrecision(trajectory_last_time); for (auto const& trajectory : trajectories) { - auto const& trajectory_back = trajectory->back(); - auto const last_degrees_of_freedom = trajectory_back.degrees_of_freedom; - CHECK_EQ(trajectory_back.time, trajectory_last_time); + auto const& [last_time, last_degrees_of_freedom] = *trajectory->rbegin(); + CHECK_EQ(last_time, trajectory_last_time); problem.initial_state.positions.emplace_back( last_degrees_of_freedom.position()); problem.initial_state.velocities.emplace_back( @@ -498,7 +497,7 @@ Ephemeris::StoppableNewInstance( template absl::Status Ephemeris::FlowWithAdaptiveStep( - not_null*> const trajectory, + not_null*> const trajectory, IntrinsicAcceleration intrinsic_acceleration, Instant const& t, AdaptiveStepParameters const& parameters, @@ -528,7 +527,7 @@ absl::Status Ephemeris::FlowWithAdaptiveStep( template absl::Status Ephemeris::FlowWithAdaptiveStep( - not_null*> trajectory, + not_null*> trajectory, GeneralizedIntrinsicAcceleration intrinsic_acceleration, Instant const& t, GeneralizedAdaptiveStepParameters const& parameters, @@ -588,10 +587,10 @@ Ephemeris::ComputeGravitationalAccelerationOnMasslessBody( template Vector Ephemeris::ComputeGravitationalAccelerationOnMasslessBody( - not_null*> const trajectory, + not_null*> const trajectory, Instant const& t) const { - auto const it = trajectory->Find(t); - DegreesOfFreedom const& degrees_of_freedom = it->degrees_of_freedom; + auto const it = trajectory->find(t); + auto const& [_, degrees_of_freedom] = *it; return ComputeGravitationalAccelerationOnMasslessBody( degrees_of_freedom.position(), t); } @@ -681,10 +680,10 @@ Ephemeris::ComputeGravitationalAccelerationOnMassiveBody( template void Ephemeris::ComputeApsides(not_null const body1, not_null const body2, - DiscreteTrajectory& apoapsides1, - DiscreteTrajectory& periapsides1, - DiscreteTrajectory& apoapsides2, - DiscreteTrajectory& periapsides2) { + DiscreteTraject0ry& apoapsides1, + DiscreteTraject0ry& periapsides1, + DiscreteTraject0ry& apoapsides2, + DiscreteTraject0ry& periapsides2) { not_null const*> const body1_trajectory = trajectory(body1); not_null const*> const body2_trajectory = @@ -1087,7 +1086,7 @@ Ephemeris::AppendMassiveBodiesStateToTrajectories( template void Ephemeris::AppendMasslessBodiesStateToTrajectories( typename NewtonianMotionEquation::SystemState const& state, - std::vector*>> const& trajectories) { + std::vector*>> const& trajectories) { Instant const time = state.time.value; int index = 0; for (auto& trajectory : trajectories) { @@ -1343,16 +1342,17 @@ template template absl::Status Ephemeris::FlowODEWithAdaptiveStep( typename ODE::RightHandSideComputation compute_acceleration, - not_null*> trajectory, + not_null*> trajectory, Instant const& t, ODEAdaptiveStepParameters const& parameters, std::int64_t max_ephemeris_steps) { - Instant const& trajectory_last_time = trajectory->back().time; + auto const& [trajectory_last_time, + trajectory_last_degrees_of_freedom] = *trajectory->rbegin(); if (trajectory_last_time == t) { return absl::OkStatus(); } - std::vector*>> const trajectories = + std::vector*>> const trajectories = {trajectory}; // The |min| is here to prevent us from spending too much time computing the // ephemeris. The |max| is here to ensure that we always try to integrate @@ -1369,11 +1369,9 @@ absl::Status Ephemeris::FlowODEWithAdaptiveStep( IntegrationProblem problem; problem.equation.compute_acceleration = std::move(compute_acceleration); - auto const trajectory_back = trajectory->back(); - auto const last_degrees_of_freedom = trajectory_back.degrees_of_freedom; - problem.initial_state = {{last_degrees_of_freedom.position()}, - {last_degrees_of_freedom.velocity()}, - trajectory_back.time}; + problem.initial_state = {{trajectory_last_degrees_of_freedom.position()}, + {trajectory_last_degrees_of_freedom.velocity()}, + trajectory_last_time}; typename AdaptiveStepSizeIntegrator::Parameters const integrator_parameters( diff --git a/physics/ephemeris_test.cpp b/physics/ephemeris_test.cpp index 88ed45adc4..78760831dd 100644 --- a/physics/ephemeris_test.cpp +++ b/physics/ephemeris_test.cpp @@ -228,7 +228,7 @@ TEST_P(EphemerisTest, FlowWithAdaptiveStepSpecialCase) { Ephemeris::FixedStepParameters(integrator(), period / 100)); MasslessBody probe; - DiscreteTrajectory trajectory; + DiscreteTraject0ry trajectory; trajectory.Append( t0_, DegreesOfFreedom( @@ -250,7 +250,7 @@ TEST_P(EphemerisTest, FlowWithAdaptiveStepSpecialCase) { EXPECT_OK(ephemeris.FlowWithAdaptiveStep( &trajectory, Ephemeris::NoIntrinsicAcceleration, - trajectory.back().time, + trajectory.rbegin()->first, Ephemeris::AdaptiveStepParameters( EmbeddedExplicitRungeKuttaNyströmIntegrator< DormandالمكاوىPrince1986RKN434FM, @@ -392,7 +392,7 @@ TEST_P(EphemerisTest, EarthProbe) { Ephemeris::FixedStepParameters(integrator(), period / 100)); MasslessBody probe; - DiscreteTrajectory trajectory; + DiscreteTraject0ry trajectory; trajectory.Append(t0_, DegreesOfFreedom( earth_position + Vector( @@ -447,10 +447,10 @@ TEST_P(EphemerisTest, EarthProbe) { AlmostEquals(1.00 * period * v_earth, 633, 635)); EXPECT_THAT(earth_positions[100].coordinates().y, Eq(q_earth)); - Length const q_probe = (trajectory.back().degrees_of_freedom.position() - + Length const q_probe = (trajectory.rbegin()->second.position() - ICRS::origin).coordinates().y; Speed const v_probe = - trajectory.back().degrees_of_freedom.velocity().coordinates().x; + trajectory.rbegin()->second.velocity().coordinates().x; std::vector> probe_positions; for (auto const& [time, degrees_of_freedom] : trajectory) { probe_positions.push_back(degrees_of_freedom.position() - ICRS::origin); @@ -472,7 +472,7 @@ TEST_P(EphemerisTest, EarthProbe) { Eq(q_probe)); Instant const old_t_max = ephemeris.t_max(); - EXPECT_THAT(trajectory.back().time, Lt(old_t_max)); + EXPECT_THAT(trajectory.rbegin()->first, Lt(old_t_max)); EXPECT_THAT(ephemeris.FlowWithAdaptiveStep( &trajectory, intrinsic_acceleration, @@ -487,7 +487,7 @@ TEST_P(EphemerisTest, EarthProbe) { /*max_ephemeris_steps=*/0), StatusIs(absl::StatusCode::kDeadlineExceeded)); EXPECT_THAT(ephemeris.t_max(), Eq(old_t_max)); - EXPECT_THAT(trajectory.back().time, Eq(old_t_max)); + EXPECT_THAT(trajectory.rbegin()->first, Eq(old_t_max)); } // The Earth and two massless probes, similar to the previous test but flowing @@ -517,7 +517,7 @@ TEST_P(EphemerisTest, EarthTwoProbes) { Ephemeris::FixedStepParameters(integrator(), period / 100)); MasslessBody probe1; - DiscreteTrajectory trajectory1; + DiscreteTraject0ry trajectory1; trajectory1.Append(t0_, DegreesOfFreedom( earth_position + Vector( @@ -531,7 +531,7 @@ TEST_P(EphemerisTest, EarthTwoProbes) { }; MasslessBody probe2; - DiscreteTrajectory trajectory2; + DiscreteTraject0ry trajectory2; trajectory2.Append(t0_, DegreesOfFreedom( earth_position + Vector( @@ -580,15 +580,13 @@ TEST_P(EphemerisTest, EarthTwoProbes) { EXPECT_THAT(earth_positions[100].coordinates().y, Eq(q_earth)); Length const q_probe1 = - (trajectory1.back().degrees_of_freedom.position() - - ICRS::origin).coordinates().y; + (trajectory1.rbegin()->second.position() - ICRS::origin).coordinates().y; Length const q_probe2 = - (trajectory2.back().degrees_of_freedom.position() - - ICRS::origin).coordinates().y; + (trajectory2.rbegin()->second.position() - ICRS::origin).coordinates().y; Speed const v_probe1 = - trajectory1.back().degrees_of_freedom.velocity().coordinates().x; + trajectory1.rbegin()->second.velocity().coordinates().x; Speed const v_probe2 = - trajectory2.back().degrees_of_freedom.velocity().coordinates().x; + trajectory2.rbegin()->second.velocity().coordinates().x; std::vector> probe1_positions; std::vector> probe2_positions; for (auto const& [time, degrees_of_freedom] : trajectory1) { @@ -696,7 +694,7 @@ TEST_P(EphemerisTest, ComputeGravitationalAccelerationMasslessBody) { Ephemeris::FixedStepParameters(integrator(), duration / 100)); // The elephant's initial position and velocity. - DiscreteTrajectory trajectory; + DiscreteTraject0ry trajectory; trajectory.Append(t0_, DegreesOfFreedom( earth_position + Vector( @@ -777,7 +775,7 @@ TEST_P(EphemerisTest, CollisionDetection) { Ephemeris::FixedStepParameters(integrator(), short_duration / 100)); // The apple's initial position and velocity. - DiscreteTrajectory trajectory; + DiscreteTraject0ry trajectory; trajectory.Append( t0_, DegreesOfFreedom( @@ -958,10 +956,10 @@ TEST_P(EphemerisTest, ComputeApsidesContinuousTrajectory) { solar_system.massive_body(*ephemeris, big_name); MassiveBody const* const small = solar_system.massive_body(*ephemeris, small_name); - DiscreteTrajectory apoapsides1; - DiscreteTrajectory apoapsides2; - DiscreteTrajectory periapsides1; - DiscreteTrajectory periapsides2; + DiscreteTraject0ry apoapsides1; + DiscreteTraject0ry apoapsides2; + DiscreteTraject0ry periapsides1; + DiscreteTraject0ry periapsides2; ephemeris->ComputeApsides(big, small, apoapsides1, @@ -969,47 +967,49 @@ TEST_P(EphemerisTest, ComputeApsidesContinuousTrajectory) { apoapsides2, periapsides2); - EXPECT_EQ(apoapsides1.Size(), apoapsides2.Size()); - EXPECT_EQ(periapsides1.Size(), periapsides2.Size()); + EXPECT_EQ(apoapsides1.size(), apoapsides2.size()); + EXPECT_EQ(periapsides1.size(), periapsides2.size()); - EXPECT_EQ(10, apoapsides1.Size()); - EXPECT_EQ(10, periapsides1.Size()); + EXPECT_EQ(10, apoapsides1.size()); + EXPECT_EQ(10, periapsides1.size()); std::optional previous_time; std::set all_times; for (auto it1 = apoapsides1.begin(), it2 = apoapsides2.begin(); it1 != apoapsides1.end() && it2 != apoapsides2.end(); ++it1, ++it2) { - Instant const time = it1->time; - all_times.emplace(time); + auto const& [time1, degrees_of_freedom1] = *it1; + auto const& [time2, degrees_of_freedom2] = *it2; + all_times.emplace(time1); Displacement const displacement = - it1->degrees_of_freedom.position() - - it2->degrees_of_freedom.position(); + degrees_of_freedom1.position() - + degrees_of_freedom2.position(); EXPECT_LT(AbsoluteError(displacement.Norm(), (1 + e) * a), 1.9e-5 * fitting_tolerance); if (previous_time) { - EXPECT_LT(AbsoluteError(time - *previous_time, T), + EXPECT_LT(AbsoluteError(time1 - *previous_time, T), 0.11 * fitting_tolerance / v_apoapsis); } - previous_time = time; + previous_time = time1; } previous_time = std::nullopt; for (auto it1 = periapsides1.begin(), it2 = periapsides2.begin(); it1 != periapsides1.end() && it2 != periapsides2.end(); ++it1, ++it2) { - Instant const time = it1->time; - all_times.emplace(time); + auto const& [time1, degrees_of_freedom1] = *it1; + auto const& [time2, degrees_of_freedom2] = *it2; + all_times.emplace(time1); Displacement const displacement = - it1->degrees_of_freedom.position() - - it2->degrees_of_freedom.position(); + degrees_of_freedom1.position() - + degrees_of_freedom2.position(); EXPECT_LT(AbsoluteError(displacement.Norm(), (1 - e) * a), 5.3e-3 * fitting_tolerance); if (previous_time) { - EXPECT_LT(AbsoluteError(time - *previous_time, T), + EXPECT_LT(AbsoluteError(time1 - *previous_time, T), 2.1 * fitting_tolerance / v_periapsis); } - previous_time = time; + previous_time = time1; } previous_time = std::nullopt; @@ -1026,7 +1026,7 @@ TEST_P(EphemerisTest, ComputeApsidesContinuousTrajectory) { // This trajectory is similar to the second trajectory in the first save in // #2400. It exhibits oscillations with a period close to 5600 s and its // downsampling period alternates between 120 and 130 s. -TEST(EphemerisTestNoFixture, DiscreteTrajectoryCompression) { +TEST(EphemerisTestNoFixture, DiscreteTraject0ryCompression) { SolarSystem solar_system( SOLUTION_DIR / "astronomy" / "sol_gravity_model.proto.txt", SOLUTION_DIR / "astronomy" / @@ -1051,9 +1051,10 @@ TEST(EphemerisTestNoFixture, DiscreteTrajectoryCompression) { 200.2551546021678 * Metre / Second}); MasslessBody probe; - DiscreteTrajectory trajectory1; - trajectory1.SetDownsampling({.max_dense_intervals = 10'000, - .tolerance = 10 * Metre}); + DiscreteTraject0ry trajectory1; + auto const segment1 = trajectory1.segments().begin(); + segment1->SetDownsampling({.max_dense_intervals = 10'000, + .tolerance = 10 * Metre}); trajectory1.Append(t0, DegreesOfFreedom(q0, p0)); auto instance = ephemeris->NewInstance( @@ -1064,13 +1065,13 @@ TEST(EphemerisTestNoFixture, DiscreteTrajectoryCompression) { Position>(), 10 * Second)); EXPECT_OK(ephemeris->FlowWithFixedStep(t1, *instance)); - EXPECT_EQ(1162, trajectory1.Size()); + EXPECT_EQ(1162, trajectory1.size()); serialization::DiscreteTrajectory message; trajectory1.WriteToMessage(&message, /*forks=*/{}, /*exact=*/{}); std::string uncompressed; message.SerializePartialToString(&uncompressed); - EXPECT_EQ(24'394, uncompressed.size()); + EXPECT_EQ(18'692, uncompressed.size()); std::string compressed; auto compressor = google::compression::NewGipfeliCompressor(); @@ -1078,17 +1079,17 @@ TEST(EphemerisTestNoFixture, DiscreteTrajectoryCompression) { // We want a change detector, but the actual compressed size varies depending // on the exact numerical values, and therefore on the mathematical library. - EXPECT_LE(18'825, compressed.size()); - EXPECT_GE(18'825, compressed.size()); + EXPECT_LE(17'145, compressed.size()); + EXPECT_GE(17'145, compressed.size()); auto const trajectory2 = - DiscreteTrajectory::ReadFromMessage(message, /*forks=*/{}); + DiscreteTraject0ry::ReadFromMessage(message, /*forks=*/{}); Length error; for (Instant t = t0; t < t1; t += 10 * Second) { error = std::max( error, - (trajectory1.EvaluatePosition(t) - trajectory2->EvaluatePosition(t)) + (trajectory1.EvaluatePosition(t) - trajectory2.EvaluatePosition(t)) .Norm()); } EXPECT_THAT(error, IsNear(3.3_⑴ * Metre)); @@ -1097,7 +1098,7 @@ TEST(EphemerisTestNoFixture, DiscreteTrajectoryCompression) { TEMP_DIR / "discrete_trajectory_compression.generated.wl", /*make_unique=*/false); logger.Set("trajectory1", trajectory1.begin(), trajectory1.end()); - logger.Set("trajectory2", trajectory2->begin(), trajectory2->end()); + logger.Set("trajectory2", trajectory2.begin(), trajectory2.end()); } TEST(EphemerisTestNoFixture, Reanimator) { diff --git a/physics/mock_ephemeris.hpp b/physics/mock_ephemeris.hpp index f0eab68b81..d90a571b12 100644 --- a/physics/mock_ephemeris.hpp +++ b/physics/mock_ephemeris.hpp @@ -47,13 +47,13 @@ class MockEphemeris : public Ephemeris { not_null::Instance>>, NewInstance, - (std::vector*>> const& trajectories, + (std::vector*>> const& trajectories, IntrinsicAccelerations const& intrinsic_accelerations, FixedStepParameters const& parameters), (override)); MOCK_METHOD(absl::Status, FlowWithAdaptiveStep, - (not_null*> trajectory, + (not_null*> trajectory, IntrinsicAcceleration intrinsic_acceleration, Instant const& t, AdaptiveStepParameters const& parameters, @@ -73,7 +73,7 @@ class MockEphemeris : public Ephemeris { MOCK_METHOD((Vector), ComputeGravitationalAccelerationOnMasslessBody, - (not_null*> trajectory, + (not_null*> trajectory, Instant const& t), (const, override)); @@ -118,21 +118,21 @@ ACTION_P2(AppendToDiscreteTrajectories, time, degrees_of_freedom) { } } -ACTION_P(AppendToDiscreteTrajectory, degrees_of_freedom) { +ACTION_P(AppendToDiscreteTraject0ry, degrees_of_freedom) { arg0->Append(arg2, degrees_of_freedom); } -ACTION_P2(AppendToDiscreteTrajectory, time, degrees_of_freedom) { +ACTION_P2(AppendToDiscreteTraject0ry, time, degrees_of_freedom) { arg0->Append(time, degrees_of_freedom); } -ACTION_P3(AppendToDiscreteTrajectory, trajectory, time, degrees_of_freedom) { +ACTION_P3(AppendToDiscreteTraject0ry, trajectory, time, degrees_of_freedom) { // The extra level of indirection is useful for tests that get a pointer to a // trajectory and squirrel it away using |SaveArg|. (*trajectory)->Append(time, degrees_of_freedom); } -ACTION_P(AppendPointsToDiscreteTrajectory, trajectory) { +ACTION_P(AppendPointsToDiscreteTraject0ry, trajectory) { for (auto const& [time, degrees_of_freedom] : *trajectory) { arg0->Append(time, degrees_of_freedom); }