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