use of org.orekit.propagation.events.EventState.EventOccurrence in project Orekit by CS-SI.
the class AbstractAnalyticalPropagator method acceptStep.
/**
* Accept a step, triggering events and step handlers.
* @param interpolator interpolator for the current step
* @param target final propagation time
* @param epsilon threshold for end date detection
* @return state at the end of the step
* @exception OrekitException if the switching function cannot be evaluated
* @exception MathRuntimeException if an event cannot be located
*/
protected SpacecraftState acceptStep(final OrekitStepInterpolator interpolator, final AbsoluteDate target, final double epsilon) throws OrekitException, MathRuntimeException {
SpacecraftState previous = interpolator.getPreviousState();
final SpacecraftState current = interpolator.getCurrentState();
// initialize the events states if needed
if (!statesInitialized) {
if (!eventsStates.isEmpty()) {
// initialize the events states
for (final EventState<?> state : eventsStates) {
state.reinitializeBegin(interpolator);
}
}
statesInitialized = true;
}
// search for next events that may occur during the step
final int orderingSign = interpolator.isForward() ? +1 : -1;
final Queue<EventState<?>> occurringEvents = new PriorityQueue<>(new Comparator<EventState<?>>() {
/**
* {@inheritDoc}
*/
@Override
public int compare(final EventState<?> es0, final EventState<?> es1) {
return orderingSign * es0.getEventDate().compareTo(es1.getEventDate());
}
});
for (final EventState<?> state : eventsStates) {
if (state.evaluateStep(interpolator)) {
// the event occurs during the current step
occurringEvents.add(state);
}
}
OrekitStepInterpolator restricted = interpolator;
do {
eventLoop: while (!occurringEvents.isEmpty()) {
// handle the chronologically first event
final EventState<?> currentEvent = occurringEvents.poll();
// get state at event time
SpacecraftState eventState = restricted.getInterpolatedState(currentEvent.getEventDate());
// try to advance all event states to current time
for (final EventState<?> state : eventsStates) {
if (state != currentEvent && state.tryAdvance(eventState, interpolator)) {
// we need to handle another event first
// remove event we just updated to prevent heap corruption
occurringEvents.remove(state);
// add it back to update its position in the heap
occurringEvents.add(state);
// re-queue the event we were processing
occurringEvents.add(currentEvent);
continue eventLoop;
}
}
// all event detectors agree we can advance to the current event time
final EventOccurrence occurrence = currentEvent.doEvent(eventState);
final Action action = occurrence.getAction();
isLastStep = action == Action.STOP;
if (isLastStep) {
// ensure the event is after the root if it is returned STOP
// this lets the user integrate to a STOP event and then restart
// integration from the same time.
eventState = interpolator.getInterpolatedState(occurrence.getStopDate());
restricted = restricted.restrictStep(previous, eventState);
}
// handle the first part of the step, up to the event
if (getStepHandler() != null) {
getStepHandler().handleStep(restricted, isLastStep);
}
if (isLastStep) {
// the event asked to stop integration
return eventState;
}
if (action == Action.RESET_DERIVATIVES || action == Action.RESET_STATE) {
// some event handler has triggered changes that
// invalidate the derivatives, we need to recompute them
final SpacecraftState resetState = occurrence.getNewState();
if (resetState != null) {
resetIntermediateState(resetState, interpolator.isForward());
return resetState;
}
}
// at this point we know action == Action.CONTINUE
// prepare handling of the remaining part of the step
previous = eventState;
restricted = new BasicStepInterpolator(restricted.isForward(), eventState, current);
// check if the same event occurs again in the remaining part of the step
if (currentEvent.evaluateStep(restricted)) {
// the event occurs during the current step
occurringEvents.add(currentEvent);
}
}
// another event detector.
for (final EventState<?> state : eventsStates) {
if (state.tryAdvance(current, interpolator)) {
occurringEvents.add(state);
}
}
} while (!occurringEvents.isEmpty());
isLastStep = target.equals(current.getDate());
// handle the remaining part of the step, after all events if any
if (getStepHandler() != null) {
getStepHandler().handleStep(interpolator, isLastStep);
}
return current;
}
Aggregations