1   /* Copyright 2002-2021 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;
18  
19  import java.util.Collection;
20  import java.util.List;
21  
22  import org.hipparchus.CalculusFieldElement;
23  import org.orekit.attitudes.AttitudeProvider;
24  import org.orekit.frames.Frame;
25  import org.orekit.propagation.events.FieldEventDetector;
26  import org.orekit.propagation.sampling.FieldOrekitFixedStepHandler;
27  import org.orekit.propagation.sampling.FieldOrekitStepHandler;
28  import org.orekit.propagation.sampling.FieldStepHandlerMultiplexer;
29  import org.orekit.time.FieldAbsoluteDate;
30  import org.orekit.utils.FieldPVCoordinatesProvider;
31  
32  /** This interface provides a way to propagate an orbit at any time.
33   *
34   * <p>This interface is the top-level abstraction for orbit propagation.
35   * It only allows propagation to a predefined date.
36   * It is implemented by analytical models which have no time limit,
37   * by orbit readers based on external data files, by numerical integrators
38   * using rich force models and by continuous models built after numerical
39   * integration has been completed and dense output data as been
40   * gathered.</p>
41   * @param <T> the type of the field elements
42  
43   * @author Luc Maisonobe
44   * @author V&eacute;ronique Pommier-Maurussane
45   *
46   */
47  
48  public interface FieldPropagator<T extends CalculusFieldElement<T>> extends FieldPVCoordinatesProvider<T> {
49  
50      /** Default mass. */
51      double DEFAULT_MASS = 1000.0;
52  
53      /** Get the multiplexer holding all step handlers.
54       * @return multiplexer holding all step handlers
55       * @since 11.0
56       */
57      FieldStepHandlerMultiplexer<T> getMultiplexer();
58  
59      /** Remove all step handlers.
60       * <p>This convenience method is equivalent to call {@code getMultiplexer().clear()}</p>
61       * @see #getMultiplexer()
62       * @see FieldStepHandlerMultiplexer#clear()
63       * @since 11.0
64       */
65      default void clearStepHandlers() {
66          getMultiplexer().clear();
67      }
68  
69      /** Set a single handler for fixed stepsizes.
70       * <p>This convenience method is equivalent to call {@code getMultiplexer().clear()}
71       * followed by {@code getMultiplexer().add(h, handler)}</p>
72       * @param h fixed stepsize (s)
73       * @param handler handler called at the end of each finalized step
74       * @see #getMultiplexer()
75       * @see FieldStepHandlerMultiplexer#add(CalculusFieldElement, FieldOrekitFixedStepHandler)
76       * @since 11.0
77       */
78      default void setStepHandler(final T h, final FieldOrekitFixedStepHandler<T> handler) {
79          getMultiplexer().clear();
80          getMultiplexer().add(h, handler);
81      }
82  
83      /** Set a single handler for variable stepsizes.
84       * <p>This convenience method is equivalent to call {@code getMultiplexer().clear()}
85       * followed by {@code getMultiplexer().add(handler)}</p>
86       * @param handler handler called at the end of each finalized step
87       * @see #getMultiplexer()
88       * @see FieldStepHandlerMultiplexer#add(FieldOrekitStepHandler)
89       * @since 11.0
90       */
91      default void setStepHandler(final FieldOrekitStepHandler<T> handler) {
92          getMultiplexer().clear();
93          getMultiplexer().add(handler);
94      }
95  
96      /**
97       * Set up an ephemeris generator that will monitor the propagation for building
98       * an ephemeris from it once completed.
99       *
100      * <p>
101      * This generator can be used when the user needs fast random access to the orbit
102      * state at any time between the initial and target times. A typical example is the
103      * implementation of search and iterative algorithms that may navigate forward and
104      * backward inside the propagation range before finding their result even if the
105      * propagator used is integration-based and only goes from one initial time to one
106      * target time.
107      * </p>
108      * <p>
109      * Beware that when used with integration-based propagators, the generator will
110      * store <strong>all</strong> intermediate results. It is therefore memory intensive
111      * for long integration-based ranges and high precision/short time steps. When
112      * used with analytical propagators, the generator only stores start/stop time
113      * and a reference to the analytical propagator itself to call it back as needed,
114      * so it is less memory intensive.
115      * </p>
116      * <p>
117      * The returned ephemeris generator will be initially empty, it will be filled
118      * with propagation data when a subsequent call to either {@link #propagate(FieldAbsoluteDate)
119      * propagate(target)} or {@link #propagate(FieldAbsoluteDate, FieldAbsoluteDate)
120      * propagate(start, target)} is called. The proper way to use this method is
121      * therefore to do:
122      * </p>
123      * <pre>
124      *   FieldEphemerisGenerator&lt;T&gt; generator = propagator.getEphemerisGenerator();
125      *   propagator.propagate(target);
126      *   FieldBoundedPropagator&lt;T&gt; ephemeris = generator.getGeneratedEphemeris();
127      * </pre>
128      * @return ephemeris generator
129      */
130     FieldEphemerisGenerator<T> getEphemerisGenerator();
131 
132     /** Get the propagator initial state.
133      * @return initial state
134      */
135     FieldSpacecraftState<T> getInitialState();
136 
137     /** Reset the propagator initial state.
138      * @param state new initial state to consider
139      */
140     void resetInitialState(FieldSpacecraftState<T> state);
141 
142     /** Add a set of user-specified state parameters to be computed along with the orbit propagation.
143      * @param additionalStateProvider provider for additional state
144      */
145     void addAdditionalStateProvider(FieldAdditionalStateProvider<T> additionalStateProvider);
146 
147     /** Get an unmodifiable list of providers for additional state.
148      * @return providers for the additional states
149      */
150     List<FieldAdditionalStateProvider<T>> getAdditionalStateProviders();
151 
152     /** Check if an additional state is managed.
153      * <p>
154      * Managed states are states for which the propagators know how to compute
155      * its evolution. They correspond to additional states for which an
156      * {@link FieldAdditionalStateProvider additional state provider} has been registered
157      * by calling the {@link #addAdditionalStateProvider(FieldAdditionalStateProvider)
158      * addAdditionalStateProvider} method. If the propagator is an {@link
159      * org.orekit.propagation.integration.FieldAbstractIntegratedPropagator integrator-based
160      * propagator}, the states for which a set of {@link
161      * org.orekit.propagation.integration.FieldAdditionalEquations additional equations} has
162      * been registered by calling the {@link
163      * org.orekit.propagation.integration.FieldAbstractIntegratedPropagator#addAdditionalEquations(
164      * org.orekit.propagation.integration.FieldAdditionalEquations) addAdditionalEquations}
165      * method are also counted as managed additional states.
166      * </p>
167      * <p>
168      * Additional states that are present in the {@link #getInitialState() initial state}
169      * but have no evolution method registered are <em>not</em> considered as managed states.
170      * These unmanaged additional states are not lost during propagation, though. Their
171      * value are piecewise constant between state resets that may change them if some
172      * event handler {@link
173      * org.orekit.propagation.events.handlers.FieldEventHandler#resetState(FieldEventDetector,
174      * FieldSpacecraftState) resetState} method is called at an event occurrence and happens
175      * to change the unmanaged additional state.
176      * </p>
177      * @param name name of the additional state
178      * @return true if the additional state is managed
179      */
180     boolean isAdditionalStateManaged(String name);
181 
182     /** Get all the names of all managed states.
183      * @return names of all managed states
184      */
185     String[] getManagedAdditionalStates();
186 
187     /** Add an event detector.
188      * @param detector event detector to add
189      * @see #clearEventsDetectors()
190      * @see #getEventsDetectors()
191      * @param <D> class type for the generic version
192      */
193     <D extends FieldEventDetector<T>> void addEventDetector(D detector);
194 
195     /** Get all the events detectors that have been added.
196      * @return an unmodifiable collection of the added detectors
197      * @see #addEventDetector(FieldEventDetector)
198      * @see #clearEventsDetectors()
199      */
200     Collection<FieldEventDetector<T>> getEventsDetectors();
201 
202     /** Remove all events detectors.
203      * @see #addEventDetector(FieldEventDetector)
204      * @see #getEventsDetectors()
205      */
206     void clearEventsDetectors();
207 
208     /** Get attitude provider.
209      * @return attitude provider
210      */
211     AttitudeProvider getAttitudeProvider();
212 
213     /** Set attitude provider.
214      * @param attitudeProvider attitude provider
215      */
216     void setAttitudeProvider(AttitudeProvider attitudeProvider);
217 
218     /** Get the frame in which the orbit is propagated.
219      * <p>
220      * The propagation frame is the definition frame of the initial
221      * state, so this method should be called after this state has
222      * been set, otherwise it may return null.
223      * </p>
224      * @return frame in which the orbit is propagated
225      * @see #resetInitialState(FieldSpacecraftState)
226      */
227     Frame getFrame();
228 
229     /** Propagate towards a target date.
230      * <p>Simple propagators use only the target date as the specification for
231      * computing the propagated state. More feature rich propagators can consider
232      * other information and provide different operating modes or G-stop
233      * facilities to stop at pinpointed events occurrences. In these cases, the
234      * target date is only a hint, not a mandatory objective.</p>
235      * @param target target date towards which orbit state should be propagated
236      * @return propagated state
237      */
238     FieldSpacecraftState<T> propagate(FieldAbsoluteDate<T> target);
239 
240     /** Propagate from a start date towards a target date.
241      * <p>Those propagators use a start date and a target date to
242      * compute the propagated state. For propagators using event detection mechanism,
243      * if the provided start date is different from the initial state date, a first,
244      * simple propagation is performed, without processing any event computation.
245      * Then complete propagation is performed from start date to target date.</p>
246      * @param start start date from which orbit state should be propagated
247      * @param target target date to which orbit state should be propagated
248      * @return propagated state
249      */
250     FieldSpacecraftState<T> propagate(FieldAbsoluteDate<T> start, FieldAbsoluteDate<T> target);
251 
252 }