Thanks a lot for the information and the test, @alberto-ferrero. I could reproduce the bug and wanted to give you an update.
The issue appears when the eccentricities are too little within the while-loop in ComputeMeanParameters. To give you an idea, in your test, the eccentricity of the osculating orbit that is fed to the method is already 0.000958. Indeed, at some point during the iterations, the eccentricity of the orbit computed by the algorithm drops below zero and the KeplerianOrbit constructor rises an exception. I had a look at the equations and everything looks fine to me.
In ComputeMeanParameters there is already a guard for negative eccentricities that resets the value to zero when a KeplerianOrbit is created, but that does not extend to all the times the KeplerianOrbit constructor is called (hence the exception). Nevertheless, extending this guard does not solve the issue, as the algorithm would not converge anyway.
I have noticed that resetting the eccentricity to the one of the initial osculating orbit (instead of zero) would let the algorithm converge for this specific test. However, that does not solve the issue completely.
A possible solution would be replacing the KeplerianOrbit with CartesianOrbit (or EquinoctialOrbit). Unfortunately this is not straight forward as the algorithm will need to be adapted in several points.
I keep investigating this issue, but I am open to comments or suggestions.
I have noticed that resetting the eccentricity to the one of the initial osculating orbit (instead of zero) would let the algorithm converge for this specific test. However, that does not solve the issue completely.
This is a nice hint. I can try to temporarily work from here as intermediate solution, waiting for your investigation to be completed.
Much appreciated the effort and the updates.
Alberto
Hi @gc
Going back to this topic.
I am trying to follow your suggestion to return a different orbit type.
If I consider EquinoctialOrbit, would be something like this?
// Return a Equinoctial orbitfinal double ex = e.getValue() * FastMath.cos(g.getValue() + h.getValue());final double ey = e.getValue() * FastMath.sin(g.getValue() + h.getValue());final double hx = FastMath.tan(i.getValue() / 2.0) * FastMath.cos(h.getValue());final double hy = FastMath.tan(i.getValue() / 2.0) * FastMath.sin(h.getValue());
Basically I derivate ex -> exDot, ey -> eyDot, etc.
d/dt(e cos(g(t) + h(t))) = -e (g'(t) + h'(t)) sin(g(t) + h(t))d/dt(e sin(g(t) + h(t))) = e (g'(t) + h'(t)) cos(g(t) + h(t))d/dt(e tan(i(t)/2) cos(h(t))) = 1/2 e cos(h(t)) i'(t) sec^2(i(t)/2) - e h'(t) sin(h(t)) tan(i(t)/2)d/dt(e tan(i(t)/2) sin(h(t))) = e h'(t) cos(h(t)) tan(i(t)/2) + 1/2 e sin(h(t)) i'(t) sec^2(i(t)/2)
What do you think?
This implementation solves my bug, but many other tests in orekit\src\test\java\org\orekit\propagation\analytical\BrouwerLyddanePropagatorTest are actually failing
What about this approach for CartesianOrbit? Should I get X,Y,Z from Keplerian elements and derivate?
But still, no regression is failing (an actually also the circular test of this thread does not converge as well.
I see that despite some tests failing because of larger error (so maybe need to adjust the tolerance), some of them does not converge at all.
This is wierd. Can it be because of the further conversion Equinoctial -> Keplerian during the call computeMeanParameters?
As I said on the forum, the method propagateParameters is suspicious. It uses UnivariateDerivative2 but using UnivariateDerivative1 would have exactly the same effect. It looks like a misuse of Derivative actually.