FieldAbstractPropagator.java

  1. /* Copyright 2002-2020 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.ArrayList;
  19. import java.util.Collection;
  20. import java.util.Collections;
  21. import java.util.HashMap;
  22. import java.util.List;
  23. import java.util.Map;

  24. import org.hipparchus.Field;
  25. import org.hipparchus.RealFieldElement;
  26. import org.orekit.attitudes.AttitudeProvider;
  27. import org.orekit.errors.OrekitException;
  28. import org.orekit.errors.OrekitMessages;
  29. import org.orekit.frames.Frame;
  30. import org.orekit.propagation.events.FieldEventDetector;
  31. import org.orekit.propagation.sampling.FieldOrekitFixedStepHandler;
  32. import org.orekit.propagation.sampling.FieldOrekitStepHandler;
  33. import org.orekit.propagation.sampling.FieldOrekitStepNormalizer;
  34. import org.orekit.time.AbsoluteDate;
  35. import org.orekit.time.FieldAbsoluteDate;
  36. import org.orekit.utils.TimeSpanMap;
  37. import org.orekit.utils.TimeStampedFieldPVCoordinates;

  38. /** Common handling of {@link Propagator} methods for analytical propagators.
  39.  * <p>
  40.  * This abstract class allows to provide easily the full set of {@link Propagator}
  41.  * methods, including all propagation modes support and discrete events support for
  42.  * any simple propagation method.
  43.  * </p>
  44.  * @author Luc Maisonobe
  45.  */
  46. public abstract class FieldAbstractPropagator<T extends RealFieldElement<T>> implements FieldPropagator<T> {

  47.     /** Propagation mode. */
  48.     private int mode;

  49.     /** Fixed step size. */
  50.     private T fixedStepSize;

  51.     /** Step handler. */
  52.     private FieldOrekitStepHandler<T> stepHandler;

  53.     /** Start date. */
  54.     private FieldAbsoluteDate<T> startDate;

  55.     /** Attitude provider. */
  56.     private AttitudeProvider attitudeProvider;

  57.     /** Additional state providers. */
  58.     private final List<FieldAdditionalStateProvider<T>> additionalStateProviders;

  59.     /** States managed by neither additional equations nor state providers. */
  60.     private final Map<String, TimeSpanMap<T[]>> unmanagedStates;

  61.     /** Field used.*/
  62.     private final Field<T> field;

  63.     /** Initial state. */
  64.     private FieldSpacecraftState<T> initialState;

  65.     /** Build a new instance.
  66.      * @param field setting the field
  67.      */
  68.     protected FieldAbstractPropagator(final Field<T> field) {
  69.         mode                     = SLAVE_MODE;
  70.         stepHandler              = null;
  71.         this.field               = field;
  72.         fixedStepSize            = field.getZero().add(Double.NaN);
  73.         additionalStateProviders = new ArrayList<>();
  74.         unmanagedStates          = new HashMap<>();
  75.     }

  76.     /** Set a start date.
  77.      * @param startDate start date
  78.      */
  79.     protected void setStartDate(final FieldAbsoluteDate<T> startDate) {
  80.         this.startDate = startDate;
  81.     }

  82.     /** Get the start date.
  83.      * @return start date
  84.      */
  85.     protected FieldAbsoluteDate<T> getStartDate() {
  86.         return startDate;
  87.     }

  88.     /**  {@inheritDoc} */
  89.     public AttitudeProvider getAttitudeProvider() {
  90.         return attitudeProvider;
  91.     }

  92.     /**  {@inheritDoc} */
  93.     public void setAttitudeProvider(final AttitudeProvider attitudeProvider) {
  94.         this.attitudeProvider = attitudeProvider;
  95.     }

  96.     /** Field getter.
  97.      * @return field used*/
  98.     public Field<T> getField() {
  99.         return field;
  100.     }

  101.     /** {@inheritDoc} */
  102.     public FieldSpacecraftState<T> getInitialState() {
  103.         return initialState;
  104.     }

  105.     /** {@inheritDoc} */
  106.     public int getMode() {
  107.         return mode;
  108.     }

  109.     /** {@inheritDoc} */
  110.     public Frame getFrame() {
  111.         return initialState.getFrame();
  112.     }

  113.     /** {@inheritDoc} */
  114.     public void resetInitialState(final FieldSpacecraftState<T> state) {
  115.         initialState = state;
  116.         setStartDate(state.getDate());
  117.     }

  118.     /** {@inheritDoc} */
  119.     public void setSlaveMode() {
  120.         mode          = SLAVE_MODE;
  121.         stepHandler   = null;
  122.         fixedStepSize = field.getZero().add(Double.NaN);
  123.     }

  124.     /** {@inheritDoc} */
  125.     public void setMasterMode(final T h,
  126.                               final FieldOrekitFixedStepHandler<T> handler) {
  127.         setMasterMode(new FieldOrekitStepNormalizer<>(h, handler));
  128.         fixedStepSize = h;
  129.     }

  130.     /** {@inheritDoc} */
  131.     public void setMasterMode(final FieldOrekitStepHandler<T> handler) {
  132.         mode          = MASTER_MODE;
  133.         stepHandler   = handler;
  134.         fixedStepSize = field.getZero().add(Double.NaN);
  135.     }

  136.     /** {@inheritDoc} */
  137.     public void setEphemerisMode() {
  138.         mode          = EPHEMERIS_GENERATION_MODE;
  139.         stepHandler   = null;
  140.         fixedStepSize = field.getZero().add(Double.NaN);
  141.     }

  142.     /** {@inheritDoc} */
  143.     public void addAdditionalStateProvider(final FieldAdditionalStateProvider<T> additionalStateProvider) {

  144.         // check if the name is already used
  145.         if (isAdditionalStateManaged(additionalStateProvider.getName())) {
  146.             // this additional state is already registered, complain
  147.             throw new OrekitException(OrekitMessages.ADDITIONAL_STATE_NAME_ALREADY_IN_USE,
  148.                                       additionalStateProvider.getName());
  149.         }

  150.         // this is really a new name, add it
  151.         additionalStateProviders.add(additionalStateProvider);

  152.     }

  153.     /** {@inheritDoc} */
  154.     public List<FieldAdditionalStateProvider<T>> getAdditionalStateProviders() {
  155.         return Collections.unmodifiableList(additionalStateProviders);
  156.     }

  157.     /** Update state by adding all additional states.
  158.      * @param original original state
  159.      * @return updated state, with all additional states included
  160.      * @see #addAdditionalStateProvider(FieldAdditionalStateProvider)
  161.      */
  162.     protected FieldSpacecraftState<T> updateAdditionalStates(final FieldSpacecraftState<T> original) {

  163.         // start with original state,
  164.         // which may already contain additional states, for example in interpolated ephemerides
  165.         FieldSpacecraftState<T> updated = original;

  166.         // update the states not managed by providers
  167.         for (final Map.Entry<String, TimeSpanMap<T[]>> entry : unmanagedStates.entrySet()) {
  168.             updated = updated.addAdditionalState(entry.getKey(),
  169.                                                  entry.getValue().get(original.getDate().toAbsoluteDate()));
  170.         }

  171.         // update the additional states managed by providers
  172.         for (final FieldAdditionalStateProvider<T> provider : additionalStateProviders) {

  173.             updated = updated.addAdditionalState(provider.getName(),
  174.                                                  provider.getAdditionalState(updated));
  175.         }

  176.         return updated;

  177.     }

  178.     /** {@inheritDoc} */
  179.     public boolean isAdditionalStateManaged(final String name) {
  180.         for (final FieldAdditionalStateProvider<T> provider : additionalStateProviders) {
  181.             if (provider.getName().equals(name)) {
  182.                 return true;
  183.             }
  184.         }
  185.         return false;
  186.     }

  187.     /** {@inheritDoc} */
  188.     public String[] getManagedAdditionalStates() {
  189.         final String[] managed = new String[additionalStateProviders.size()];
  190.         for (int i = 0; i < managed.length; ++i) {
  191.             managed[i] = additionalStateProviders.get(i).getName();
  192.         }
  193.         return managed;
  194.     }

  195.     /** Get the fixed step size.
  196.      * @return fixed step size (or NaN if there are no fixed step size).
  197.      */
  198.     protected T getFixedStepSize() {
  199.         return fixedStepSize;
  200.     }

  201.     /** Get the step handler.
  202.      * @return step handler
  203.      */
  204.     protected FieldOrekitStepHandler<T> getStepHandler() {
  205.         return stepHandler;
  206.     }

  207.     /** {@inheritDoc} */
  208.     public abstract FieldBoundedPropagator<T> getGeneratedEphemeris();

  209.     /** {@inheritDoc} */
  210.     public abstract <D extends FieldEventDetector<T>> void addEventDetector(D detector);

  211.     /** {@inheritDoc} */
  212.     public abstract Collection<FieldEventDetector<T>> getEventsDetectors();

  213.     /** {@inheritDoc} */
  214.     public abstract void clearEventsDetectors();

  215.     /** {@inheritDoc} */
  216.     public FieldSpacecraftState<T> propagate(final FieldAbsoluteDate<T> target) {
  217.         if (startDate == null) {
  218.             startDate = getInitialState().getDate();
  219.         }
  220.         return propagate(startDate, target);
  221.     }

  222.     /** {@inheritDoc} */
  223.     public TimeStampedFieldPVCoordinates<T> getPVCoordinates(final FieldAbsoluteDate<T> date, final Frame frame) {
  224.         return propagate(date).getPVCoordinates(frame);
  225.     }

  226.     /** Initialize propagation.
  227.      * @since 10.1
  228.      */
  229.     protected void initializePropagation() {

  230.         unmanagedStates.clear();

  231.         if (initialState != null) {
  232.             // there is an initial state
  233.             // (null initial states occur for example in interpolated ephemerides)
  234.             // copy the additional states present in initialState but otherwise not managed
  235.             for (final Map.Entry<String, T[]> initial : initialState.getAdditionalStates().entrySet()) {
  236.                 if (!isAdditionalStateManaged(initial.getKey())) {
  237.                     // this additional state is in the initial state, but is unknown to the propagator
  238.                     // we store it in a way event handlers may change it
  239.                     unmanagedStates.put(initial.getKey(), new TimeSpanMap<>(initial.getValue()));
  240.                 }
  241.             }
  242.         }
  243.     }

  244.     /** Notify about a state change.
  245.      * @param state new state
  246.      */
  247.     protected void stateChanged(final FieldSpacecraftState<T> state) {
  248.         final AbsoluteDate date    = state.getDate().toAbsoluteDate();
  249.         final boolean      forward = date.durationFrom(getStartDate().toAbsoluteDate()) >= 0.0;
  250.         for (final Map.Entry<String, T[]> changed : state.getAdditionalStates().entrySet()) {
  251.             final TimeSpanMap<T[]> tsm = unmanagedStates.get(changed.getKey());
  252.             if (tsm != null) {
  253.                 // this is an unmanaged state
  254.                 if (forward) {
  255.                     tsm.addValidAfter(changed.getValue(), date);
  256.                 } else {
  257.                     tsm.addValidBefore(changed.getValue(), date);
  258.                 }
  259.             }
  260.         }
  261.     }

  262. }