Fixed wrong state reset in field ode.

This commit is contained in:
Luc Maisonobe 2016-01-06 12:40:22 +01:00
parent c053a327f9
commit aab178594f
2 changed files with 22 additions and 16 deletions

View File

@ -340,17 +340,17 @@ public abstract class AbstractFieldIntegrator<T extends RealFieldElement<T>> imp
return eventState;
}
boolean needReset = false;
FieldODEState<T> newState = null;
for (final FieldEventState<T> state : eventsStates) {
needReset = needReset || state.reset(eventState);
}
if (needReset) {
// some event handler has triggered changes that
// invalidate the derivatives, we need to recompute them
final T[] y = equations.getMapper().mapState(eventState);
final T[] yDot = computeDerivatives(eventState.getTime(), y);
resetOccurred = true;
return equations.getMapper().mapStateAndDerivative(eventState.getTime(), y, yDot);
newState = state.reset(eventState);
if (newState != null) {
// some event handler has triggered changes that
// invalidate the derivatives, we need to recompute them
final T[] y = equations.getMapper().mapState(newState);
final T[] yDot = computeDerivatives(newState.getTime(), y);
resetOccurred = true;
return equations.getMapper().mapStateAndDerivative(newState.getTime(), y, yDot);
}
}
// prepare handling of the remaining part of the step

View File

@ -23,6 +23,7 @@ import org.apache.commons.math4.analysis.solvers.AllowedSolution;
import org.apache.commons.math4.analysis.solvers.BracketedRealFieldUnivariateSolver;
import org.apache.commons.math4.exception.MaxCountExceededException;
import org.apache.commons.math4.exception.NoBracketingException;
import org.apache.commons.math4.ode.FieldODEState;
import org.apache.commons.math4.ode.FieldODEStateAndDerivative;
import org.apache.commons.math4.ode.sampling.FieldStepInterpolator;
import org.apache.commons.math4.util.FastMath;
@ -325,22 +326,27 @@ public class FieldEventState<T extends RealFieldElement<T>> {
/** Let the event handler reset the state if it wants.
* @param state state at the beginning of the next step
* @return true if the integrator should reset the derivatives too
* @return reset state (may by the same as initial state if only
* derivatives should be reset), or null if nothing is reset
*/
public boolean reset(final FieldODEStateAndDerivative<T> state) {
public FieldODEState<T> reset(final FieldODEStateAndDerivative<T> state) {
if (!(pendingEvent && pendingEventTime.subtract(state.getTime()).abs().subtract(convergence).getReal() <= 0)) {
return false;
return null;
}
final FieldODEState<T> newState;
if (nextAction == Action.RESET_STATE) {
handler.resetState(state);
newState = handler.resetState(state);
} else if (nextAction == Action.RESET_DERIVATIVES) {
newState = state;
} else {
newState = null;
}
pendingEvent = false;
pendingEventTime = null;
return (nextAction == Action.RESET_STATE) ||
(nextAction == Action.RESET_DERIVATIVES);
return newState;
}