Home | History | Annotate | Download | only in events
      1 /*
      2  * Licensed to the Apache Software Foundation (ASF) under one or more
      3  * contributor license agreements.  See the NOTICE file distributed with
      4  * this work for additional information regarding copyright ownership.
      5  * The ASF licenses this file to You under the Apache License, Version 2.0
      6  * (the "License"); you may not use this file except in compliance with
      7  * the License.  You may obtain a copy of the License at
      8  *
      9  *      http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  * Unless required by applicable law or agreed to in writing, software
     12  * distributed under the License is distributed on an "AS IS" BASIS,
     13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  * See the License for the specific language governing permissions and
     15  * limitations under the License.
     16  */
     17 
     18 package org.apache.commons.math.ode.events;
     19 
     20 import java.util.ArrayList;
     21 import java.util.Collection;
     22 import java.util.Collections;
     23 import java.util.List;
     24 
     25 import org.apache.commons.math.ConvergenceException;
     26 import org.apache.commons.math.ode.DerivativeException;
     27 import org.apache.commons.math.ode.IntegratorException;
     28 import org.apache.commons.math.ode.sampling.StepInterpolator;
     29 
     30 /** This class manages several {@link EventHandler event handlers} during integration.
     31  *
     32  * @see EventHandler
     33  * @see EventState
     34  * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 fvr. 2011) $
     35  * @since 1.2
     36  * @deprecated as of 2.2, this class is not used anymore
     37  */
     38 @Deprecated
     39 public class CombinedEventsManager {
     40 
     41     /** Events states. */
     42     private final List<EventState> states;
     43 
     44     /** First active event. */
     45     private EventState first;
     46 
     47     /** Initialization indicator. */
     48     private boolean initialized;
     49 
     50     /** Simple constructor.
     51      * Create an empty manager
     52      */
     53     public CombinedEventsManager() {
     54         states      = new ArrayList<EventState>();
     55         first       = null;
     56         initialized = false;
     57     }
     58 
     59     /** Add an events handler.
     60      * @param handler event handler
     61      * @param maxCheckInterval maximal time interval between events
     62      * checks (this interval prevents missing sign changes in
     63      * case the integration steps becomes very large)
     64      * @param convergence convergence threshold in the event time search
     65      * @param maxIterationCount upper limit of the iteration count in
     66      * the event time search
     67      * @see #getEventsHandlers()
     68      * @see #clearEventsHandlers()
     69      */
     70     public void addEventHandler(final EventHandler handler, final double maxCheckInterval,
     71                                 final double convergence, final int maxIterationCount) {
     72         states.add(new EventState(handler, maxCheckInterval,
     73                                   convergence, maxIterationCount));
     74     }
     75 
     76     /** Get all the events handlers that have been added to the manager.
     77      * @return an unmodifiable collection of the added event handlers
     78      * @see #addEventHandler(EventHandler, double, double, int)
     79      * @see #clearEventsHandlers()
     80      * @see #getEventsStates()
     81      */
     82     public Collection<EventHandler> getEventsHandlers() {
     83         final List<EventHandler> list = new ArrayList<EventHandler>();
     84         for (EventState state : states) {
     85             list.add(state.getEventHandler());
     86         }
     87         return Collections.unmodifiableCollection(list);
     88     }
     89 
     90     /** Remove all the events handlers that have been added to the manager.
     91      * @see #addEventHandler(EventHandler, double, double, int)
     92      * @see #getEventsHandlers()
     93      */
     94     public void clearEventsHandlers() {
     95         states.clear();
     96     }
     97 
     98     /** Get all the events state wrapping the handlers that have been added to the manager.
     99      * @return a collection of the events states
    100      * @see #getEventsHandlers()
    101      */
    102     public Collection<EventState> getEventsStates() {
    103         return states;
    104     }
    105 
    106     /** Check if the manager does not manage any event handlers.
    107      * @return true if manager is empty
    108      */
    109     public boolean isEmpty() {
    110         return states.isEmpty();
    111     }
    112 
    113     /** Evaluate the impact of the proposed step on all managed
    114      * event handlers.
    115      * @param interpolator step interpolator for the proposed step
    116      * @return true if at least one event handler triggers an event
    117      * before the end of the proposed step (this implies the step should
    118      * be rejected)
    119      * @exception DerivativeException if the interpolator fails to
    120      * compute the function somewhere within the step
    121      * @exception IntegratorException if an event cannot be located
    122      */
    123     public boolean evaluateStep(final StepInterpolator interpolator)
    124     throws DerivativeException, IntegratorException {
    125 
    126         try {
    127 
    128             first = null;
    129             if (states.isEmpty()) {
    130                 // there is nothing to do, return now to avoid setting the
    131                 // interpolator time (and hence avoid unneeded calls to the
    132                 // user function due to interpolator finalization)
    133                 return false;
    134             }
    135 
    136             if (! initialized) {
    137 
    138                 // initialize the events states
    139                 for (EventState state : states) {
    140                     state.reinitializeBegin(interpolator);
    141                 }
    142 
    143                 initialized = true;
    144 
    145             }
    146 
    147             // check events occurrence
    148             for (EventState state : states) {
    149 
    150                 if (state.evaluateStep(interpolator)) {
    151                     if (first == null) {
    152                         first = state;
    153                     } else {
    154                         if (interpolator.isForward()) {
    155                             if (state.getEventTime() < first.getEventTime()) {
    156                                 first = state;
    157                             }
    158                         } else {
    159                             if (state.getEventTime() > first.getEventTime()) {
    160                                 first = state;
    161                             }
    162                         }
    163                     }
    164                 }
    165 
    166             }
    167 
    168             return first != null;
    169 
    170         } catch (EventException se) {
    171             final Throwable cause = se.getCause();
    172             if ((cause != null) && (cause instanceof DerivativeException)) {
    173                 throw (DerivativeException) cause;
    174             }
    175             throw new IntegratorException(se);
    176         } catch (ConvergenceException ce) {
    177             throw new IntegratorException(ce);
    178         }
    179 
    180     }
    181 
    182     /** Get the occurrence time of the first event triggered in the
    183      * last evaluated step.
    184      * @return occurrence time of the first event triggered in the last
    185      * evaluated step, or </code>Double.NaN</code> if no event is
    186      * triggered
    187      */
    188     public double getEventTime() {
    189         return (first == null) ? Double.NaN : first.getEventTime();
    190     }
    191 
    192     /** Inform the event handlers that the step has been accepted
    193      * by the integrator.
    194      * @param t value of the independent <i>time</i> variable at the
    195      * end of the step
    196      * @param y array containing the current value of the state vector
    197      * at the end of the step
    198      * @exception IntegratorException if the value of one of the
    199      * events states cannot be evaluated
    200      */
    201     public void stepAccepted(final double t, final double[] y)
    202     throws IntegratorException {
    203         try {
    204             for (EventState state : states) {
    205                 state.stepAccepted(t, y);
    206             }
    207         } catch (EventException se) {
    208             throw new IntegratorException(se);
    209         }
    210     }
    211 
    212     /** Check if the integration should be stopped at the end of the
    213      * current step.
    214      * @return true if the integration should be stopped
    215      */
    216     public boolean stop() {
    217         for (EventState state : states) {
    218             if (state.stop()) {
    219                 return true;
    220             }
    221         }
    222         return false;
    223     }
    224 
    225     /** Let the event handlers reset the state if they want.
    226      * @param t value of the independent <i>time</i> variable at the
    227      * beginning of the next step
    228      * @param y array were to put the desired state vector at the beginning
    229      * of the next step
    230      * @return true if the integrator should reset the derivatives too
    231      * @exception IntegratorException if one of the events states
    232      * that should reset the state fails to do it
    233      */
    234     public boolean reset(final double t, final double[] y)
    235         throws IntegratorException {
    236         try {
    237             boolean resetDerivatives = false;
    238             for (EventState state : states) {
    239                 if (state.reset(t, y)) {
    240                     resetDerivatives = true;
    241                 }
    242             }
    243             return resetDerivatives;
    244         } catch (EventException se) {
    245             throw new IntegratorException(se);
    246         }
    247     }
    248 
    249 }
    250