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