DSSTAtmosphericDrag.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.semianalytical.dsst.forces;

  18. import org.hipparchus.Field;
  19. import org.hipparchus.RealFieldElement;
  20. import org.hipparchus.util.FastMath;
  21. import org.hipparchus.util.MathArrays;
  22. import org.hipparchus.util.MathUtils;
  23. import org.orekit.forces.drag.DragForce;
  24. import org.orekit.forces.drag.DragSensitive;
  25. import org.orekit.forces.drag.IsotropicDrag;
  26. import org.orekit.models.earth.atmosphere.Atmosphere;
  27. import org.orekit.propagation.FieldSpacecraftState;
  28. import org.orekit.propagation.SpacecraftState;
  29. import org.orekit.propagation.events.EventDetector;
  30. import org.orekit.propagation.events.FieldEventDetector;
  31. import org.orekit.propagation.semianalytical.dsst.utilities.AuxiliaryElements;
  32. import org.orekit.propagation.semianalytical.dsst.utilities.FieldAuxiliaryElements;
  33. import org.orekit.utils.Constants;
  34. import org.orekit.utils.ParameterDriver;

  35. /** Atmospheric drag contribution to the
  36.  *  {@link org.orekit.propagation.semianalytical.dsst.DSSTPropagator DSSTPropagator}.
  37.  *  <p>
  38.  *  The drag acceleration is computed through the acceleration model of
  39.  *  {@link org.orekit.forces.drag.DragForce DragForce}.
  40.  *  </p>
  41.  *
  42.  * @author Pascal Parraud
  43.  */
  44. public class DSSTAtmosphericDrag extends AbstractGaussianContribution {

  45.     /** Threshold for the choice of the Gauss quadrature order. */
  46.     private static final double GAUSS_THRESHOLD = 6.0e-10;

  47.     /** Upper limit for atmospheric drag (m) . */
  48.     private static final double ATMOSPHERE_ALTITUDE_MAX = 1000000.;

  49.     /** Atmospheric drag force model. */
  50.     private final DragForce drag;

  51.     /** Critical distance from the center of the central body for entering/leaving the atmosphere. */
  52.     private final double     rbar;

  53.     /** Simple constructor with custom force.
  54.      * @param force atmospheric drag force model
  55.      * @param mu central attraction coefficient
  56.      */
  57.     public DSSTAtmosphericDrag(final DragForce force, final double mu) {
  58.         //Call to the constructor from superclass using the numerical drag model as ForceModel
  59.         super("DSST-drag-", GAUSS_THRESHOLD, force, mu);
  60.         this.drag = force;
  61.         this.rbar = ATMOSPHERE_ALTITUDE_MAX + Constants.WGS84_EARTH_EQUATORIAL_RADIUS;
  62.     }

  63.     /** Simple constructor assuming spherical spacecraft.
  64.      * @param atmosphere atmospheric model
  65.      * @param cd drag coefficient
  66.      * @param area cross sectionnal area of satellite
  67.      * @param mu central attraction coefficient
  68.      */
  69.     public DSSTAtmosphericDrag(final Atmosphere atmosphere, final double cd,
  70.                                final double area, final double mu) {
  71.         this(atmosphere, new IsotropicDrag(area, cd), mu);
  72.     }

  73.     /** Simple constructor with custom spacecraft.
  74.      * @param atmosphere atmospheric model
  75.      * @param spacecraft spacecraft model
  76.      * @param mu central attraction coefficient
  77.      */
  78.     public DSSTAtmosphericDrag(final Atmosphere atmosphere, final DragSensitive spacecraft, final double mu) {

  79.         //Call to the constructor from superclass using the numerical drag model as ForceModel
  80.         this(new DragForce(atmosphere, spacecraft), mu);
  81.     }

  82.     /** Get the atmospheric model.
  83.      * @return atmosphere model
  84.      */
  85.     public Atmosphere getAtmosphere() {
  86.         return drag.getAtmosphere();
  87.     }

  88.     /** Get the critical distance.
  89.      *  <p>
  90.      *  The critical distance from the center of the central body aims at
  91.      *  defining the atmosphere entry/exit.
  92.      *  </p>
  93.      *  @return the critical distance from the center of the central body (m)
  94.      */
  95.     public double getRbar() {
  96.         return rbar;
  97.     }

  98.     /** {@inheritDoc} */
  99.     public EventDetector[] getEventsDetectors() {
  100.         return null;
  101.     }

  102.     /** {@inheritDoc} */
  103.     @Override
  104.     public <T extends RealFieldElement<T>> FieldEventDetector<T>[] getFieldEventsDetectors(final Field<T> field) {
  105.         return null;
  106.     }

  107.     /** {@inheritDoc} */
  108.     protected double[] getLLimits(final SpacecraftState state, final AuxiliaryElements auxiliaryElements) {

  109.         final double perigee = auxiliaryElements.getSma() * (1. - auxiliaryElements.getEcc());

  110.         // Trajectory entirely out of the atmosphere
  111.         if (perigee > rbar) {
  112.             return new double[2];
  113.         }
  114.         final double apogee  = auxiliaryElements.getSma() * (1. + auxiliaryElements.getEcc());
  115.         // Trajectory entirely within of the atmosphere
  116.         if (apogee < rbar) {
  117.             return new double[] { -FastMath.PI + MathUtils.normalizeAngle(state.getLv(), 0),
  118.                                   FastMath.PI + MathUtils.normalizeAngle(state.getLv(), 0) };
  119.         }
  120.         // Else, trajectory partialy within of the atmosphere
  121.         final double fb = FastMath.acos(((auxiliaryElements.getSma() * (1. - auxiliaryElements.getEcc() * auxiliaryElements.getEcc()) / rbar) - 1.) / auxiliaryElements.getEcc());
  122.         final double wW = FastMath.atan2(auxiliaryElements.getH(), auxiliaryElements.getK());
  123.         return new double[] {wW - fb, wW + fb};
  124.     }

  125.     /** {@inheritDoc} */
  126.     protected <T extends RealFieldElement<T>> T[] getLLimits(final FieldSpacecraftState<T> state,
  127.                                                              final FieldAuxiliaryElements<T> auxiliaryElements) {

  128.         final Field<T> field = state.getDate().getField();
  129.         final T zero = field.getZero();

  130.         final T[] tab = MathArrays.buildArray(field, 2);

  131.         final T perigee = auxiliaryElements.getSma().multiply(auxiliaryElements.getEcc().negate().add(1.));
  132.         // Trajectory entirely out of the atmosphere
  133.         if (perigee.getReal() > rbar) {
  134.             return tab;
  135.         }
  136.         final T apogee  = auxiliaryElements.getSma().multiply(auxiliaryElements.getEcc().add(1.));
  137.         // Trajectory entirely within of the atmosphere
  138.         if (apogee.getReal() < rbar) {
  139.             tab[0] = MathUtils.normalizeAngle(state.getLv(), zero).subtract(FastMath.PI);
  140.             tab[1] = MathUtils.normalizeAngle(state.getLv(), zero).add(FastMath.PI);
  141.             return tab;
  142.         }
  143.         // Else, trajectory partialy within of the atmosphere
  144.         final T fb = FastMath.acos(((auxiliaryElements.getSma().multiply(auxiliaryElements.getEcc().multiply(auxiliaryElements.getEcc()).negate().add(1.)).divide(rbar)).subtract(1.)).divide(auxiliaryElements.getEcc()));
  145.         final T wW = FastMath.atan2(auxiliaryElements.getH(), auxiliaryElements.getK());

  146.         tab[0] = wW.subtract(fb);
  147.         tab[1] = wW.add(fb);
  148.         return tab;
  149.     }

  150.     /** {@inheritDoc} */
  151.     @Override
  152.     protected ParameterDriver[] getParametersDriversWithoutMu() {
  153.         return drag.getParametersDrivers();
  154.     }

  155.     /** Get spacecraft shape.
  156.      *
  157.      * @return spacecraft shape
  158.      */
  159.     public DragSensitive getSpacecraft() {
  160.         return drag.getSpacecraft();
  161.     }

  162.     /** Get drag force.
  163.      *
  164.      * @return drag force
  165.      */
  166.     public DragForce getDrag() {
  167.         return drag;
  168.     }
  169. }