protected FieldODEStateAndDerivative acceptStep()

in commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/ode/AbstractFieldIntegrator.java [292:393]


    protected FieldODEStateAndDerivative<T> acceptStep(final AbstractFieldStepInterpolator<T> interpolator,
                                                       final T tEnd)
        throws MaxCountExceededException, DimensionMismatchException, NoBracketingException {

            FieldODEStateAndDerivative<T> previousState = interpolator.getGlobalPreviousState();
            final FieldODEStateAndDerivative<T> currentState = interpolator.getGlobalCurrentState();

            // initialize the events states if needed
            if (! statesInitialized) {
                for (FieldEventState<T> state : eventsStates) {
                    state.reinitializeBegin(interpolator);
                }
                statesInitialized = true;
            }

            // search for next events that may occur during the step
            final int orderingSign = interpolator.isForward() ? +1 : -1;
            SortedSet<FieldEventState<T>> occurringEvents = new TreeSet<>(new Comparator<FieldEventState<T>>() {

                /** {@inheritDoc} */
                @Override
                public int compare(FieldEventState<T> es0, FieldEventState<T> es1) {
                    return orderingSign * Double.compare(es0.getEventTime().getReal(), es1.getEventTime().getReal());
                }
            });

            for (final FieldEventState<T> state : eventsStates) {
                if (state.evaluateStep(interpolator)) {
                    // the event occurs during the current step
                    occurringEvents.add(state);
                }
            }

            AbstractFieldStepInterpolator<T> restricted = interpolator;
            while (!occurringEvents.isEmpty()) {

                // handle the chronologically first event
                final Iterator<FieldEventState<T>> iterator = occurringEvents.iterator();
                final FieldEventState<T> currentEvent = iterator.next();
                iterator.remove();

                // get state at event time
                final FieldODEStateAndDerivative<T> eventState = restricted.getInterpolatedState(currentEvent.getEventTime());

                // restrict the interpolator to the first part of the step, up to the event
                restricted = restricted.restrictStep(previousState, eventState);

                // advance all event states to current time
                for (final FieldEventState<T> state : eventsStates) {
                    state.stepAccepted(eventState);
                    isLastStep = isLastStep || state.stop();
                }

                // handle the first part of the step, up to the event
                for (final FieldStepHandler<T> handler : stepHandlers) {
                    handler.handleStep(restricted, isLastStep);
                }

                if (isLastStep) {
                    // the event asked to stop integration
                    return eventState;
                }

                FieldODEState<T> newState = null;
                resetOccurred = false;
                for (final FieldEventState<T> state : eventsStates) {
                    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
                previousState = eventState;
                restricted = restricted.restrictStep(eventState, currentState);

                // 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);
                }
            }

            // last part of the step, after the last event
            for (final FieldEventState<T> state : eventsStates) {
                state.stepAccepted(currentState);
                isLastStep = isLastStep || state.stop();
            }
            isLastStep = isLastStep || currentState.getTime().subtract(tEnd).abs().getReal() <= JdkMath.ulp(tEnd.getReal());

            // handle the remaining part of the step, after all events if any
            for (FieldStepHandler<T> handler : stepHandlers) {
                handler.handleStep(restricted, isLastStep);
            }

            return currentState;
    }