1 /* Copyright 2002-2024 CS GROUP
2 * Licensed to CS GROUP (CS) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * CS 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 package org.orekit.propagation.events;
18
19 import org.orekit.errors.OrekitException;
20 import org.orekit.errors.OrekitMessages;
21 import org.orekit.propagation.SpacecraftState;
22 import org.orekit.propagation.events.handlers.EventHandler;
23 import org.orekit.time.AbsoluteDate;
24
25 /** Common parts shared by several orbital events finders.
26 * @param <T> type of the detector
27 * @see org.orekit.propagation.Propagator#addEventDetector(EventDetector)
28 * @author Luc Maisonobe
29 */
30 public abstract class AbstractDetector<T extends AbstractDetector<T>> implements EventDetector {
31
32 /** Default maximum checking interval (s). */
33 public static final double DEFAULT_MAXCHECK = 600;
34
35 /** Default convergence threshold (s). */
36 public static final double DEFAULT_THRESHOLD = 1.e-6;
37
38 /** Default maximum number of iterations in the event time search. */
39 public static final int DEFAULT_MAX_ITER = 100;
40
41 /** Max check interval. */
42 private final AdaptableInterval maxCheck;
43
44 /** Convergence threshold. */
45 private final double threshold;
46
47 /** Maximum number of iterations in the event time search. */
48 private final int maxIter;
49
50 /** Default handler for event overrides. */
51 private final EventHandler handler;
52
53 /** Propagation direction. */
54 private boolean forward;
55
56 /** Build a new instance.
57 * @param maxCheck maximum checking interval, must be strictly positive (s)
58 * @param threshold convergence threshold (s)
59 * @param maxIter maximum number of iterations in the event time search
60 * @param handler event handler to call at event occurrences
61 */
62 protected AbstractDetector(final double maxCheck, final double threshold, final int maxIter,
63 final EventHandler handler) {
64 this(AdaptableInterval.of(maxCheck), threshold, maxIter, handler);
65 }
66
67 /** Build a new instance.
68 * @param maxCheck maximum checking interval
69 * @param threshold convergence threshold (s)
70 * @param maxIter maximum number of iterations in the event time search
71 * @param handler event handler to call at event occurrences
72 * @since 12.0
73 */
74 protected AbstractDetector(final AdaptableInterval maxCheck, final double threshold, final int maxIter,
75 final EventHandler handler) {
76 checkStrictlyPositive(threshold);
77 this.maxCheck = maxCheck;
78 this.threshold = threshold;
79 this.maxIter = maxIter;
80 this.handler = handler;
81 this.forward = true;
82 }
83
84 /** Check value is strictly positive.
85 * @param value value to check
86 * @exception OrekitException if value is not strictly positive
87 * @since 11.2
88 */
89 private void checkStrictlyPositive(final double value) throws OrekitException {
90 if (value <= 0.0) {
91 throw new OrekitException(OrekitMessages.NOT_STRICTLY_POSITIVE, value);
92 }
93 }
94
95 /**
96 * {@inheritDoc}
97 *
98 * <p> This implementation sets the direction of propagation and initializes the event
99 * handler. If a subclass overrides this method it should call {@code
100 * super.init(s0, t)}.
101 */
102 public void init(final SpacecraftState s0,
103 final AbsoluteDate t) {
104 forward = t.durationFrom(s0.getDate()) >= 0.0;
105 getHandler().init(s0, t, this);
106 }
107
108 /** {@inheritDoc} */
109 public abstract double g(SpacecraftState s);
110
111 /** {@inheritDoc} */
112 public AdaptableInterval getMaxCheckInterval() {
113 return maxCheck;
114 }
115
116 /** {@inheritDoc} */
117 public int getMaxIterationCount() {
118 return maxIter;
119 }
120
121 /** {@inheritDoc} */
122 public double getThreshold() {
123 return threshold;
124 }
125
126 /**
127 * Setup the maximum checking interval.
128 * <p>
129 * This will override a maximum checking interval if it has been configured previously.
130 * </p>
131 * @param newMaxCheck maximum checking interval (s)
132 * @return a new detector with updated configuration (the instance is not changed)
133 * @since 6.1
134 */
135 public T withMaxCheck(final double newMaxCheck) {
136 return withMaxCheck(AdaptableInterval.of(newMaxCheck));
137 }
138
139 /**
140 * Setup the maximum checking interval.
141 * <p>
142 * This will override a maximum checking interval if it has been configured previously.
143 * </p>
144 * @param newMaxCheck maximum checking interval (s)
145 * @return a new detector with updated configuration (the instance is not changed)
146 * @since 12.0
147 */
148 public T withMaxCheck(final AdaptableInterval newMaxCheck) {
149 return create(newMaxCheck, getThreshold(), getMaxIterationCount(), getHandler());
150 }
151
152 /**
153 * Setup the maximum number of iterations in the event time search.
154 * <p>
155 * This will override a number of iterations if it has been configured previously.
156 * </p>
157 * @param newMaxIter maximum number of iterations in the event time search
158 * @return a new detector with updated configuration (the instance is not changed)
159 * @since 6.1
160 */
161 public T withMaxIter(final int newMaxIter) {
162 return create(getMaxCheckInterval(), getThreshold(), newMaxIter, getHandler());
163 }
164
165 /**
166 * Setup the convergence threshold.
167 * <p>
168 * This will override a convergence threshold if it has been configured previously.
169 * </p>
170 * @param newThreshold convergence threshold (s)
171 * @return a new detector with updated configuration (the instance is not changed)
172 * @since 6.1
173 */
174 public T withThreshold(final double newThreshold) {
175 return create(getMaxCheckInterval(), newThreshold, getMaxIterationCount(), getHandler());
176 }
177
178 /**
179 * Setup the event handler to call at event occurrences.
180 * <p>
181 * This will override a handler if it has been configured previously.
182 * </p>
183 * @param newHandler event handler to call at event occurrences
184 * @return a new detector with updated configuration (the instance is not changed)
185 * @since 6.1
186 */
187 public T withHandler(final EventHandler newHandler) {
188 return create(getMaxCheckInterval(), getThreshold(), getMaxIterationCount(), newHandler);
189 }
190
191 /** {@inheritDoc} */
192 @Override
193 public EventHandler getHandler() {
194 return handler;
195 }
196
197 /** Build a new instance.
198 * @param newMaxCheck maximum checking interval (s)
199 * @param newThreshold convergence threshold (s)
200 * @param newMaxIter maximum number of iterations in the event time search
201 * @param newHandler event handler to call at event occurrences
202 * @return a new instance of the appropriate sub-type
203 */
204 protected abstract T create(AdaptableInterval newMaxCheck, double newThreshold,
205 int newMaxIter, EventHandler newHandler);
206
207 /** Check if the current propagation is forward or backward.
208 * @return true if the current propagation is forward
209 * @since 7.2
210 */
211 public boolean isForward() {
212 return forward;
213 }
214
215 }