DSSTTesseralContext.java

  1. /* Copyright 2002-2025 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.geometry.euclidean.threed.Vector3D;
  19. import org.hipparchus.util.FastMath;
  20. import org.hipparchus.util.MathUtils;
  21. import org.orekit.forces.gravity.potential.UnnormalizedSphericalHarmonicsProvider;
  22. import org.orekit.frames.Frame;
  23. import org.orekit.frames.StaticTransform;
  24. import org.orekit.propagation.semianalytical.dsst.utilities.AuxiliaryElements;

  25. /**
  26.  * This class is a container for the common parameters used in {@link DSSTTesseral}.
  27.  * <p>
  28.  * It performs parameters initialization at each integration step for the Tesseral contribution
  29.  * to the central body gravitational perturbation.
  30.  * </p>
  31.  * @author Bryan Cazabonne
  32.  * @since 10.0
  33.  */
  34. public class DSSTTesseralContext extends DSSTGravityContext {

  35.     /** Retrograde factor I.
  36.      * <p>
  37.      *  DSST model needs equinoctial orbit as internal representation.
  38.      *  Classical equinoctial elements have discontinuities when inclination
  39.      *  is close to zero. In this representation, I = +1. <br>
  40.      * To avoid this discontinuity, another representation exists and equinoctial
  41.      *  elements can be expressed in a different way, called "retrograde" orbit.
  42.      *  This implies I = -1. <br>
  43.      *  As Orekit doesn't implement the retrograde orbit, I is always set to +1.
  44.      *  But for the sake of consistency with the theory, the retrograde factor
  45.      *  has been kept in the formulas.
  46.      * </p>
  47.      */
  48.     private static final int I = 1;

  49.     /** Central body rotation angle θ. */
  50.     private double theta;

  51.     /** ecc². */
  52.     private double e2;

  53.     /** Keplerian period. */
  54.     private double period;

  55.     /** Ratio of satellite period to central body rotation period. */
  56.     private double ratio;

  57.     /**
  58.      * Simple constructor.
  59.      *
  60.      * @param auxiliaryElements auxiliary elements related to the current orbit
  61.      * @param centralBodyFrame           rotating body frame
  62.      * @param provider                   provider for spherical harmonics
  63.      * @param maxFrequencyShortPeriodics maximum value for j
  64.      * @param bodyPeriod                 central body rotation period (seconds)
  65.      * @param parameters                 values of the force model parameters
  66.      */
  67.     DSSTTesseralContext(final AuxiliaryElements auxiliaryElements,
  68.                         final Frame centralBodyFrame,
  69.                         final UnnormalizedSphericalHarmonicsProvider provider,
  70.                         final int maxFrequencyShortPeriodics,
  71.                         final double bodyPeriod,
  72.                         final double[] parameters) {

  73.         super(auxiliaryElements, centralBodyFrame, provider, parameters);

  74.         // Keplerian period
  75.         final double a = auxiliaryElements.getSma();
  76.         period = (a < 0) ? Double.POSITIVE_INFINITY : MathUtils.TWO_PI / getMeanMotion();

  77.         // Eccentricity square
  78.         e2 = auxiliaryElements.getEcc() * auxiliaryElements.getEcc();

  79.         // Central body rotation angle from equation 2.7.1-(3)(4).
  80.         final StaticTransform t = getBodyFixedToInertialTransform();
  81.         final Vector3D xB = t.transformVector(Vector3D.PLUS_I);
  82.         final Vector3D yB = t.transformVector(Vector3D.PLUS_J);
  83.         theta = FastMath.atan2(-auxiliaryElements.getVectorF().dotProduct(yB) + I * auxiliaryElements.getVectorG().dotProduct(xB),
  84.                 auxiliaryElements.getVectorF().dotProduct(xB) + I * auxiliaryElements.getVectorG().dotProduct(yB));

  85.         // Ratio of satellite to central body periods to define resonant terms
  86.         ratio = period / bodyPeriod;
  87.     }

  88.     /** Get ecc².
  89.      * @return e2
  90.      */
  91.     public double getE2() {
  92.         return e2;
  93.     }

  94.     /**
  95.      * Get Central body rotation angle θ.
  96.      * @return theta
  97.      */
  98.     public double getTheta() {
  99.         return theta;
  100.     }

  101.     /**
  102.      * Get the Keplerian period.
  103.      * <p>
  104.      * The Keplerian period is computed directly from semi major axis and central
  105.      * acceleration constant.
  106.      * </p>
  107.      * @return Keplerian period in seconds, or positive infinity for hyperbolic
  108.      *         orbits
  109.      */
  110.     public double getOrbitPeriod() {
  111.         return period;
  112.     }

  113.     /**
  114.      * Get the ratio of satellite period to central body rotation period.
  115.      * @return ratio
  116.      */
  117.     public double getRatio() {
  118.         return ratio;
  119.     }

  120. }