FieldIntegratedEphemeris.java

  1. /* Copyright 2002-2018 CS Systèmes d'Information
  2.  * Licensed to CS Systèmes d'Information (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.integration;

  18. import java.util.List;
  19. import java.util.Map;
  20. import org.hipparchus.RealFieldElement;
  21. import org.hipparchus.ode.FieldDenseOutputModel;
  22. import org.hipparchus.ode.FieldODEStateAndDerivative;
  23. import org.orekit.errors.OrekitException;
  24. import org.orekit.errors.OrekitExceptionWrapper;
  25. import org.orekit.errors.OrekitMessages;
  26. import org.orekit.frames.Frame;
  27. import org.orekit.orbits.FieldOrbit;
  28. import org.orekit.propagation.FieldAdditionalStateProvider;
  29. import org.orekit.propagation.FieldBoundedPropagator;
  30. import org.orekit.propagation.FieldSpacecraftState;
  31. import org.orekit.propagation.analytical.FieldAbstractAnalyticalPropagator;
  32. import org.orekit.time.FieldAbsoluteDate;
  33. import org.orekit.utils.TimeStampedFieldPVCoordinates;

  34. /** This class stores sequentially generated orbital parameters for
  35.  * later retrieval.
  36.  *
  37.  * <p>
  38.  * Instances of this class are built and then must be fed with the results
  39.  * provided by {@link org.orekit.propagation.Propagator Propagator} objects
  40.  * configured in {@link org.orekit.propagation.Propagator#setEphemerisMode()
  41.  * ephemeris generation mode}. Once propagation is o, random access to any
  42.  * intermediate state of the orbit throughout the propagation range is possible.
  43.  * </p>
  44.  * <p>
  45.  * A typical use case is for numerically integrated orbits, which can be used by
  46.  * algorithms that need to wander around according to their own algorithm without
  47.  * cumbersome tight links with the integrator.
  48.  * </p>
  49.  * <p>
  50.  * Another use case is persistence, as this class is one of the few propagators
  51.  * to be serializable.
  52.  * </p>
  53.  * <p>
  54.  * As this class implements the {@link org.orekit.propagation.Propagator Propagator}
  55.  * interface, it can itself be used in batch mode to build another instance of the
  56.  * same type. This is however not recommended since it would be a waste of resources.
  57.  * </p>
  58.  * <p>
  59.  * Note that this class stores all intermediate states along with interpolation
  60.  * models, so it may be memory intensive.
  61.  * </p>
  62.  *
  63.  * @see org.orekit.propagation.numerical.NumericalPropagator
  64.  * @author Mathieu Rom&eacute;ro
  65.  * @author Luc Maisonobe
  66.  * @author V&eacute;ronique Pommier-Maurussane
  67.  */
  68. public class FieldIntegratedEphemeris <T extends RealFieldElement<T>>
  69.     extends FieldAbstractAnalyticalPropagator<T> implements FieldBoundedPropagator<T> {

  70.     /** Event detection requires evaluating the state slightly before / past an event. */
  71.     private static final double EXTRAPOLATION_TOLERANCE = 1.0;

  72.     /** Mapper between raw double components and spacecraft state. */
  73.     private final FieldStateMapper<T> mapper;

  74.     /** Output only the mean orbit. <br/>
  75.      * <p>
  76.      * This is used only in the case of semianalitical propagators where there is a clear separation between
  77.      * mean and short periodic elements. It is ignored by the Numerical propagator.
  78.      * </p>
  79.      */
  80.     private boolean meanFieldOrbit;

  81.     /** Start date of the integration (can be min or max). */
  82.     private final FieldAbsoluteDate<T> startDate;

  83.     /** First date of the range. */
  84.     private final FieldAbsoluteDate<T> minDate;

  85.     /** Last date of the range. */
  86.     private final FieldAbsoluteDate<T> maxDate;

  87.     /** Underlying raw mathematical model. */
  88.     private FieldDenseOutputModel<T> model;

  89.     /** Unmanaged additional states that must be simply copied. */
  90.     private final Map<String, T[]> unmanaged;

  91.     /** Creates a new instance of IntegratedEphemeris.
  92.      * @param startDate Start date of the integration (can be minDate or maxDate)
  93.      * @param minDate first date of the range
  94.      * @param maxDate last date of the range
  95.      * @param mapper mapper between raw double components and spacecraft state
  96.      * @param meanFieldOrbit output only the mean orbit
  97.      * @param model underlying raw mathematical model
  98.      * @param unmanaged unmanaged additional states that must be simply copied
  99.      * @param providers providers for pre-integrated states
  100.      * @param equations names of additional equations
  101.      * @exception OrekitException if several providers have the same name
  102.      */
  103.     public FieldIntegratedEphemeris(final FieldAbsoluteDate<T> startDate,
  104.                                final FieldAbsoluteDate<T> minDate, final FieldAbsoluteDate<T> maxDate,
  105.                                final FieldStateMapper<T> mapper, final boolean meanFieldOrbit,
  106.                                final FieldDenseOutputModel<T> model,
  107.                                final Map<String, T[]> unmanaged,
  108.                                final List<FieldAdditionalStateProvider<T>> providers,
  109.                                final String[] equations)
  110.         throws OrekitException {

  111.         super(startDate.getField(), mapper.getAttitudeProvider());

  112.         this.startDate = startDate;
  113.         this.minDate   = minDate;
  114.         this.maxDate   = maxDate;
  115.         this.mapper    = mapper;
  116.         this.meanFieldOrbit = meanFieldOrbit;
  117.         this.model     = model;
  118.         this.unmanaged = unmanaged;
  119.         // set up the pre-integrated providers
  120.         for (final FieldAdditionalStateProvider<T> provider : providers) {
  121.             addAdditionalStateProvider(provider);
  122.         }

  123.         // set up providers to map the final elements of the model array to additional states
  124.         for (int i = 0; i < equations.length; ++i) {
  125.             addAdditionalStateProvider(new LocalProvider(equations[i], i));
  126.         }

  127.     }

  128.     /** Interpolate the model at some date.
  129.      * @param date desired interpolation date
  130.      * @return state interpolated at date
  131.      * @exception OrekitException if specified date is outside
  132.      * of supported range
  133.      */
  134.     private FieldODEStateAndDerivative<T> getInterpolatedState(final FieldAbsoluteDate<T> date)
  135.         throws OrekitException {

  136.         // compare using double precision instead of FieldAbsoluteDate<T>.compareTo(...)
  137.         // because time is expressed as a double when searching for events
  138.         if (date.compareTo(minDate.shiftedBy(-EXTRAPOLATION_TOLERANCE)) < 0 ||
  139.                 date.compareTo(maxDate.shiftedBy(EXTRAPOLATION_TOLERANCE)) > 0 ) {
  140.             // date is outside of supported range
  141.             throw new OrekitException(OrekitMessages.OUT_OF_RANGE_EPHEMERIDES_DATE,
  142.                                            date, minDate, maxDate);
  143.         }

  144.         return model.getInterpolatedState(date.durationFrom(startDate));

  145.     }

  146.     /** {@inheritDoc} */
  147.     @Override
  148.     protected FieldSpacecraftState<T> basicPropagate(final FieldAbsoluteDate<T> date)
  149.         throws OrekitException {
  150.         try {
  151.             final FieldODEStateAndDerivative<T> os = getInterpolatedState(date);
  152.             FieldSpacecraftState<T> state = mapper.mapArrayToState(mapper.mapDoubleToDate(os.getTime(), date),
  153.                                                                    os.getPrimaryState(), os.getPrimaryDerivative(),
  154.                                                                    meanFieldOrbit);
  155.             for (Map.Entry<String, T[]> initial : unmanaged.entrySet()) {
  156.                 state = state.addAdditionalState(initial.getKey(), initial.getValue());
  157.             }
  158.             return state;
  159.         } catch (OrekitExceptionWrapper oew) {
  160.             throw new OrekitException(oew.getException());
  161.         }
  162.     }

  163.     /** {@inheritDoc} */
  164.     protected FieldOrbit<T> propagateOrbit(final FieldAbsoluteDate<T> date)
  165.         throws OrekitException {
  166.         return basicPropagate(date).getOrbit();
  167.     }

  168.     /** {@inheritDoc} */
  169.     protected T getMass(final FieldAbsoluteDate<T> date) throws OrekitException {
  170.         return basicPropagate(date).getMass();
  171.     }

  172.     /** {@inheritDoc} */
  173.     public TimeStampedFieldPVCoordinates<T> getPVCoordinates(final FieldAbsoluteDate<T> date, final Frame frame)
  174.         throws OrekitException {
  175.         return propagate(date).getPVCoordinates(frame);
  176.     }

  177.     /** Get the first date of the range.
  178.      * @return the first date of the range
  179.      */
  180.     public FieldAbsoluteDate<T> getMinDate() {
  181.         return minDate;
  182.     }

  183.     /** Get the last date of the range.
  184.      * @return the last date of the range
  185.      */
  186.     public FieldAbsoluteDate<T> getMaxDate() {
  187.         return maxDate;
  188.     }

  189.     @Override
  190.     public Frame getFrame() {
  191.         return this.mapper.getFrame();
  192.     }

  193.     /** {@inheritDoc} */
  194.     public void resetInitialState(final FieldSpacecraftState<T> state)
  195.         throws OrekitException {
  196.         throw new OrekitException(OrekitMessages.NON_RESETABLE_STATE);
  197.     }

  198.     /** {@inheritDoc} */
  199.     protected void resetIntermediateState(final FieldSpacecraftState<T> state, final boolean forward)
  200.         throws OrekitException {
  201.         throw new OrekitException(OrekitMessages.NON_RESETABLE_STATE);
  202.     }

  203.     /** {@inheritDoc} */
  204.     public FieldSpacecraftState<T> getInitialState() throws OrekitException {
  205.         return updateAdditionalStates(basicPropagate(getMinDate()));
  206.     }

  207.     /** Local provider for additional state data. */
  208.     private class LocalProvider implements FieldAdditionalStateProvider<T> {

  209.         /** Name of the additional state. */
  210.         private final String name;

  211.         /** Index of the additional state. */
  212.         private final int index;

  213.         /** Simple constructor.
  214.          * @param name name of the additional state
  215.          * @param index index of the additional state
  216.          */
  217.         LocalProvider(final String name, final int index) {
  218.             this.name  = name;
  219.             this.index = index;
  220.         }

  221.         /** {@inheritDoc} */
  222.         public String getName() {
  223.             return name;
  224.         }

  225.         /** {@inheritDoc} */
  226.         public T[] getAdditionalState(final FieldSpacecraftState<T> state)
  227.             throws OrekitException {

  228.             // extract the part of the interpolated array corresponding to the additional state
  229.             return getInterpolatedState(state.getDate()).getSecondaryState(index + 1);

  230.         }

  231.     }

  232. }