AbstractCartesianAdjointNewtonianTerm.java

  1. /* Copyright 2022-2025 Romain Serra
  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.control.indirect.adjoint;

  18. import org.hipparchus.CalculusFieldElement;
  19. import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
  20. import org.hipparchus.geometry.euclidean.threed.Vector3D;
  21. import org.hipparchus.util.FastMath;
  22. import org.hipparchus.util.MathArrays;

  23. /**
  24.  * Abstract class for common computations regarding adjoint dynamics and Newtonian gravity for Cartesian coordinates.
  25.  *
  26.  * @author Romain Serra
  27.  * @see CartesianAdjointEquationTerm
  28.  * @since 12.2
  29.  */
  30. public abstract class AbstractCartesianAdjointNewtonianTerm extends AbstractCartesianAdjointGravitationalTerm {

  31.     /** Minus three. */
  32.     private static final double MINUS_THREE = -3;

  33.     /**
  34.      * Constructor.
  35.      * @param mu body gravitational parameter
  36.      */
  37.     protected AbstractCartesianAdjointNewtonianTerm(final double mu) {
  38.         super(mu);
  39.     }

  40.     /**
  41.      * Computes the generic term of a Newtonian attraction (central or not).
  42.      * @param relativePosition relative position w.r.t. the body
  43.      * @param adjointVariables adjoint variables
  44.      * @return contribution to velocity adjoint derivatives
  45.      */
  46.     protected double[] getNewtonianVelocityAdjointContribution(final double[] relativePosition,
  47.                                                                final double[] adjointVariables) {
  48.         final double[] contribution = new double[3];
  49.         final double x = relativePosition[0];
  50.         final double y = relativePosition[1];
  51.         final double z = relativePosition[2];
  52.         final double x2 = x * x;
  53.         final double y2 = y * y;
  54.         final double z2 = z * z;
  55.         final double r2 = x2 + y2 + z2;
  56.         final double r = FastMath.sqrt(r2);
  57.         final double factor = getMu() / (r2 * r2 * r);
  58.         final double xy = x * y;
  59.         final double xz = x * z;
  60.         final double yz = y * z;
  61.         final double pvx = adjointVariables[3];
  62.         final double pvy = adjointVariables[4];
  63.         final double pvz = adjointVariables[5];
  64.         contribution[0] = ((x2 * MINUS_THREE + r2) * pvx + xy * MINUS_THREE * pvy + xz * MINUS_THREE * pvz) * factor;
  65.         contribution[1] = ((y2 * MINUS_THREE + r2) * pvy + xy * MINUS_THREE * pvx + yz * MINUS_THREE * pvz) * factor;
  66.         contribution[2] = ((z2 * MINUS_THREE + r2) * pvz + yz * MINUS_THREE * pvy + xz * MINUS_THREE * pvx) * factor;
  67.         return contribution;
  68.     }

  69.     /**
  70.      * Computes the generic term of a Newtonian attraction (central or not).
  71.      * @param relativePosition relative position w.r.t. the body
  72.      * @param adjointVariables adjoint variables
  73.      * @param <T> field type
  74.      * @return contribution to velocity adjoint derivatives
  75.      */
  76.     protected <T extends CalculusFieldElement<T>> T[] getFieldNewtonianVelocityAdjointContribution(final T[] relativePosition,
  77.                                                                                                     final T[] adjointVariables) {
  78.         final T[] contribution = MathArrays.buildArray(adjointVariables[0].getField(), 3);
  79.         final T x = relativePosition[0];
  80.         final T y = relativePosition[1];
  81.         final T z = relativePosition[2];
  82.         final T x2 = x.multiply(x);
  83.         final T y2 = y.multiply(y);
  84.         final T z2 = z.multiply(z);
  85.         final T r2 = x2.add(y2).add(z2);
  86.         final T r = r2.sqrt();
  87.         final T factor = (r2.multiply(r2).multiply(r)).reciprocal().multiply(getMu());
  88.         final T xy = x.multiply(y);
  89.         final T xz = x.multiply(z);
  90.         final T yz = y.multiply(z);
  91.         final T pvx = adjointVariables[3];
  92.         final T pvy = adjointVariables[4];
  93.         final T pvz = adjointVariables[5];
  94.         contribution[0] = ((x2.multiply(MINUS_THREE).add(r2)).multiply(pvx).
  95.                 add((xy.multiply(MINUS_THREE)).multiply(pvy)).
  96.                 add((xz.multiply(MINUS_THREE)).multiply(pvz))).multiply(factor);
  97.         contribution[1] = ((xy.multiply(MINUS_THREE)).multiply(pvx).
  98.                 add((y2.multiply(MINUS_THREE).add(r2)).multiply(pvy)).
  99.                 add((yz.multiply(MINUS_THREE)).multiply(pvz))).multiply(factor);
  100.         contribution[2] = ((xz.multiply(MINUS_THREE)).multiply(pvx).
  101.                 add((yz.multiply(MINUS_THREE)).multiply(pvy)).
  102.                 add((z2.multiply(MINUS_THREE).add(r2)).multiply(pvz))).multiply(factor);
  103.         return contribution;
  104.     }

  105.     /**
  106.      * Compute the Newtonian acceleration.
  107.      * @param position position vector as array
  108.      * @return Newtonian acceleration vector
  109.      */
  110.     protected Vector3D getNewtonianAcceleration(final double[] position) {
  111.         final Vector3D positionVector = new Vector3D(position[0], position[1], position[2]);
  112.         final double squaredRadius = positionVector.getNormSq();
  113.         final double factor = -getMu() / (squaredRadius * FastMath.sqrt(squaredRadius));
  114.         return positionVector.scalarMultiply(factor);
  115.     }

  116.     /**
  117.      * Compute the Newtonian acceleration.
  118.      * @param position position vector as array
  119.      * @param <T> field type
  120.      * @return Newtonian acceleration vector
  121.      */
  122.     protected <T extends CalculusFieldElement<T>> FieldVector3D<T> getFieldNewtonianAcceleration(final T[] position) {
  123.         final FieldVector3D<T> positionVector = new FieldVector3D<>(position[0], position[1], position[2]);
  124.         final T squaredRadius = positionVector.getNormSq();
  125.         final T factor = (squaredRadius.multiply(FastMath.sqrt(squaredRadius))).reciprocal().multiply(-getMu());
  126.         return positionVector.scalarMultiply(factor);
  127.     }
  128. }