View Javadoc
1   /*
2    * Licensed to the Hipparchus project 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 Hipparchus project 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    *      https://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.hipparchus.ode.events;
19  
20  import org.hipparchus.CalculusFieldElement;
21  import org.hipparchus.analysis.solvers.BracketedRealFieldUnivariateSolver;
22  import org.hipparchus.analysis.solvers.FieldBracketingNthOrderBrentSolver;
23  import org.hipparchus.ode.FieldODEStateAndDerivative;
24  
25  /** Base class for #@link {@link FieldODEEventDetector}.
26   * @param <T> type of the detector
27   * @param <E> type of the field elements
28   * @since 3.0
29   */
30  public abstract class AbstractFieldODEDetector<T extends AbstractFieldODEDetector<T, E>, E extends CalculusFieldElement<E>>
31      implements FieldODEEventDetector<E> {
32  
33      /** Default maximum checking interval (s). */
34      public static final double DEFAULT_MAX_CHECK = AbstractODEDetector.DEFAULT_MAX_CHECK;
35  
36      /** Default convergence threshold (s). */
37      public static final double DEFAULT_THRESHOLD = AbstractODEDetector.DEFAULT_THRESHOLD;
38  
39      /** Default maximum number of iterations in the event time search. */
40      public static final int DEFAULT_MAX_ITER = AbstractODEDetector.DEFAULT_MAX_ITER;
41  
42      /** Max check interval. */
43      private final FieldAdaptableInterval<E> maxCheck;
44  
45      /** Maximum number of iterations in the event time search. */
46      private final int maxIter;
47  
48      /** Root-finding algorithm to use to detect state events. */
49      private final BracketedRealFieldUnivariateSolver<E> solver;
50  
51      /** Default handler for event overrides. */
52      private final FieldODEEventHandler<E> handler;
53  
54      /** Propagation direction. */
55      private boolean forward;
56  
57      /** Build a new instance.
58       * @param maxCheck maximum checking interval, must be strictly positive (s)
59       * @param maxIter maximum number of iterations in the event time search
60       * @param solver root-finding algorithm to use to detect state events
61       * @param handler event handler to call at event occurrences
62       */
63      protected AbstractFieldODEDetector(final FieldAdaptableInterval<E> maxCheck, final int maxIter,
64                                         final BracketedRealFieldUnivariateSolver<E> solver,
65                                         final FieldODEEventHandler<E> handler) {
66          this.maxCheck  = maxCheck;
67          this.maxIter   = maxIter;
68          this.solver    = solver;
69          this.handler   = handler;
70          this.forward   = true;
71      }
72  
73      /**
74       * {@inheritDoc}
75       *
76       * <p> This implementation sets the direction of integration and initializes the event
77       * handler. If a subclass overrides this method it should call {@code
78       * super.init(s0, t)}.
79       */
80      @Override
81      public void init(final FieldODEStateAndDerivative<E> s0, final E t) {
82          FieldODEEventDetector.super.init(s0, t);
83          forward = t.subtract(s0.getTime()).getReal() >= 0;
84      }
85  
86      /** {@inheritDoc} */
87      @Override
88      public FieldAdaptableInterval<E> getMaxCheckInterval() {
89          return maxCheck;
90      }
91  
92      /** {@inheritDoc} */
93      @Override
94      public int getMaxIterationCount() {
95          return maxIter;
96      }
97  
98      /** {@inheritDoc} */
99      @Override
100     public BracketedRealFieldUnivariateSolver<E> getSolver() {
101         return solver;
102     }
103 
104     /**
105      * Setup the maximum checking interval.
106      * <p>
107      * This will override a maximum checking interval if it has been configured previously.
108      * </p>
109      * @param newMaxCheck maximum checking interval (s)
110      * @return a new detector with updated configuration (the instance is not changed)
111      */
112     public T withMaxCheck(final E newMaxCheck) {
113         return withMaxCheck(FieldAdaptableInterval.of(newMaxCheck.getReal()));
114     }
115 
116     /**
117      * Setup the maximum checking interval.
118      * <p>
119      * This will override a maximum checking interval if it has been configured previously.
120      * </p>
121      * @param newMaxCheck maximum checking interval (s)
122      * @return a new detector with updated configuration (the instance is not changed)
123      * @since 3.0
124      */
125     public T withMaxCheck(final FieldAdaptableInterval<E> newMaxCheck) {
126         return create(newMaxCheck, getMaxIterationCount(), getSolver(), getHandler());
127     }
128 
129     /**
130      * Setup the maximum number of iterations in the event time search.
131      * <p>
132      * This will override a number of iterations if it has been configured previously.
133      * </p>
134      * @param newMaxIter maximum number of iterations in the event time search
135      * @return a new detector with updated configuration (the instance is not changed)
136      */
137     public T withMaxIter(final int newMaxIter) {
138         return create(getMaxCheckInterval(), newMaxIter, getSolver(), getHandler());
139     }
140 
141     /**
142      * Setup the convergence threshold.
143      * <p>
144      * This is equivalent to call {@code withSolver(new FieldBracketingNthOrderBrentSolver<>(zero,
145      * newThreshold, zero, 5)}, so it will override a solver if one has been configured previously.
146      * </p>
147      * @param newThreshold convergence threshold
148      * @return a new detector with updated configuration (the instance is not changed)
149      * @see #withSolver(BracketedRealFieldUnivariateSolver)
150      */
151     public T withThreshold(final E newThreshold) {
152         final E zero = newThreshold.getField().getZero();
153         return withSolver(new FieldBracketingNthOrderBrentSolver<>(zero, newThreshold, zero, 5));
154     }
155 
156     /**
157      * Setup the root-finding algorithm to use to detect state events.
158      * <p>
159      * This will override a solver if it has been configured previously.
160      * </p>
161      * @param newSolver root-finding algorithm to use to detect state events
162      * @return a new detector with updated configuration (the instance is not changed)
163      * @see #withThreshold(CalculusFieldElement)
164      */
165     public T withSolver(final BracketedRealFieldUnivariateSolver<E> newSolver) {
166         return create(getMaxCheckInterval(), getMaxIterationCount(), newSolver, getHandler());
167     }
168 
169     /**
170      * Setup the event handler to call at event occurrences.
171      * <p>
172      * This will override a handler if it has been configured previously.
173      * </p>
174      * @param newHandler event handler to call at event occurrences
175      * @return a new detector with updated configuration (the instance is not changed)
176      */
177     public T withHandler(final FieldODEEventHandler<E> newHandler) {
178         return create(getMaxCheckInterval(), getMaxIterationCount(), getSolver(), newHandler);
179     }
180 
181     /** {@inheritDoc} */
182     @Override
183     public FieldODEEventHandler<E> getHandler() {
184         return handler;
185     }
186 
187     /** Build a new instance.
188      * @param newMaxCheck maximum checking interval
189      * @param newMaxIter maximum number of iterations in the event time search
190      * @param newSolver root-finding algorithm to use to detect state events
191      * @param newHandler event handler to call at event occurrences
192      * @return a new instance of the appropriate sub-type
193      */
194     protected abstract T create(FieldAdaptableInterval<E> newMaxCheck, int newMaxIter,
195                                 BracketedRealFieldUnivariateSolver<E> newSolver,
196                                 FieldODEEventHandler<E> newHandler);
197 
198     /** Check if the current propagation is forward or backward.
199      * @return true if the current propagation is forward
200      */
201     public boolean isForward() {
202         return forward;
203     }
204 
205 }