FieldAbstractPropagator.java

  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. import java.util.ArrayList;
  19. import java.util.Collections;
  20. import java.util.HashMap;
  21. import java.util.List;
  22. import java.util.Map;

  23. import org.hipparchus.CalculusFieldElement;
  24. import org.hipparchus.Field;
  25. import org.orekit.attitudes.AttitudeProvider;
  26. import org.orekit.errors.OrekitException;
  27. import org.orekit.errors.OrekitMessages;
  28. import org.orekit.frames.Frame;
  29. import org.orekit.propagation.sampling.FieldStepHandlerMultiplexer;
  30. import org.orekit.time.AbsoluteDate;
  31. import org.orekit.time.FieldAbsoluteDate;
  32. import org.orekit.utils.TimeSpanMap;
  33. import org.orekit.utils.TimeStampedFieldPVCoordinates;

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

  44.     /** Multiplexer for step handlers. */
  45.     private FieldStepHandlerMultiplexer<T> multiplexer;

  46.     /** Start date. */
  47.     private FieldAbsoluteDate<T> startDate;

  48.     /** Attitude provider. */
  49.     private AttitudeProvider attitudeProvider;

  50.     /** Additional state providers. */
  51.     private final List<FieldAdditionalStateProvider<T>> additionalStateProviders;

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

  54.     /** Field used.*/
  55.     private final Field<T> field;

  56.     /** Initial state. */
  57.     private FieldSpacecraftState<T> initialState;

  58.     /** Build a new instance.
  59.      * @param field setting the field
  60.      */
  61.     protected FieldAbstractPropagator(final Field<T> field) {
  62.         this.field               = field;
  63.         multiplexer              = new FieldStepHandlerMultiplexer<>();
  64.         additionalStateProviders = new ArrayList<>();
  65.         unmanagedStates          = new HashMap<>();
  66.     }

  67.     /** Set a start date.
  68.      * @param startDate start date
  69.      */
  70.     protected void setStartDate(final FieldAbsoluteDate<T> startDate) {
  71.         this.startDate = startDate;
  72.     }

  73.     /** Get the start date.
  74.      * @return start date
  75.      */
  76.     protected FieldAbsoluteDate<T> getStartDate() {
  77.         return startDate;
  78.     }

  79.     /**  {@inheritDoc} */
  80.     public AttitudeProvider getAttitudeProvider() {
  81.         return attitudeProvider;
  82.     }

  83.     /**  {@inheritDoc} */
  84.     public void setAttitudeProvider(final AttitudeProvider attitudeProvider) {
  85.         this.attitudeProvider = attitudeProvider;
  86.     }

  87.     /** Field getter.
  88.      * @return field used*/
  89.     public Field<T> getField() {
  90.         return field;
  91.     }

  92.     /** {@inheritDoc} */
  93.     public FieldSpacecraftState<T> getInitialState() {
  94.         return initialState;
  95.     }

  96.     /** {@inheritDoc} */
  97.     public Frame getFrame() {
  98.         return initialState.getFrame();
  99.     }

  100.     /** {@inheritDoc} */
  101.     public void resetInitialState(final FieldSpacecraftState<T> state) {
  102.         initialState = state;
  103.         setStartDate(state.getDate());
  104.     }

  105.     /** {@inheritDoc} */
  106.     public FieldStepHandlerMultiplexer<T> getMultiplexer() {
  107.         return multiplexer;
  108.     }

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

  111.         // check if the name is already used
  112.         if (isAdditionalStateManaged(additionalStateProvider.getName())) {
  113.             // this additional state is already registered, complain
  114.             throw new OrekitException(OrekitMessages.ADDITIONAL_STATE_NAME_ALREADY_IN_USE,
  115.                                       additionalStateProvider.getName());
  116.         }

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

  119.     }

  120.     /** {@inheritDoc} */
  121.     public List<FieldAdditionalStateProvider<T>> getAdditionalStateProviders() {
  122.         return Collections.unmodifiableList(additionalStateProviders);
  123.     }

  124.     /** Update state by adding all additional states.
  125.      * @param original original state
  126.      * @return updated state, with all additional states included
  127.      * @see #addAdditionalStateProvider(FieldAdditionalStateProvider)
  128.      */
  129.     protected FieldSpacecraftState<T> updateAdditionalStates(final FieldSpacecraftState<T> original) {

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

  133.         // update the states not managed by providers
  134.         for (final Map.Entry<String, TimeSpanMap<T[]>> entry : unmanagedStates.entrySet()) {
  135.             updated = updated.addAdditionalState(entry.getKey(),
  136.                                                  entry.getValue().get(original.getDate().toAbsoluteDate()));
  137.         }

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

  140.             updated = updated.addAdditionalState(provider.getName(),
  141.                                                  provider.getAdditionalState(updated));
  142.         }

  143.         return updated;

  144.     }

  145.     /** {@inheritDoc} */
  146.     public boolean isAdditionalStateManaged(final String name) {
  147.         for (final FieldAdditionalStateProvider<T> provider : additionalStateProviders) {
  148.             if (provider.getName().equals(name)) {
  149.                 return true;
  150.             }
  151.         }
  152.         return false;
  153.     }

  154.     /** {@inheritDoc} */
  155.     public String[] getManagedAdditionalStates() {
  156.         final String[] managed = new String[additionalStateProviders.size()];
  157.         for (int i = 0; i < managed.length; ++i) {
  158.             managed[i] = additionalStateProviders.get(i).getName();
  159.         }
  160.         return managed;
  161.     }

  162.     /** {@inheritDoc} */
  163.     public FieldSpacecraftState<T> propagate(final FieldAbsoluteDate<T> target) {
  164.         if (startDate == null) {
  165.             startDate = getInitialState().getDate();
  166.         }
  167.         return propagate(startDate, target);
  168.     }

  169.     /** {@inheritDoc} */
  170.     public TimeStampedFieldPVCoordinates<T> getPVCoordinates(final FieldAbsoluteDate<T> date, final Frame frame) {
  171.         return propagate(date).getPVCoordinates(frame);
  172.     }

  173.     /** Initialize propagation.
  174.      * @since 10.1
  175.      */
  176.     protected void initializePropagation() {

  177.         unmanagedStates.clear();

  178.         if (initialState != null) {
  179.             // there is an initial state
  180.             // (null initial states occur for example in interpolated ephemerides)
  181.             // copy the additional states present in initialState but otherwise not managed
  182.             for (final Map.Entry<String, T[]> initial : initialState.getAdditionalStates().entrySet()) {
  183.                 if (!isAdditionalStateManaged(initial.getKey())) {
  184.                     // this additional state is in the initial state, but is unknown to the propagator
  185.                     // we store it in a way event handlers may change it
  186.                     unmanagedStates.put(initial.getKey(), new TimeSpanMap<>(initial.getValue()));
  187.                 }
  188.             }
  189.         }
  190.     }

  191.     /** Notify about a state change.
  192.      * @param state new state
  193.      */
  194.     protected void stateChanged(final FieldSpacecraftState<T> state) {
  195.         final AbsoluteDate date    = state.getDate().toAbsoluteDate();
  196.         final boolean      forward = date.durationFrom(getStartDate().toAbsoluteDate()) >= 0.0;
  197.         for (final Map.Entry<String, T[]> changed : state.getAdditionalStates().entrySet()) {
  198.             final TimeSpanMap<T[]> tsm = unmanagedStates.get(changed.getKey());
  199.             if (tsm != null) {
  200.                 // this is an unmanaged state
  201.                 if (forward) {
  202.                     tsm.addValidAfter(changed.getValue(), date);
  203.                 } else {
  204.                     tsm.addValidBefore(changed.getValue(), date);
  205.                 }
  206.             }
  207.         }
  208.     }

  209. }