Propagator.java

  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;

  18. import java.util.Collection;
  19. import java.util.List;

  20. import org.hipparchus.geometry.euclidean.threed.Rotation;
  21. import org.hipparchus.geometry.euclidean.threed.Vector3D;
  22. import org.hipparchus.linear.RealMatrix;
  23. import org.orekit.attitudes.AttitudeProvider;
  24. import org.orekit.attitudes.FrameAlignedProvider;
  25. import org.orekit.frames.Frame;
  26. import org.orekit.frames.Frames;
  27. import org.orekit.orbits.PositionAngleType;
  28. import org.orekit.propagation.events.EventDetector;
  29. import org.orekit.propagation.sampling.OrekitFixedStepHandler;
  30. import org.orekit.propagation.sampling.OrekitStepHandler;
  31. import org.orekit.propagation.sampling.StepHandlerMultiplexer;
  32. import org.orekit.time.AbsoluteDate;
  33. import org.orekit.utils.DoubleArrayDictionary;
  34. import org.orekit.utils.PVCoordinatesProvider;
  35. import org.orekit.utils.TimeStampedPVCoordinates;

  36. /** This interface provides a way to propagate an orbit at any time.
  37.  *
  38.  * <p>This interface is the top-level abstraction for orbit propagation.
  39.  * It only allows propagation to a predefined date.
  40.  * It is implemented by analytical models which have no time limit,
  41.  * by orbit readers based on external data files, by numerical integrators
  42.  * using rich force models and by continuous models built after numerical
  43.  * integration has been completed and dense output data as been
  44.  * gathered.</p>
  45.  * <p>Note that one single propagator cannot be called from multiple threads.
  46.  * Its configuration can be changed as there is at least a {@link
  47.  * #resetInitialState(SpacecraftState)} method, and even propagators that do
  48.  * not support resetting state (like the {@link
  49.  * org.orekit.propagation.analytical.tle.TLEPropagator TLEPropagator} do
  50.  * cache some internal data during computation. However, as long as they
  51.  * are configured with independent building blocks (mainly event handlers
  52.  * and step handlers that may preserve some internal state), and as long
  53.  * as they are called from one thread only, they <em>can</em> be used in
  54.  * multi-threaded applications. Synchronizing several propagators to run in
  55.  * parallel is also possible using {@link PropagatorsParallelizer}.</p>
  56.  * @author Luc Maisonobe
  57.  * @author V&eacute;ronique Pommier-Maurussane
  58.  *
  59.  */

  60. public interface Propagator extends PVCoordinatesProvider {

  61.     /** Default mass. */
  62.     double DEFAULT_MASS = 1000.0;

  63.     /**
  64.      * Get a default law using the given frames.
  65.      *
  66.      * @param frames the set of frames to use.
  67.      * @return attitude law.
  68.      */
  69.     static AttitudeProvider getDefaultLaw(final Frames frames) {
  70.         return new FrameAlignedProvider(Rotation.IDENTITY, frames.getEME2000());
  71.     }

  72.     /** Get the multiplexer holding all step handlers.
  73.      * @return multiplexer holding all step handlers
  74.      * @since 11.0
  75.      */
  76.     StepHandlerMultiplexer getMultiplexer();

  77.     /** Remove all step handlers.
  78.      * <p>This convenience method is equivalent to call {@code getMultiplexer().clear()}</p>
  79.      * @see #getMultiplexer()
  80.      * @see StepHandlerMultiplexer#clear()
  81.      * @since 11.0
  82.      */
  83.     default void clearStepHandlers() {
  84.         getMultiplexer().clear();
  85.     }

  86.     /** Set a single handler for fixed stepsizes.
  87.      * <p>This convenience method is equivalent to call {@code getMultiplexer().clear()}
  88.      * followed by {@code getMultiplexer().add(h, handler)}</p>
  89.      * @param h fixed stepsize (s)
  90.      * @param handler handler called at the end of each finalized step
  91.      * @see #getMultiplexer()
  92.      * @see StepHandlerMultiplexer#add(double, OrekitFixedStepHandler)
  93.      * @since 11.0
  94.      */
  95.     default void setStepHandler(final double h, final OrekitFixedStepHandler handler) {
  96.         getMultiplexer().clear();
  97.         getMultiplexer().add(h, handler);
  98.     }

  99.     /** Set a single handler for variable stepsizes.
  100.      * <p>This convenience method is equivalent to call {@code getMultiplexer().clear()}
  101.      * followed by {@code getMultiplexer().add(handler)}</p>
  102.      * @param handler handler called at the end of each finalized step
  103.      * @see #getMultiplexer()
  104.      * @see StepHandlerMultiplexer#add(OrekitStepHandler)
  105.      * @since 11.0
  106.      */
  107.     default void setStepHandler(final OrekitStepHandler handler) {
  108.         getMultiplexer().clear();
  109.         getMultiplexer().add(handler);
  110.     }

  111.     /**
  112.      * Set up an ephemeris generator that will monitor the propagation for building
  113.      * an ephemeris from it once completed.
  114.      *
  115.      * <p>
  116.      * This generator can be used when the user needs fast random access to the orbit
  117.      * state at any time between the initial and target times. A typical example is the
  118.      * implementation of search and iterative algorithms that may navigate forward and
  119.      * backward inside the propagation range before finding their result even if the
  120.      * propagator used is integration-based and only goes from one initial time to one
  121.      * target time.
  122.      * </p>
  123.      * <p>
  124.      * Beware that when used with integration-based propagators, the generator will
  125.      * store <strong>all</strong> intermediate results. It is therefore memory intensive
  126.      * for long integration-based ranges and high precision/short time steps. When
  127.      * used with analytical propagators, the generator only stores start/stop time
  128.      * and a reference to the analytical propagator itself to call it back as needed,
  129.      * so it is less memory intensive.
  130.      * </p>
  131.      * <p>
  132.      * The returned ephemeris generator will be initially empty, it will be filled
  133.      * with propagation data when a subsequent call to either {@link #propagate(AbsoluteDate)
  134.      * propagate(target)} or {@link #propagate(AbsoluteDate, AbsoluteDate)
  135.      * propagate(start, target)} is called. The proper way to use this method is
  136.      * therefore to do:
  137.      * </p>
  138.      * <pre>
  139.      *   EphemerisGenerator generator = propagator.getEphemerisGenerator();
  140.      *   propagator.propagate(target);
  141.      *   BoundedPropagator ephemeris = generator.getGeneratedEphemeris();
  142.      * </pre>
  143.      * @return ephemeris generator
  144.      */
  145.     EphemerisGenerator getEphemerisGenerator();

  146.     /** Get the propagator initial state.
  147.      * @return initial state
  148.      */
  149.     SpacecraftState getInitialState();

  150.     /** Reset the propagator initial state.
  151.      * @param state new initial state to consider
  152.      */
  153.     void resetInitialState(SpacecraftState state);

  154.     /** Add a set of user-specified state parameters to be computed along with the orbit propagation.
  155.      * @param additionalStateProvider provider for additional state
  156.      */
  157.     void addAdditionalStateProvider(AdditionalStateProvider additionalStateProvider);

  158.     /** Get an unmodifiable list of providers for additional state.
  159.      * @return providers for the additional states
  160.      */
  161.     List<AdditionalStateProvider> getAdditionalStateProviders();

  162.     /** Check if an additional state is managed.
  163.      * <p>
  164.      * Managed states are states for which the propagators know how to compute
  165.      * its evolution. They correspond to additional states for which a
  166.      * {@link AdditionalStateProvider provider} has been registered by calling the
  167.      * {@link #addAdditionalStateProvider(AdditionalStateProvider) addAdditionalStateProvider} method.
  168.      * </p>
  169.      * <p>
  170.      * Additional states that are present in the {@link #getInitialState() initial state}
  171.      * but have no evolution method registered are <em>not</em> considered as managed states.
  172.      * These unmanaged additional states are not lost during propagation, though. Their
  173.      * value are piecewise constant between state resets that may change them if some
  174.      * event handler {@link
  175.      * org.orekit.propagation.events.handlers.EventHandler#resetState(EventDetector,
  176.      * SpacecraftState) resetState} method is called at an event occurrence and happens
  177.      * to change the unmanaged additional state.
  178.      * </p>
  179.      * @param name name of the additional state
  180.      * @return true if the additional state is managed
  181.      */
  182.     boolean isAdditionalStateManaged(String name);

  183.     /** Get all the names of all managed states.
  184.      * @return names of all managed states
  185.      */
  186.     String[] getManagedAdditionalStates();

  187.     /** Add an event detector.
  188.      * @param detector event detector to add
  189.      * @see #clearEventsDetectors()
  190.      * @see #getEventsDetectors()
  191.      * @param <T> class type for the generic version
  192.      */
  193.     <T extends EventDetector> void addEventDetector(T detector);

  194.     /** Get all the events detectors that have been added.
  195.      * @return an unmodifiable collection of the added detectors
  196.      * @see #addEventDetector(EventDetector)
  197.      * @see #clearEventsDetectors()
  198.      */
  199.     Collection<EventDetector> getEventsDetectors();

  200.     /** Remove all events detectors.
  201.      * @see #addEventDetector(EventDetector)
  202.      * @see #getEventsDetectors()
  203.      */
  204.     void clearEventsDetectors();

  205.     /** Get attitude provider.
  206.      * @return attitude provider
  207.      */
  208.     AttitudeProvider getAttitudeProvider();

  209.     /** Set attitude provider.
  210.      * @param attitudeProvider attitude provider
  211.      */
  212.     void setAttitudeProvider(AttitudeProvider attitudeProvider);

  213.     /** Get the frame in which the orbit is propagated.
  214.      * <p>
  215.      * The propagation frame is the definition frame of the initial
  216.      * state, so this method should be called after this state has
  217.      * been set, otherwise it may return null.
  218.      * </p>
  219.      * @return frame in which the orbit is propagated
  220.      * @see #resetInitialState(SpacecraftState)
  221.      */
  222.     Frame getFrame();

  223.     /** Set up computation of State Transition Matrix and Jacobians matrix with respect to parameters.
  224.      * <p>
  225.      * If this method is called, both State Transition Matrix and Jacobians with respect to the
  226.      * force models parameters that will be selected when propagation starts will be automatically
  227.      * computed, and the harvester will allow to retrieve them.
  228.      * </p>
  229.      * <p>
  230.      * The arguments for initial matrices <em>must</em> be compatible with the {@link org.orekit.orbits.OrbitType
  231.      * orbit type} and {@link PositionAngleType position angle} that will be used by the propagator.
  232.      * </p>
  233.      * <p>
  234.      * The default implementation throws an exception as the method is not supported by all propagators.
  235.      * </p>
  236.      * @param stmName State Transition Matrix state name
  237.      * @param initialStm initial State Transition Matrix ∂Y/∂Y₀,
  238.      * if null (which is the most frequent case), assumed to be 6x6 identity
  239.      * @param initialJacobianColumns initial columns of the Jacobians matrix with respect to parameters,
  240.      * if null or if some selected parameters are missing from the dictionary, the corresponding
  241.      * initial column is assumed to be 0
  242.      * @return harvester to retrieve computed matrices during and after propagation
  243.      * @since 11.1
  244.      */
  245.     default MatricesHarvester setupMatricesComputation(final String stmName, final RealMatrix initialStm,
  246.                                                        final DoubleArrayDictionary initialJacobianColumns) {
  247.         throw new UnsupportedOperationException();
  248.     }

  249.     /** Propagate towards a target date.
  250.      * <p>Simple propagators use only the target date as the specification for
  251.      * computing the propagated state. More feature rich propagators can consider
  252.      * other information and provide different operating modes or G-stop
  253.      * facilities to stop at pinpointed events occurrences. In these cases, the
  254.      * target date is only a hint, not a mandatory objective.</p>
  255.      * @param target target date towards which orbit state should be propagated
  256.      * @return propagated state
  257.      */
  258.     SpacecraftState propagate(AbsoluteDate target);

  259.     /** Propagate from a start date towards a target date.
  260.      * <p>Those propagators use a start date and a target date to
  261.      * compute the propagated state. For propagators using event detection mechanism,
  262.      * if the provided start date is different from the initial state date, a first,
  263.      * simple propagation is performed, without processing any event computation.
  264.      * Then complete propagation is performed from start date to target date.</p>
  265.      * @param start start date from which orbit state should be propagated
  266.      * @param target target date to which orbit state should be propagated
  267.      * @return propagated state
  268.      */
  269.     SpacecraftState propagate(AbsoluteDate start, AbsoluteDate target);

  270.     /** {@inheritDoc} */
  271.     @Override
  272.     default TimeStampedPVCoordinates getPVCoordinates(AbsoluteDate date, Frame frame) {
  273.         return propagate(date).getPVCoordinates(frame);
  274.     }

  275.     /** {@inheritDoc} */
  276.     @Override
  277.     default Vector3D getPosition(AbsoluteDate date, Frame frame) {
  278.         return propagate(date).getPosition(frame);
  279.     }

  280. }