Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: mockingbirdnest/Principia
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 40dfcbd68720
Choose a base ref
...
head repository: mockingbirdnest/Principia
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 7765178107e0
Choose a head ref
  • 4 commits
  • 4 files changed
  • 1 contributor

Commits on May 9, 2021

  1. Copy the full SHA
    542ff49 View commit details
  2. Copy the full SHA
    a624f8a View commit details
  3. After egg's review.

    pleroy committed May 9, 2021
    Copy the full SHA
    bd139c5 View commit details
  4. Merge pull request #2980 from pleroy/Serialization

    Properly handle stopping in Prolong
    pleroy authored May 9, 2021
    Copy the full SHA
    7765178 View commit details
Showing with 37 additions and 7 deletions.
  1. +4 −2 ksp_plugin/orbit_analyser.cpp
  2. +13 −2 physics/ephemeris.hpp
  3. +19 −2 physics/ephemeris_body.hpp
  4. +1 −1 physics/mock_ephemeris.hpp
6 changes: 4 additions & 2 deletions ksp_plugin/orbit_analyser.cpp
Original file line number Diff line number Diff line change
@@ -114,10 +114,12 @@ Status OrbitAnalyser::AnalyseOrbit(GuardedParameters const guarded_parameters) {
if (primary != nullptr) {
std::vector<not_null<DiscreteTrajectory<Barycentric>*>> trajectories = {
&trajectory};
auto instance = ephemeris_->NewInstance(
auto instance = ephemeris_->StoppableNewInstance(
trajectories,
Ephemeris<Barycentric>::NoIntrinsicAccelerations,
analysed_trajectory_parameters_);
RETURN_IF_STOPPED;

Time const analysis_duration = std::min(
parameters.extended_mission_duration.value_or(
parameters.mission_duration),
@@ -126,7 +128,7 @@ Status OrbitAnalyser::AnalyseOrbit(GuardedParameters const guarded_parameters) {
for (int n = 0; n <= progress_bar_steps; ++n) {
Instant const t =
parameters.first_time + n / progress_bar_steps * analysis_duration;
if (!ephemeris_->FlowWithFixedStep(t, *instance).ok()) {
if (!ephemeris_->FlowWithFixedStep(t, *instance.ValueOrDie()).ok()) {
// TODO(egg): Report that the integration failed.
break;
}
15 changes: 13 additions & 2 deletions physics/ephemeris.hpp
Original file line number Diff line number Diff line change
@@ -11,6 +11,7 @@
#include "base/jthread.hpp"
#include "base/not_null.hpp"
#include "base/status.hpp"
#include "base/status_or.hpp"
#include "geometry/grassmann.hpp"
#include "geometry/named_quantities.hpp"
#include "google/protobuf/repeated_field.h"
@@ -36,6 +37,7 @@ using base::Error;
using base::jthread;
using base::not_null;
using base::Status;
using base::StatusOr;
using geometry::Instant;
using geometry::Position;
using geometry::Vector;
@@ -186,8 +188,9 @@ class Ephemeris {

virtual Status last_severe_integration_status() const;

// Prolongs the ephemeris up to at least |t|. After the call, |t_max() >= t|.
virtual void Prolong(Instant const& t) EXCLUDES(lock_);
// Prolongs the ephemeris up to at least |t|. Returns an error iff the thread
// is stopped. After a successful call, |t_max() >= t|.
virtual Status Prolong(Instant const& t) EXCLUDES(lock_);

// Creates an instance suitable for integrating the given |trajectories| with
// their |intrinsic_accelerations| using a fixed-step integrator parameterized
@@ -199,6 +202,14 @@ class Ephemeris {
IntrinsicAccelerations const& intrinsic_accelerations,
FixedStepParameters const& parameters);

// Same as above, but returns an error status if the thread is stopped.
virtual StatusOr<not_null<
std::unique_ptr<typename Integrator<NewtonianMotionEquation>::Instance>>>
StoppableNewInstance(
std::vector<not_null<DiscreteTrajectory<Frame>*>> const& trajectories,
IntrinsicAccelerations const& intrinsic_accelerations,
FixedStepParameters const& parameters);

// Integrates, until exactly |t| (except for timeouts or singularities), the
// |trajectory| followed by a massless body in the gravitational potential
// described by |*this|. If |t > t_max()|, calls |Prolong(t)| beforehand.
21 changes: 19 additions & 2 deletions physics/ephemeris_body.hpp
Original file line number Diff line number Diff line change
@@ -352,10 +352,10 @@ Status Ephemeris<Frame>::last_severe_integration_status() const {
}

template<typename Frame>
void Ephemeris<Frame>::Prolong(Instant const& t) {
Status Ephemeris<Frame>::Prolong(Instant const& t) {
// Short-circuit without locking.
if (t <= t_max()) {
return;
return Status::OK;
}

// Note that |t| may be before the last time that we integrated and still
@@ -375,8 +375,11 @@ void Ephemeris<Frame>::Prolong(Instant const& t) {
absl::MutexLock l(&lock_);
while (t_max() < t) {
instance_->Solve(t_final);
RETURN_IF_STOPPED;
t_final += fixed_step_parameters_.step_;
}

return Status::OK;
}

template<typename Frame>
@@ -386,6 +389,17 @@ Ephemeris<Frame>::NewInstance(
std::vector<not_null<DiscreteTrajectory<Frame>*>> const& trajectories,
IntrinsicAccelerations const& intrinsic_accelerations,
FixedStepParameters const& parameters) {
return StoppableNewInstance(trajectories, intrinsic_accelerations, parameters)
.ValueOrDie();
}

template<typename Frame>
StatusOr<not_null<std::unique_ptr<typename Integrator<
typename Ephemeris<Frame>::NewtonianMotionEquation>::Instance>>>
Ephemeris<Frame>::StoppableNewInstance(
std::vector<not_null<DiscreteTrajectory<Frame>*>> const& trajectories,
IntrinsicAccelerations const& intrinsic_accelerations,
FixedStepParameters const& parameters) {
IntegrationProblem<NewtonianMotionEquation> problem;

problem.equation.compute_acceleration =
@@ -427,6 +441,7 @@ Ephemeris<Frame>::NewInstance(
// The construction of the instance may evaluate the degrees of freedom of the
// bodies.
Prolong(trajectory_last_time + parameters.step_);
RETURN_IF_STOPPED;

return parameters.integrator_->NewInstance(
problem, append_state, parameters.step_);
@@ -501,6 +516,7 @@ Status Ephemeris<Frame>::FlowWithFixedStep(
typename Integrator<NewtonianMotionEquation>::Instance& instance) {
if (empty() || t > t_max()) {
Prolong(t);
RETURN_IF_STOPPED;
}
if (instance.time() == DoublePrecision<Instant>(t)) {
return Status::OK;
@@ -1244,6 +1260,7 @@ Status Ephemeris<Frame>::FlowODEWithAdaptiveStep(
trajectory_last_time + fixed_step_parameters_.step()),
t);
Prolong(t_final);
RETURN_IF_STOPPED;

IntegrationProblem<ODE> problem;
problem.equation.compute_acceleration = std::move(compute_acceleration);
2 changes: 1 addition & 1 deletion physics/mock_ephemeris.hpp
Original file line number Diff line number Diff line change
@@ -38,7 +38,7 @@ class MockEphemeris : public Ephemeris<Frame> {
planetary_integrator,
FixedStepSizeIntegrator<NewtonianMotionEquation> const&());

MOCK_METHOD1_T(Prolong, void(Instant const& t));
MOCK_METHOD1_T(Prolong, Status(Instant const& t));
MOCK_METHOD3_T(
NewInstance,
not_null<std::unique_ptr<