1 /* Copyright 2002-2025 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.hipparchus.CalculusFieldElement;
20 import org.orekit.errors.OrekitException;
21 import org.orekit.errors.OrekitMessages;
22 import org.orekit.propagation.FieldSpacecraftState;
23 import org.orekit.propagation.events.handlers.FieldEventHandler;
24 import org.orekit.propagation.events.intervals.FieldAdaptableInterval;
25 import org.orekit.time.FieldAbsoluteDate;
26
27 /** Common parts shared by several orbital events finders.
28 * @param <D> type of the detector
29 * @param <T> type of the field element
30 * @see org.orekit.propagation.Propagator#addEventDetector(EventDetector)
31 * @author Luc Maisonobe
32 */
33 public abstract class FieldAbstractDetector<D extends FieldAbstractDetector<D, T>, T extends CalculusFieldElement<T>>
34 implements FieldEventDetector<T> {
35
36 /** Default maximum checking interval (s). */
37 public static final double DEFAULT_MAX_CHECK = FieldEventDetectionSettings.DEFAULT_MAX_CHECK;
38
39 /** Default convergence threshold (s). */
40 public static final double DEFAULT_THRESHOLD = FieldEventDetectionSettings.DEFAULT_THRESHOLD;
41
42 /** Default maximum number of iterations in the event time search. */
43 public static final int DEFAULT_MAX_ITER = FieldEventDetectionSettings.DEFAULT_MAX_ITER;
44
45 /** Detection settings. */
46 private final FieldEventDetectionSettings<T> eventDetectionSettings;
47
48 /** Default handler for event overrides. */
49 private final FieldEventHandler<T> handler;
50
51 /** Propagation direction. */
52 private boolean forward;
53
54 /** Build a new instance.
55 * @param detectionSettings event detection settings
56 * @param handler event handler to call at event occurrences
57 * @since 12.2
58 */
59 protected FieldAbstractDetector(final FieldEventDetectionSettings<T> detectionSettings,
60 final FieldEventHandler<T> handler) {
61 checkStrictlyPositive(detectionSettings.getThreshold().getReal());
62 this.eventDetectionSettings = detectionSettings;
63 this.handler = handler;
64 this.forward = true;
65 }
66
67 /**
68 * Check if propagation is forward or not.
69 * @param <W> field type
70 * @param state initial state
71 * @param targetDate target propagation date
72 * @return forward flag
73 * @since 13.0
74 */
75 public static <W extends CalculusFieldElement<W>> boolean checkIfForward(final FieldSpacecraftState<W> state,
76 final FieldAbsoluteDate<W> targetDate) {
77 return targetDate.durationFrom(state.getDate()).getReal() >= 0.0;
78 }
79
80 /** Check value is strictly positive.
81 * @param value value to check
82 * @exception OrekitException if value is not strictly positive
83 * @since 11.2
84 */
85 private void checkStrictlyPositive(final double value) throws OrekitException {
86 if (value <= 0.0) {
87 throw new OrekitException(OrekitMessages.NOT_STRICTLY_POSITIVE, value);
88 }
89 }
90
91 /** {@inheritDoc} */
92 @Override
93 public void init(final FieldSpacecraftState<T> s0, final FieldAbsoluteDate<T> t) {
94 FieldEventDetector.super.init(s0, t);
95 forward = checkIfForward(s0, t);
96 }
97
98 /** {@inheritDoc} */
99 @Override
100 public FieldEventDetectionSettings<T> getDetectionSettings() {
101 return eventDetectionSettings;
102 }
103
104 /**
105 * Set up 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 * @since 12.0
112 */
113 public D withMaxCheck(final double newMaxCheck) {
114 return withMaxCheck(FieldAdaptableInterval.of(newMaxCheck));
115 }
116
117 /**
118 * Set up the maximum checking interval.
119 * <p>
120 * This will override a maximum checking interval if it has been configured previously.
121 * </p>
122 * @param newMaxCheck maximum checking interval (s)
123 * @return a new detector with updated configuration (the instance is not changed)
124 * @since 12.0
125 */
126 public D withMaxCheck(final FieldAdaptableInterval<T> newMaxCheck) {
127 return withDetectionSettings(new FieldEventDetectionSettings<>(newMaxCheck, getThreshold(), getMaxIterationCount()));
128 }
129
130 /**
131 * Set up the maximum number of iterations in the event time search.
132 * <p>
133 * This will override a number of iterations if it has been configured previously.
134 * </p>
135 * @param newMaxIter maximum number of iterations in the event time search
136 * @return a new detector with updated configuration (the instance is not changed)
137 * @since 6.1
138 */
139 public D withMaxIter(final int newMaxIter) {
140 return withDetectionSettings(new FieldEventDetectionSettings<>(getMaxCheckInterval(), getThreshold(), newMaxIter));
141 }
142
143 /**
144 * Set up the convergence threshold.
145 * <p>
146 * This will override a convergence threshold if it has been configured previously.
147 * </p>
148 * @param newThreshold convergence threshold (s)
149 * @return a new detector with updated configuration (the instance is not changed)
150 * @since 6.1
151 */
152 public D withThreshold(final T newThreshold) {
153 return withDetectionSettings(new FieldEventDetectionSettings<>(getMaxCheckInterval(), newThreshold, getMaxIterationCount()));
154 }
155
156 /**
157 * Set up the event detection settings.
158 * <p>
159 * This will override settings previously configured.
160 * </p>
161 * @param newSettings new event detection settings
162 * @return a new detector with updated configuration (the instance is not changed)
163 * @since 12.2
164 */
165 public D withDetectionSettings(final FieldEventDetectionSettings<T> newSettings) {
166 return create(newSettings, getHandler());
167 }
168
169 /**
170 * Set up 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 * @since 6.1
177 */
178 public D withHandler(final FieldEventHandler<T> newHandler) {
179 return create(getDetectionSettings(), newHandler);
180 }
181
182 /** {@inheritDoc} */
183 public FieldEventHandler<T> getHandler() {
184 return handler;
185 }
186
187 /** Build a new instance.
188 * @param detectionSettings detection settings
189 * @param newHandler event handler to call at event occurrences
190 * @return a new instance of the appropriate sub-type
191 * @since 12.2
192 */
193 protected abstract D create(FieldEventDetectionSettings<T> detectionSettings, FieldEventHandler<T> newHandler);
194
195 /** Check if the current propagation is forward or backward.
196 * @return true if the current propagation is forward
197 * @since 7.2
198 */
199 public boolean isForward() {
200 return forward;
201 }
202
203 }