View Javadoc

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 org.apache.commons.math.ode.FirstOrderDifferentialEquations;
21  import org.apache.commons.math.ode.sampling.StepHandler;
22  
23  /** This interface represents a handler for discrete events triggered
24   * during ODE integration.
25   *
26   * <p>Some events can be triggered at discrete times as an ODE problem
27   * is solved. These occurs for example when the integration process
28   * should be stopped as some state is reached (G-stop facility) when the
29   * precise date is unknown a priori, or when the derivatives have
30   * discontinuities, or simply when the user wants to monitor some
31   * states boundaries crossings.
32   * </p>
33   * 
34   * <p>These events are defined as occurring when a <code>g</code>
35   * switching function sign changes.</p>
36   *
37   * <p>Since events are only problem-dependent and are triggered by the
38   * independent <i>time</i> variable and the state vector, they can
39   * occur at virtually any time, unknown in advance. The integrators will
40   * take care to avoid sign changes inside the steps, they will reduce
41   * the step size when such an event is detected in order to put this
42   * event exactly at the end of the current step. This guarantees that
43   * step interpolation (which always has a one step scope) is relevant
44   * even in presence of discontinuities. This is independent from the
45   * stepsize control provided by integrators that monitor the local
46   * error (this event handling feature is available for all integrators,
47   * including fixed step ones).</p>
48   *
49   * @version $Revision: 785473 $ $Date: 2009-06-17 00:02:35 -0400 (Wed, 17 Jun 2009) $
50   * @since 1.2
51   */
52  
53  public interface EventHandler  {
54  
55    /** Stop indicator.
56     * <p>This value should be used as the return value of the {@link
57     * #eventOccurred eventOccurred} method when the integration should be
58     * stopped after the event ending the current step.</p>
59     */
60    public static final int STOP = 0;
61  
62    /** Reset state indicator.
63     * <p>This value should be used as the return value of the {@link
64     * #eventOccurred eventOccurred} method when the integration should
65     * go on after the event ending the current step, with a new state
66     * vector (which will be retrieved thanks to the {@link #resetState
67     * resetState} method).</p>
68     */
69    public static final int RESET_STATE = 1;
70  
71    /** Reset derivatives indicator.
72     * <p>This value should be used as the return value of the {@link
73     * #eventOccurred eventOccurred} method when the integration should
74     * go on after the event ending the current step, with a new derivatives
75     * vector (which will be retrieved thanks to the {@link
76     * FirstOrderDifferentialEquations#computeDerivatives} method).</p>
77     */
78    public static final int RESET_DERIVATIVES = 2;
79  
80    /** Continue indicator.
81     * <p>This value should be used as the return value of the {@link
82     * #eventOccurred eventOccurred} method when the integration should go
83     * on after the event ending the current step.</p>
84     */
85    public static final int CONTINUE = 3;
86  
87    /** Compute the value of the switching function.
88  
89     * <p>The discrete events are generated when the sign of this 
90     * switching function changes. The integrator will take care to change
91     * the stepsize in such a way these events occur exactly at step boundaries.
92     * The switching function must be continuous in its roots neighborhood
93     * (but not necessarily smooth), as the integrator will need to find its
94     * roots to locate precisely the events.</p>
95  
96     * @param t current value of the independent <i>time</i> variable
97     * @param y array containing the current value of the state vector
98     * @return value of the g switching function
99     * @exception EventException if the switching function cannot be evaluated
100    */
101   public double g(double t, double[] y) throws EventException;
102 
103   /** Handle an event and choose what to do next.
104 
105    * <p>This method is called when the integrator has accepted a step
106    * ending exactly on a sign change of the function, just before the
107    * step handler itself is called. It allows the user to update his
108    * internal data to acknowledge the fact the event has been handled
109    * (for example setting a flag in the {@link
110    * FirstOrderDifferentialEquations differential equations} to switch
111    * the derivatives computation in case of discontinuity), or to
112    * direct the integrator to either stop or continue integration,
113    * possibly with a reset state or derivatives.</p>
114 
115    * <ul>
116    *   <li>if {@link #STOP} is returned, the step handler will be called
117    *   with the <code>isLast</code> flag of the {@link
118    *   StepHandler#handleStep handleStep} method set to true and the
119    *   integration will be stopped,</li>
120    *   <li>if {@link #RESET_STATE} is returned, the {@link #resetState
121    *   resetState} method will be called once the step handler has
122    *   finished its task, and the integrator will also recompute the
123    *   derivatives,</li>
124    *   <li>if {@link #RESET_DERIVATIVES} is returned, the integrator
125    *   will recompute the derivatives,
126    *   <li>if {@link #CONTINUE} is returned, no specific action will
127    *   be taken (apart from having called this method) and integration
128    *   will continue.</li>
129    * </ul>
130 
131    * @param t current value of the independent <i>time</i> variable
132    * @param y array containing the current value of the state vector
133    * @param increasing if true, the value of the switching function increases
134    * when times increases around event (note that increase is measured with respect
135    * to physical time, not with respect to integration which may go backward in time)
136    * @return indication of what the integrator should do next, this
137    * value must be one of {@link #STOP}, {@link #RESET_STATE},
138    * {@link #RESET_DERIVATIVES} or {@link #CONTINUE}
139    * @exception EventException if the event occurrence triggers an error
140    */
141   public int eventOccurred(double t, double[] y, boolean increasing) throws EventException;
142   
143   /** Reset the state prior to continue the integration.
144 
145    * <p>This method is called after the step handler has returned and
146    * before the next step is started, but only when {@link
147    * #eventOccurred} has itself returned the {@link #RESET_STATE}
148    * indicator. It allows the user to reset the state vector for the
149    * next step, without perturbing the step handler of the finishing
150    * step. If the {@link #eventOccurred} never returns the {@link
151    * #RESET_STATE} indicator, this function will never be called, and it is
152    * safe to leave its body empty.</p>
153 
154    * @param t current value of the independent <i>time</i> variable
155    * @param y array containing the current value of the state vector
156    * the new state should be put in the same array
157    * @exception EventException if the state cannot be reseted
158    */
159   public void resetState(double t, double[] y) throws EventException;
160 
161 }