fixed an infinite loop error that occurred when an event that reset the state occurs exactly at multistep initialisation start

git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/trunk@781156 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Luc Maisonobe 2009-06-02 20:39:41 +00:00
parent ed813abf79
commit ebd8043bee

View File

@ -161,9 +161,15 @@ public abstract class MultistepIntegrator extends AbstractIntegrator {
double stopTime = Double.NaN; double stopTime = Double.NaN;
do { do {
resetTime = Double.NaN; resetTime = Double.NaN;
final double dt = (n - 0.9999) * h;
for (EventHandler handler : starter.getEventHandlers()) {
((ResetCheckingWrapper) handler).setRange(t, Math.abs(dt));
}
store.restart(); store.restart();
// we overshoot by 1/10000 step the end to make sure we don't miss the last point // we overshoot by 1/10000 step the end to make sure we don't miss the last point
stopTime = starter.integrate(equations, t, y, t + (n - 0.9999) * h, y); stopTime = starter.integrate(equations, t, y, t + dt, y);
if (!Double.isNaN(resetTime)) { if (!Double.isNaN(resetTime)) {
// there was an intermediate reset, we restart // there was an intermediate reset, we restart
t = resetTime; t = resetTime;
@ -201,6 +207,12 @@ public abstract class MultistepIntegrator extends AbstractIntegrator {
/** Wrapped event handler. */ /** Wrapped event handler. */
private final EventHandler handler; private final EventHandler handler;
/** Range start. */
private double rangeStart;
/** Range size. */
private double rangeSize;
/** Build a new instance. /** Build a new instance.
* @param handler event handler to wrap * @param handler event handler to wrap
*/ */
@ -208,10 +220,23 @@ public abstract class MultistepIntegrator extends AbstractIntegrator {
this.handler = handler; this.handler = handler;
} }
/** Set the range.
* @param rangeStart range start
* @param rangeSize range size
*/
public void setRange(final double rangeStart, final double rangeSize) {
this.rangeStart = rangeStart;
this.rangeSize = rangeSize;
}
/** {@inheritDoc} */ /** {@inheritDoc} */
public int eventOccurred(double t, double[] y, boolean increasing) public int eventOccurred(double t, double[] y, boolean increasing)
throws EventException { throws EventException {
final int action = handler.eventOccurred(t, y, increasing); final int action = handler.eventOccurred(t, y, increasing);
if (Math.abs(t - rangeStart) < 1.0e-10 * rangeSize) {
// we have encountered again an already handled reset, don't stop here
return action;
}
if ((action == RESET_DERIVATIVES) || (action == RESET_STATE)) { if ((action == RESET_DERIVATIVES) || (action == RESET_STATE)) {
// a singularity has been encountered // a singularity has been encountered
// we need to restart the start phase // we need to restart the start phase