StepSize hardcoded for Master_Mode in AnalyticalPropagator. Change?

While trying to find a way for what I aim to do, I found that when you setMasterMode on an Analytical Propagator it will assume a hardcoded Step-Size of a 100th KeplerianPeriod (See AbstractAnalyticalPropagator - Line 131).

You are able to set a custom one with the overloaded method, but that forces one to use the FixedStepHandler instead of a general StepHandler. The question is if this is intentional and if it could be changed to allow a general OrekitStepHandler with a custom Step Size in an analytical propagator?

Context/why?
I currently use EventDetectors to find certain Multi-Satellite events. But in many cases I throw the result away afterwards, because it is irrelevant. The Detectors are designed to show a g-flip even with high step sizes. Increasing Step size is the most performance increasing thing to do, I found so far, that’s why I want them to skip over as most uninteresting area as possible.
But when there is a g-flip it always has to solve the whole root, even though half way through I could determine if finding the root is actually neccesary. Just setting the g arbitrarily to 0.0 didn’t work as expected to abort a root Finding process, instead it increases it even longer. My guess is, because it breaks continuity of the function unexpectedly.
Anyway an alternative idea is to use a custom StepHandler to find the events instead of Detectors, which would allow to customize how to find roots and also abort the process mid-way. It also could get rid of the sorting mechanism, as I actually don’t care of the order of those events. But to construct a Handler as some kind of detector, I would need the interpolator for the whole step and not just one SpacecraftState. But, as mentioned above, that forces a step-size of 100th period, which makes the whole effort to make big steps for performance useless.

So, my suggestion/question would be, if a custom step for MasterMode with general StepHandlers is possible / viable for the future? And/or if there is a more convenient way to achieve what I want in a different functionality (analytical prop, multi-sat events with an embedded slave prop, order of events doesnt matter, most events could be canceled during the root-finding, goal of big steps in between times with zero events) ?

Best regards

Hi Skyrex,

I’m actually surprised that is in there. Nice find. Looking at the history it dates back to at least 2008. @luc could you speak to why it is in there originally or if there is a reason to keep it? My guess is that it was before event detectors had their own independent maxCheck.

I think we should remove it and let the propagator do the whole propagation in one step if no step size has been set. And since this next release is a major one this would be the time to do it. Could you create an issue on gitlab.orekit.org for it?

I don’t know of a more convenient way to achieve your goals though it does bring up some interesting ideas.

Significant effort was put in to being able to know an order of events and it is valuable in some cases. For your case where order doesn’t matter it reduces performance by checking other event detectors registered on the same propagator before dispatching the event. One solution would be a replaceable event engine (acceptStep and EventState) which is sounds like your working on with implementing your own step handler for event detection. I would be curious to hear how that works. Perhaps it would be something you could contribute. You could also try the tip below for working within the current framework.

Cancelling root finding could be another nice performance feature. Though it would seem to break the alternating increasing/decreasing guarantee so would need to be separated from the existing implementation. Perhaps in your step handler event engine.

I agree step size should be limited only by the integrator, or in your case the min and max date of propagation as discussed above.

Finally some tips.

If event detection is the biggest performance cost, split up the detectors across multiple propagators. As implemented event detection is O(nm) where n is the number of events and m is the number of detectors.

If you haven’t found them already BooleanDetector, EventEnablingPredicateFilter, and EventSlopeFilter can be good ways to not find uninteresting events before root finding starts.

Best Regards,
Evan

Hi @evan.ward ,

Thanks for aknowledging the hardcoded stepsize and considering it to be changed for the next major release.

Since then I have been working on a workaround way to achieve the same thing, and you were curious of the solution, so I wanted to share (Although current approach is still prototyping stage, and might very well change in future).

So, baseline was, Detectors can’t be broken and StepSizes on analytical masterModes are hardcoded. Therefor I approached it from a slave perspective and am now driving the Propagators manually with my own time loop.

Furthermore, I am also driving the detectors manually, which was the key to break their searching.
In practise that means I have a custom Propagator class (that is not actually any Propagator type), but it has an internal TLEPropagator and it also holds all the EventDetectors.
The TLEPropagator doesn’t know of the Detectors at all.
The wrapping class creates custom eventChecking logic for the added Detectors (which must be of a specific type, cause the whole logic is currently taylored for the specific use-case).

What happens is that the wrapping class propagates a step in slave mode and gives this new state to all the Detectors for event checking.
All the detectors check their g-value and start searching for the flip point if their was a sign change.
But this search is also customized, as they use a strict bisection method until they reach a bracket of smaller than 75 sec, at which point a break-condition is calculated. If true, the whole checking stops right there, if false the remaining bracket is thrown into a BrentSolver (Just like in Orekit’s EventState class) to find the actual event.
For the found event the customDetector calls the eventOccured of the internal wrapped Detector, which hits the Handler and then we’re back on orekit’s intended track of information flow.

This “manual wielding” of the event search also allows to “not care” about the order. For my handler it doesn’t matter if the events are ordered, so every Detector can happily check on it’s own until it finds something or breaks the search, without ever checking on other events.

Another benefit is, that the propagator gets NOT set to the Event State after an Event has been found. Actually the propagator doesnt even get informed that anything happend. So it waits at its target epoch until all eventchecks have finished and fired their handlers and then it just steps to the next step. This makes it, that all propagators are actually walking synchronous automatically and saves on reoccuring calculations as many points for bisection search might have been calculated and saved beforehand, saving more time.

This way I can now set the general step size to 10 minutes, without missing any event in between.
Compared to the MasterMode with 100th Period StepSize and Orekit’s pure “locked into search” Detectors, I was overall able to save more than ~50% of calculation time.

Nice approach under your assumptions. A 50% performance improvement is significant.

Would it be something that you’re interested in contributing?