prevent too small (sometimes exactly 0) steps to occur

when an event is within convergence tolerance to the step end

git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/trunk@783529 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Luc Maisonobe 2009-06-10 21:44:33 +00:00
parent b63d261b54
commit 9d4fb6760b
4 changed files with 30 additions and 7 deletions

View File

@ -309,8 +309,14 @@ public class AdamsMoultonIntegrator extends MultistepIntegrator {
interpolatorTmp.shift();
interpolatorTmp.storeTime(stepEnd);
if (manager.evaluateStep(interpolatorTmp)) {
// reject the step to match exactly the next switch time
hNew = manager.getEventTime() - stepStart;
final double dt = manager.getEventTime() - stepStart;
if (Math.abs(dt) <= Math.ulp(stepStart)) {
// rejecting the step would lead to a too small next step, we accept it
loop = false;
} else {
// reject the step to match exactly the next switch time
hNew = dt;
}
} else {
// accept the step
scaled = correctedScaled;

View File

@ -268,8 +268,14 @@ public abstract class EmbeddedRungeKuttaIntegrator
// discrete events handling
interpolator.storeTime(stepStart + stepSize);
if (manager.evaluateStep(interpolator)) {
// reject the step to match exactly the next switch time
hNew = manager.getEventTime() - stepStart;
final double dt = manager.getEventTime() - stepStart;
if (Math.abs(dt) <= Math.ulp(stepStart)) {
// rejecting the step would lead to a too small next step, we accept it
loop = false;
} else {
// reject the step to match exactly the next switch time
hNew = dt;
}
} else {
// accept the step
loop = false;

View File

@ -831,8 +831,12 @@ public class GraggBulirschStoerIntegrator
if (!reject) {
interpolator.storeTime(stepStart + stepSize);
if (eventsHandlersManager.evaluateStep(interpolator)) {
reject = true;
hNew = Math.abs(eventsHandlersManager.getEventTime() - stepStart);
final double dt = eventsHandlersManager.getEventTime() - stepStart;
if (Math.abs(dt) > Math.ulp(stepStart)) {
// reject the step to match exactly the next switch time
hNew = Math.abs(dt);
reject = true;
}
}
}

View File

@ -158,7 +158,14 @@ public abstract class RungeKuttaIntegrator extends AbstractIntegrator {
// discrete events handling
interpolator.storeTime(stepStart + stepSize);
if (manager.evaluateStep(interpolator)) {
stepSize = manager.getEventTime() - stepStart;
final double dt = manager.getEventTime() - stepStart;
if (Math.abs(dt) <= Math.ulp(stepStart)) {
// rejecting the step would lead to a too small next step, we accept it
loop = false;
} else {
// reject the step to match exactly the next switch time
stepSize = dt;
}
} else {
loop = false;
}