ForceModel.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.forces;

  18. import java.util.stream.Stream;

  19. import org.hipparchus.Field;
  20. import org.hipparchus.RealFieldElement;
  21. import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
  22. import org.hipparchus.geometry.euclidean.threed.Vector3D;
  23. import org.hipparchus.util.MathArrays;
  24. import org.orekit.propagation.FieldSpacecraftState;
  25. import org.orekit.propagation.SpacecraftState;
  26. import org.orekit.propagation.events.EventDetector;
  27. import org.orekit.propagation.events.FieldEventDetector;
  28. import org.orekit.propagation.numerical.FieldTimeDerivativesEquations;
  29. import org.orekit.propagation.numerical.TimeDerivativesEquations;
  30. import org.orekit.time.AbsoluteDate;
  31. import org.orekit.utils.ParameterDriver;

  32. /** This interface represents a force modifying spacecraft motion.
  33.  *
  34.  * <p>
  35.  * Objects implementing this interface are intended to be added to a
  36.  * {@link org.orekit.propagation.numerical.NumericalPropagator numerical propagator}
  37.  * before the propagation is started.
  38.  *
  39.  * <p>
  40.  * The propagator will call at each step the {@link #addContribution(SpacecraftState,
  41.  * TimeDerivativesEquations)} method. The force model instance will extract all the
  42.  * state data it needs (date, position, velocity, frame, attitude, mass) from the first
  43.  * parameter. From these state data, it will compute the perturbing acceleration. It
  44.  * will then add this acceleration to the second parameter which will take thins
  45.  * contribution into account and will use the Gauss equations to evaluate its impact
  46.  * on the global state derivative.
  47.  * </p>
  48.  * <p>
  49.  * Force models which create discontinuous acceleration patterns (typically for maneuvers
  50.  * start/stop or solar eclipses entry/exit) must provide one or more {@link
  51.  * org.orekit.propagation.events.EventDetector events detectors} to the
  52.  * propagator thanks to their {@link #getEventsDetectors()} method. This method
  53.  * is called once just before propagation starts. The events states will be checked by
  54.  * the propagator to ensure accurate propagation and proper events handling.
  55.  * </p>
  56.  *
  57.  * @author Mathieu Rom&eacute;ro
  58.  * @author Luc Maisonobe
  59.  * @author V&eacute;ronique Pommier-Maurussane
  60.  */
  61. public interface ForceModel {

  62.     /**
  63.      * Initialize the force model at the start of propagation. This method will be called
  64.      * before any calls to {@link #addContribution(SpacecraftState, TimeDerivativesEquations)},
  65.      * {@link #addContribution(FieldSpacecraftState, FieldTimeDerivativesEquations)},
  66.      * {@link #acceleration(SpacecraftState, double[])} or {@link #acceleration(FieldSpacecraftState, RealFieldElement[])}
  67.      *
  68.      * <p> The default implementation of this method does nothing.</p>
  69.      *
  70.      * @param initialState spacecraft state at the start of propagation.
  71.      * @param target       date of propagation. Not equal to {@code initialState.getDate()}.
  72.      */
  73.     default void init(SpacecraftState initialState, AbsoluteDate target) {
  74.     }

  75.     /** Compute the contribution of the force model to the perturbing
  76.      * acceleration.
  77.      * <p>
  78.      * The default implementation simply adds the {@link #acceleration(SpacecraftState, double[]) acceleration}
  79.      * as a non-Keplerian acceleration.
  80.      * </p>
  81.      * @param s current state information: date, kinematics, attitude
  82.      * @param adder object where the contribution should be added
  83.      */
  84.     default void addContribution(SpacecraftState s, TimeDerivativesEquations adder) {
  85.         adder.addNonKeplerianAcceleration(acceleration(s, getParameters()));
  86.     }

  87.     /** Compute the contribution of the force model to the perturbing
  88.      * acceleration.
  89.      * @param s current state information: date, kinematics, attitude
  90.      * @param adder object where the contribution should be added
  91.      * @param <T> type of the elements
  92.      */
  93.     default <T extends RealFieldElement<T>> void addContribution(FieldSpacecraftState<T> s, FieldTimeDerivativesEquations<T> adder) {
  94.         adder.addNonKeplerianAcceleration(acceleration(s, getParameters(s.getDate().getField())));
  95.     }

  96.     /** Get force model parameters.
  97.      * @return force model parameters
  98.      * @since 9.0
  99.      */
  100.     default double[] getParameters() {
  101.         final ParameterDriver[] drivers = getParametersDrivers();
  102.         final double[] parameters = new double[drivers.length];
  103.         for (int i = 0; i < drivers.length; ++i) {
  104.             parameters[i] = drivers[i].getValue();
  105.         }
  106.         return parameters;
  107.     }

  108.     /** Get force model parameters.
  109.      * @param field field to which the elements belong
  110.      * @param <T> type of the elements
  111.      * @return force model parameters
  112.      * @since 9.0
  113.      */
  114.     default <T extends RealFieldElement<T>> T[] getParameters(final Field<T> field) {
  115.         final ParameterDriver[] drivers = getParametersDrivers();
  116.         final T[] parameters = MathArrays.buildArray(field, drivers.length);
  117.         for (int i = 0; i < drivers.length; ++i) {
  118.             parameters[i] = field.getZero().add(drivers[i].getValue());
  119.         }
  120.         return parameters;
  121.     }

  122.     /** Check if force models depends on position only.
  123.      * @return true if force model depends on position only, false
  124.      * if it depends on velocity, either directly or due to a dependency
  125.      * on attitude
  126.      * @since 9.0
  127.      */
  128.     boolean dependsOnPositionOnly();

  129.     /** Compute acceleration.
  130.      * @param s current state information: date, kinematics, attitude
  131.      * @param parameters values of the force model parameters
  132.      * @return acceleration in same frame as state
  133.      * @since 9.0
  134.      */
  135.     Vector3D acceleration(SpacecraftState s, double[] parameters);

  136.     /** Compute acceleration.
  137.      * @param s current state information: date, kinematics, attitude
  138.      * @param parameters values of the force model parameters
  139.      * @return acceleration in same frame as state
  140.      * @param <T> type of the elements
  141.      * @since 9.0
  142.      */
  143.     <T extends RealFieldElement<T>> FieldVector3D<T> acceleration(FieldSpacecraftState<T> s, T[] parameters);

  144.     /** Get the discrete events related to the model.
  145.      * @return stream of events detectors
  146.      */
  147.     Stream<EventDetector> getEventsDetectors();

  148.     /** Get the discrete events related to the model.
  149.      * @param field field to which the state belongs
  150.      * @param <T> extends RealFieldElement&lt;T&gt;
  151.      * @return stream of events detectors
  152.      */
  153.     <T extends RealFieldElement<T>> Stream<FieldEventDetector<T>> getFieldEventsDetectors(Field<T> field);

  154.     /** Get the drivers for force model parameters.
  155.      * @return drivers for force model parameters
  156.      * @since 8.0
  157.      */
  158.     ParameterDriver[] getParametersDrivers();

  159.     /** Get parameter value from its name.
  160.      * @param name parameter name
  161.      * @return parameter value
  162.           * @since 8.0
  163.      */
  164.     ParameterDriver getParameterDriver(String name);

  165.     /** Check if a parameter is supported.
  166.      * <p>Supported parameters are those listed by {@link #getParametersDrivers()}.</p>
  167.      * @param name parameter name to check
  168.      * @return true if the parameter is supported
  169.      * @see #getParametersDrivers()
  170.      */
  171.     boolean isSupported(String name);

  172. }