Performance improvement with AggregateBoundedPropagator

Hi all,

I’ve noticed some performance issues with the class AggregateBoundedPropagator.
I couldn’t understand why an AggregateBoundedPropagator containing multiple IntegratedEphemeris was much slower than a single IntegratedEphemeris.

It turns out the problem comes from the method AggregateBoundedPropagator.basicPropagate.
At the beginning of this method, if we replace:

final SpacecraftState state = getPropagator(date).propagate(date);

With

final BoundedPropagator propagator = getPropagator(date);
final SpacecraftState state = propagator instanceof AbstractAnalyticalPropagator ?
                                      ((AbstractAnalyticalPropagator) propagator).basicPropagate(date) :
                                      propagator.propagate(date);

The performance of the multiple-ephemeris propagation is on par with the single-ephemeris propagation.
The idea is to use the fact that if the propagator is analytical then we can use basicPropagate instead of propagate.
Does that look legit to you? Or is there any caveat that I missed in the difference between propagate and basicPropagate here?

Here’s a small test:
AggregateBoundedPropagatorIssue.java (4.9 KB)

It propagates a LEO numerical propagator for 300 days with a step of 60s step and do:

  1. A single ephemeris generation
  2. A multiple ephemeris (each orbit) generation
  3. Repropagates 1 with a handler (every 3s to force a long time)
  4. Repropagates 2 with the same handler

Without the fix (4) is about 50% slower than (3).
With the fix (4) and (3) takes about the same time.

This test doesn’t fully show performance improvement. I’ve noticed running times divided by 5 with the fix when running something more complex with many low-thrust maneuvers added to the underlying propagator.

Do I have your approval to implement this fix in Orekit?

Cheers,
Maxime

Hi Maxime,

Thanks for noticing this. Your proposal makes sense. Actually I wonder if the current implementation is sound at all. Because any call to propagate means that the events detection is active, but basicPropagate does not include any normally. This would mean that with a mix of analytical and non-analytical wrapped propagators, we’d get a weird behaviour am I right?

Cheers,
Romain.

Hi Romain,

With the current implementation no, but with the one I propose, I realize that yes… :frowning:
But yes it’s weird to do a complete propagate in basicPropagate since it’s not supposed to be used that way. That’s the reason why it’s underperforming in the first place.

I tried yesterday to launch the tests with the fix and I ran into problems in SP3ParserTest (for example, testSP3Propagator) because the additional states are not managed with basicPropagate.
So, to fix the tests, I had to make method AbstractAnalyticalPropagator.updateAdditionalStates public and replace the code from my first post with:

        // do propagation
        final BoundedPropagator propagator = getPropagator(date);
        SpacecraftState state;
        if (propagator instanceof AbstractAnalyticalPropagator) {
            // Take advantage of the fact that the underlying propagator
            // is analytical to speed up propagation
            final AbstractAnalyticalPropagator analyticalPropagator = (AbstractAnalyticalPropagator) propagator;
            state = analyticalPropagator.basicPropagate(date);
            state = analyticalPropagator.updateAdditionalStates(state);
        } else {
            state = propagator.propagate(date);;
        }

But as you say we will probably have unexpected behavior with event detection…
So I don’t know, should I still open the issue and wait for when we manage to provide a consistent fix?

Cheers,
Maxime

Does anyone mind if I at least make methods basicPropagate and updateAdditionalStates public in AbstractAnalyticalPropagator?

Right now they are protected and I cannot create my own version of AggregateBoundedPropagator that suits my needs.

1 Like

+1 for making these methods public.

I’m pretty sure some inheritors already have basicPropagate public actually. However this is API breaking. For users inheriting from AbstractAnalyticalPropagator I mean. So we might need to wait for a major release I’m afraid.

Cheers,
Romain.

That 's right, unfortunately. Thank you Romain for noticing it. The issue is opened and is planned for 13.0.

Cheers,
Maxime

Shouldn’t we also make propagateOrbit public? Some inheritors like BrouwerLyddanePropagator already do so.

Cheers,
Romain.

2 Likes

Sure, we could and should.