ZeisModel.java

  1. /* Copyright 2022 Bryan Cazabonne
  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.  * Bryan Cazabonne 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.CalculusFieldElement;
  19. import org.hipparchus.Field;
  20. import org.hipparchus.util.MathArrays;
  21. import org.orekit.propagation.semianalytical.dsst.utilities.AuxiliaryElements;
  22. import org.orekit.propagation.semianalytical.dsst.utilities.FieldAuxiliaryElements;

  23. /**
  24.  * Zeis model for J2-squared second-order terms.
  25.  *
  26.  * @see "ZEIS, Eric and CEFOLA, P. Computerized algebraic utilities for the
  27.  *      construction of nonsingular satellite theories. Journal of Guidance and
  28.  *      Control, 1980, vol. 3, no 1, p. 48-54."
  29.  *
  30.  * @see "SAN-JUAN, Juan F., LĂ“PEZ, Rosario, et CEFOLA, Paul J. A Second-Order
  31.  *      Closed-Form $$ J_2 $$ Model for the Draper Semi-Analytical Satellite
  32.  *      Theory. The Journal of the Astronautical Sciences, 2022, p. 1-27."
  33.  *
  34.  * @author Bryan Cazabonne
  35.  * @since 12.0
  36.  */
  37. public class ZeisModel implements J2SquaredModel {

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

  53.     /** Constructor. */
  54.     public ZeisModel() {
  55.         // Nothing to do...
  56.     }

  57.     /** {@inheritDoc}. */
  58.     @Override
  59.     public double[] computeMeanEquinoctialSecondOrderTerms(final DSSTJ2SquaredClosedFormContext context) {

  60.         // Auxiliary elements
  61.         final AuxiliaryElements auxiliaryElements = context.getAuxiliaryElements();

  62.         // Zeis constant
  63.         final double c2z = computeC2Z(context);

  64.         // Useful terms
  65.         final double s2mf    = 19.0 * context.getS2() - 15.0;
  66.         final double s2pIcmo = context.getS2() + I * context.getC() - 1.0;
  67.         final double s4mts2  = 19.0 * context.getS2() * context.getS2() - 30.0 * context.getS2() + 12.0;

  68.         // Second-order terms (Ref [2] Eq. 37)
  69.         final double deltaA =  0.0;
  70.         final double deltaK = -c2z * auxiliaryElements.getH() * s2mf * s2pIcmo;
  71.         final double deltaH =  c2z * auxiliaryElements.getK() * s2mf * s2pIcmo;
  72.         final double deltaQ = -c2z * context.getC() * auxiliaryElements.getP() * s2mf;
  73.         final double deltaP =  c2z * context.getC() * auxiliaryElements.getQ() * s2mf;
  74.         final double deltaM =  0.5 * c2z * (2.0 * s2mf * s2pIcmo + 5.0 * s4mts2 * context.getEta());

  75.         // Return
  76.         return new double[] { deltaA, deltaK, deltaH, deltaQ, deltaP, deltaM };

  77.     }

  78.     /** {@inheritDoc}. */
  79.     @Override
  80.     public <T extends CalculusFieldElement<T>> T[] computeMeanEquinoctialSecondOrderTerms(final FieldDSSTJ2SquaredClosedFormContext<T> context) {

  81.         // Auxiliary elements
  82.         final FieldAuxiliaryElements<T> auxiliaryElements = context.getFieldAuxiliaryElements();

  83.         // Field
  84.         final Field<T> field = auxiliaryElements.getDate().getField();

  85.         // Zeis constant
  86.         final T c2z = computeC2Z(context);

  87.         // Useful terms
  88.         final T s2mf    = context.getS2().multiply(19.0).subtract(15.0);
  89.         final T s2pIcmo = context.getS2().add(context.getC().multiply(I)).subtract(1.0);
  90.         final T s4mts2  = context.getS2().multiply(context.getS2()).multiply(19.0).subtract(context.getS2().multiply(30.0)).add(12.0);

  91.         // Second-order terms (Ref [2] Eq. 37)
  92.         final T deltaA = field.getZero();
  93.         final T deltaK = c2z.multiply(auxiliaryElements.getH()).multiply(s2mf).multiply(s2pIcmo).negate();
  94.         final T deltaH = c2z.multiply(auxiliaryElements.getK()).multiply(s2mf).multiply(s2pIcmo);
  95.         final T deltaQ = c2z.multiply(context.getC()).multiply(auxiliaryElements.getP()).multiply(s2mf).negate();
  96.         final T deltaP = c2z.multiply(context.getC()).multiply(auxiliaryElements.getQ()).multiply(s2mf);
  97.         final T deltaM = c2z.multiply(0.5).multiply(s2mf.multiply(s2pIcmo).multiply(2.0).add(s4mts2.multiply(context.getEta()).multiply(5.0)));

  98.         // Return
  99.         final T[] terms = MathArrays.buildArray(field, 6);
  100.         terms[0] = deltaA;
  101.         terms[1] = deltaK;
  102.         terms[2] = deltaH;
  103.         terms[3] = deltaQ;
  104.         terms[4] = deltaP;
  105.         terms[5] = deltaM;
  106.         return terms;

  107.     }

  108.     /**
  109.      * Get the value of the Zeis constant.
  110.      *
  111.      * @param context model context
  112.      * @return the value of the Zeis constant
  113.      */
  114.     public double computeC2Z(final DSSTJ2SquaredClosedFormContext context) {
  115.         final AuxiliaryElements auxiliaryElements = context.getAuxiliaryElements();
  116.         return 0.75 * context.getAlpha4() * auxiliaryElements.getMeanMotion() / (context.getA4() * context.getEta());
  117.     }

  118.     /**
  119.      * Get the value of the Zeis constant.
  120.      *
  121.      * @param context model context
  122.      * @param <T> type of the elements
  123.      * @return the value of the Zeis constant
  124.      */
  125.     public <T extends CalculusFieldElement<T>> T computeC2Z(final FieldDSSTJ2SquaredClosedFormContext<T> context) {
  126.         final FieldAuxiliaryElements<T> auxiliaryElements = context.getFieldAuxiliaryElements();
  127.         return auxiliaryElements.getMeanMotion().multiply(context.getAlpha4()).multiply(0.75).divide(context.getA4().multiply(context.getEta()));
  128.     }

  129. }