Crash in Field propagation with date detection
Since Hipparchus 3.0/Orekit 12.0, following code doesn't finish the propagation. Some possible causes:
new values for default threshold inFieldDateDetector
- use of
isZero
(see comments)
Orekit 12.0 code:
@Test
void regressionDetection() {
final GradientField field = GradientField.getField(1);
final FieldAbsoluteDate<Gradient> fieldEpoch = FieldAbsoluteDate.getArbitraryEpoch(field);
final FieldPVCoordinates<Gradient> fieldPVCoordinates = new FieldPVCoordinates<>(
new FieldVector3D<>(field, new Vector3D(10000.e3, 0, 0)),
new FieldVector3D<>(field, new Vector3D(0, 7.5e3, 0)));
final FieldCartesianOrbit<Gradient> fieldOrbit = new FieldCartesianOrbit<>(fieldPVCoordinates,
FramesFactory.getGCRF(), fieldEpoch, field.getZero().add(Constants.EGM96_EARTH_MU));
final ClassicalRungeKuttaFieldIntegrator<Gradient> fieldIntegrator = new ClassicalRungeKuttaFieldIntegrator<>(field,
field.getZero().add(5.));
final FieldNumericalPropagator<Gradient> fieldNumericalPropagator = new FieldNumericalPropagator<>(
field, fieldIntegrator);
fieldNumericalPropagator.resetInitialState(new FieldSpacecraftState<>(fieldOrbit));
fieldNumericalPropagator.setResetAtEnd(true);
final AbsoluteDate epoch = fieldEpoch.toAbsoluteDate();
final TestForce testForce = new TestForce(epoch.shiftedBy(10.),
epoch.shiftedBy(100.), epoch.shiftedBy(1000.));
fieldNumericalPropagator.addForceModel(testForce);
for (AbsoluteDate date: testForce.dates) {
final FieldAbsoluteDate<Gradient> fieldDate = new FieldAbsoluteDate<>(field, date)
.shiftedBy(Gradient.variable(1, 0, 0.));
fieldNumericalPropagator.propagate(fieldDate);
}
}
private static class TestForce implements ForceModel {
private final AbsoluteDate[] dates;
TestForce (AbsoluteDate ...dates) {
this.dates = dates;
}
@Override
public boolean dependsOnPositionOnly() {
return true;
}
@Override
public Stream<EventDetector> getEventDetectors() {
return Arrays.stream(dates).map(DateDetector::new)
.map(d -> d.withHandler((a, b, c) -> Action.RESET_DERIVATIVES));
}
@Override
public <T extends CalculusFieldElement<T>> Stream<FieldEventDetector<T>> getFieldEventDetectors(Field<T> field) {
return Arrays.stream(dates).map(date -> new FieldDateDetector<>(field, new FieldAbsoluteDate<>(field, date)))
.map(d -> d.withHandler((a, b, c) -> Action.RESET_DERIVATIVES));
}
@Override
public Vector3D acceleration(SpacecraftState s, double[] parameters) {
return Vector3D.ZERO;
}
@Override
public <T extends CalculusFieldElement<T>> FieldVector3D<T> acceleration(FieldSpacecraftState<T> s, T[] parameters) {
return FieldVector3D.getZero(s.getDate().getField());
}
@Override
public List<ParameterDriver> getParametersDrivers() {
return new ArrayList<>();
}
}
Orekit 11.3 code:
@Test
void regressionDetection() {
final GradientField field = GradientField.getField(1);
final FieldAbsoluteDate<Gradient> fieldEpoch = FieldAbsoluteDate.getArbitraryEpoch(field);
final FieldPVCoordinates<Gradient> fieldPVCoordinates = new FieldPVCoordinates<>(
new FieldVector3D<>(field, new Vector3D(10000.e3, 0, 0)),
new FieldVector3D<>(field, new Vector3D(0, 7.5e3, 0)));
final FieldCartesianOrbit<Gradient> fieldOrbit = new FieldCartesianOrbit<>(fieldPVCoordinates,
FramesFactory.getGCRF(), fieldEpoch, field.getZero().add(Constants.EGM96_EARTH_MU));
final ClassicalRungeKuttaFieldIntegrator<Gradient> fieldIntegrator = new ClassicalRungeKuttaFieldIntegrator<>(field,
field.getZero().add(5.));
final FieldNumericalPropagator<Gradient> fieldNumericalPropagator = new FieldNumericalPropagator<>(
field, fieldIntegrator);
fieldNumericalPropagator.resetInitialState(new FieldSpacecraftState<>(fieldOrbit));
fieldNumericalPropagator.setResetAtEnd(true);
final AbsoluteDate epoch = fieldEpoch.toAbsoluteDate();
final TestForce testForce = new TestForce(epoch.shiftedBy(10.),
epoch.shiftedBy(100.), epoch.shiftedBy(1000.));
fieldNumericalPropagator.addForceModel(testForce);
for (AbsoluteDate date: testForce.dates) {
final FieldAbsoluteDate<Gradient> fieldDate = new FieldAbsoluteDate<>(field, date)
.shiftedBy(Gradient.variable(1, 0, 0.));
fieldNumericalPropagator.propagate(fieldDate);
}
}
private static class TestForce extends AbstractForceModel {
private final AbsoluteDate[] dates;
TestForce (AbsoluteDate ...dates) {
this.dates = dates;
}
@Override
public boolean dependsOnPositionOnly() {
return true;
}
@Override
public Stream<EventDetector> getEventsDetectors() {
return Arrays.stream(dates).map(DateDetector::new)
.map(d -> d.withHandler((a, b, c) -> Action.RESET_DERIVATIVES));
}
@Override
public <T extends CalculusFieldElement<T>> Stream<FieldEventDetector<T>> getFieldEventsDetectors(Field<T> field) {
return Arrays.stream(dates).map(date ->
new FieldDateDetector<>(field.getZero().add(AbstractDetector.DEFAULT_MAXCHECK),
field.getZero().add(AbstractDetector.DEFAULT_THRESHOLD), new FieldAbsoluteDate<>(field, date)))
.map(d -> d.withHandler((a, b, c) -> Action.RESET_DERIVATIVES));
}
@Override
public Vector3D acceleration(SpacecraftState s, double[] parameters) {
return Vector3D.ZERO;
}
@Override
public <T extends CalculusFieldElement<T>> FieldVector3D<T> acceleration(FieldSpacecraftState<T> s, T[] parameters) {
return FieldVector3D.getZero(s.getDate().getField());
}
@Override
public List<ParameterDriver> getParametersDrivers() {
return new ArrayList<>();
}
}
Edited by Romain Serra