second attempt at fixing MATH-484
This fixes bad behavior when several events occur during a long step This also fixes bad behavior when events are triggered during backward integration Jira: MATH-484 git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/trunk@1070499 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
26c1c29575
commit
5a2bf9c657
|
@ -21,6 +21,7 @@ import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.SortedSet;
|
import java.util.SortedSet;
|
||||||
import java.util.TreeSet;
|
import java.util.TreeSet;
|
||||||
|
@ -245,16 +246,17 @@ public abstract class AbstractIntegrator implements FirstOrderIntegrator {
|
||||||
statesInitialized = true;
|
statesInitialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// search for next events that may occur during the step
|
||||||
|
final int orderingSign = interpolator.isForward() ? +1 : -1;
|
||||||
SortedSet<EventState> occuringEvents = new TreeSet<EventState>(new Comparator<EventState>() {
|
SortedSet<EventState> occuringEvents = new TreeSet<EventState>(new Comparator<EventState>() {
|
||||||
|
|
||||||
/** {@inheritDoc} */
|
/** {@inheritDoc} */
|
||||||
public int compare(EventState es0, EventState es1) {
|
public int compare(EventState es0, EventState es1) {
|
||||||
return Double.compare(es0.getEventTime(), es1.getEventTime());
|
return orderingSign * Double.compare(es0.getEventTime(), es1.getEventTime());
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// find all events that occur during the step
|
|
||||||
for (final EventState state : eventsStates) {
|
for (final EventState state : eventsStates) {
|
||||||
if (state.evaluateStep(interpolator)) {
|
if (state.evaluateStep(interpolator)) {
|
||||||
// the event occurs during the current step
|
// the event occurs during the current step
|
||||||
|
@ -262,19 +264,23 @@ public abstract class AbstractIntegrator implements FirstOrderIntegrator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// handle the events chronologically
|
while (!occuringEvents.isEmpty()) {
|
||||||
for (final EventState state : occuringEvents) {
|
|
||||||
|
// handle the chronologically first event
|
||||||
|
final Iterator<EventState> iterator = occuringEvents.iterator();
|
||||||
|
final EventState currentEvent = iterator.next();
|
||||||
|
iterator.remove();
|
||||||
|
|
||||||
// restrict the interpolator to the first part of the step, up to the event
|
// restrict the interpolator to the first part of the step, up to the event
|
||||||
final double eventT = state.getEventTime();
|
final double eventT = currentEvent.getEventTime();
|
||||||
interpolator.setSoftPreviousTime(previousT);
|
interpolator.setSoftPreviousTime(previousT);
|
||||||
interpolator.setSoftCurrentTime(eventT);
|
interpolator.setSoftCurrentTime(eventT);
|
||||||
|
|
||||||
// trigger the event
|
// trigger the event
|
||||||
interpolator.setInterpolatedTime(eventT);
|
interpolator.setInterpolatedTime(eventT);
|
||||||
final double[] eventY = interpolator.getInterpolatedState();
|
final double[] eventY = interpolator.getInterpolatedState();
|
||||||
state.stepAccepted(eventT, eventY);
|
currentEvent.stepAccepted(eventT, eventY);
|
||||||
isLastStep = state.stop();
|
isLastStep = currentEvent.stop();
|
||||||
|
|
||||||
// handle the first part of the step, up to the event
|
// handle the first part of the step, up to the event
|
||||||
for (final StepHandler handler : stepHandlers) {
|
for (final StepHandler handler : stepHandlers) {
|
||||||
|
@ -287,7 +293,7 @@ public abstract class AbstractIntegrator implements FirstOrderIntegrator {
|
||||||
return eventT;
|
return eventT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state.reset(eventT, eventY)) {
|
if (currentEvent.reset(eventT, eventY)) {
|
||||||
// some event handler has triggered changes that
|
// some event handler has triggered changes that
|
||||||
// invalidate the derivatives, we need to recompute them
|
// invalidate the derivatives, we need to recompute them
|
||||||
System.arraycopy(eventY, 0, y, 0, y.length);
|
System.arraycopy(eventY, 0, y, 0, y.length);
|
||||||
|
@ -301,6 +307,12 @@ public abstract class AbstractIntegrator implements FirstOrderIntegrator {
|
||||||
interpolator.setSoftPreviousTime(eventT);
|
interpolator.setSoftPreviousTime(eventT);
|
||||||
interpolator.setSoftCurrentTime(currentT);
|
interpolator.setSoftCurrentTime(currentT);
|
||||||
|
|
||||||
|
// check if the same event occurs again in the remaining part of the step
|
||||||
|
if (currentEvent.evaluateStep(interpolator)) {
|
||||||
|
// the event occurs during the current step
|
||||||
|
occuringEvents.add(currentEvent);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interpolator.setInterpolatedTime(currentT);
|
interpolator.setInterpolatedTime(currentT);
|
||||||
|
|
Loading…
Reference in New Issue