CartesianAdjointInertialTerm.java

  1. /* Copyright 2022-2024 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.analysis.differentiation.FieldGradient;
  20. import org.hipparchus.analysis.differentiation.Gradient;
  21. import org.hipparchus.geometry.euclidean.threed.FieldRotation;
  22. import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
  23. import org.hipparchus.geometry.euclidean.threed.Rotation;
  24. import org.hipparchus.geometry.euclidean.threed.Vector3D;
  25. import org.hipparchus.util.MathArrays;
  26. import org.orekit.errors.OrekitIllegalArgumentException;
  27. import org.orekit.errors.OrekitMessages;
  28. import org.orekit.frames.FieldTransform;
  29. import org.orekit.frames.Frame;
  30. import org.orekit.frames.Transform;
  31. import org.orekit.time.AbsoluteDate;
  32. import org.orekit.time.FieldAbsoluteDate;

  33. /**
  34.  * Class defining inertial forces' contributions in the adjoint equations for Cartesian coordinates.
  35.  * If present, then the propagator should also include inertial forces.
  36.  * @author Romain Serra
  37.  * @see CartesianAdjointEquationTerm
  38.  * @see org.orekit.forces.inertia.InertialForces
  39.  * @since 12.2
  40.  */
  41. public class CartesianAdjointInertialTerm extends AbstractCartesianAdjointEquationTerm {

  42.     /** Reference frame for inertial forces. Must be inertial. */
  43.     private final Frame referenceInertialFrame;

  44.     /**
  45.      * Constructor.
  46.      * @param referenceInertialFrame reference inertial frame
  47.      */
  48.     public CartesianAdjointInertialTerm(final Frame referenceInertialFrame) {
  49.         this.referenceInertialFrame = referenceInertialFrame;
  50.         if (!referenceInertialFrame.isPseudoInertial()) {
  51.             throw new OrekitIllegalArgumentException(OrekitMessages.NON_PSEUDO_INERTIAL_FRAME_NOT_SUITABLE_AS_REFERENCE_FOR_INERTIAL_FORCES,
  52.                     referenceInertialFrame.getName());
  53.         }
  54.     }

  55.     /**
  56.      * Getter for reference frame.
  57.      * @return frame
  58.      */
  59.     public Frame getReferenceInertialFrame() {
  60.         return referenceInertialFrame;
  61.     }

  62.     /** {@inheritDoc} */
  63.     @Override
  64.     public double[] getRatesContribution(final AbsoluteDate date, final double[] stateVariables,
  65.                                          final double[] adjointVariables, final Frame frame) {
  66.         final double[] contribution = new double[adjointVariables.length];
  67.         final Gradient[] gradients = buildGradientCartesianVector(stateVariables);
  68.         final Transform transform = getReferenceInertialFrame().getTransformTo(frame, date);
  69.         final FieldTransform<Gradient> fieldTransform = new FieldTransform<>(gradients[0].getField(), transform);
  70.         final FieldVector3D<Gradient> acceleration = getFieldAcceleration(fieldTransform, gradients);
  71.         final double[] accelerationXgradient = acceleration.getX().getGradient();
  72.         final double[] accelerationYgradient = acceleration.getY().getGradient();
  73.         final double[] accelerationZgradient = acceleration.getZ().getGradient();
  74.         for (int i = 0; i < 6; i++) {
  75.             contribution[i] = -(accelerationXgradient[i] * adjointVariables[3] + accelerationYgradient[i] * adjointVariables[4] + accelerationZgradient[i] * adjointVariables[5]);
  76.         }
  77.         return contribution;
  78.     }

  79.     /** {@inheritDoc} */
  80.     @Override
  81.     public <T extends CalculusFieldElement<T>> T[] getFieldRatesContribution(final FieldAbsoluteDate<T> date,
  82.                                                                              final T[] stateVariables,
  83.                                                                              final T[] adjointVariables, final Frame frame) {
  84.         final T[] contribution = MathArrays.buildArray(date.getField(), 6);
  85.         final FieldGradient<T>[] gradients = buildFieldGradientCartesianVector(stateVariables);
  86.         final FieldTransform<T> transform = getReferenceInertialFrame().getTransformTo(frame, date);
  87.         final FieldTransform<FieldGradient<T>> fieldTransform = new FieldTransform<>(gradients[0].getField(),
  88.                 new Transform(date.toAbsoluteDate(), transform.getAngular().toAngularCoordinates()));
  89.         final FieldVector3D<FieldGradient<T>> acceleration = getFieldAcceleration(fieldTransform, gradients);
  90.         final T[] accelerationXgradient = acceleration.getX().getGradient();
  91.         final T[] accelerationYgradient = acceleration.getY().getGradient();
  92.         final T[] accelerationZgradient = acceleration.getZ().getGradient();
  93.         for (int i = 0; i < 6; i++) {
  94.             contribution[i] = (accelerationXgradient[i].multiply(adjointVariables[3])
  95.                 .add(accelerationYgradient[i].multiply(adjointVariables[4])).add(accelerationZgradient[i].multiply(adjointVariables[5]))).negate();
  96.         }
  97.         return contribution;
  98.     }

  99.     /** {@inheritDoc} */
  100.     @Override
  101.     protected Vector3D getAcceleration(final AbsoluteDate date, final double[] stateVariables,
  102.                                        final Frame frame) {
  103.         final Transform transform = getReferenceInertialFrame().getTransformTo(frame, date);
  104.         return getAcceleration(transform, stateVariables);
  105.     }

  106.     /**
  107.      * Evaluates the inertial acceleration vector.
  108.      * @param inertialToPropagationFrame transform from inertial to propagation frame
  109.      * @param stateVariables state variables
  110.      * @return acceleration
  111.      */
  112.     public Vector3D getAcceleration(final Transform inertialToPropagationFrame, final double[] stateVariables) {
  113.         final Vector3D  a1                = inertialToPropagationFrame.getCartesian().getAcceleration();
  114.         final Rotation r1                = inertialToPropagationFrame.getAngular().getRotation();
  115.         final Vector3D  o1                = inertialToPropagationFrame.getAngular().getRotationRate();
  116.         final Vector3D  oDot1             = inertialToPropagationFrame.getAngular().getRotationAcceleration();

  117.         final Vector3D  p2                = new Vector3D(stateVariables[0], stateVariables[1], stateVariables[2]);
  118.         final Vector3D  v2                = new Vector3D(stateVariables[3], stateVariables[4], stateVariables[5]);

  119.         final Vector3D crossCrossP        = Vector3D.crossProduct(o1,    Vector3D.crossProduct(o1, p2));
  120.         final Vector3D crossV             = Vector3D.crossProduct(o1,    v2);
  121.         final Vector3D crossDotP          = Vector3D.crossProduct(oDot1, p2);

  122.         return r1.applyTo(a1).subtract(new Vector3D(2, crossV, 1, crossCrossP, 1, crossDotP));
  123.     }

  124.     /** {@inheritDoc} */
  125.     @Override
  126.     protected <T extends CalculusFieldElement<T>> FieldVector3D<T> getFieldAcceleration(final FieldAbsoluteDate<T> date,
  127.                                                                                         final T[] stateVariables,
  128.                                                                                         final Frame frame) {
  129.         final FieldTransform<T> transform = getReferenceInertialFrame().getTransformTo(frame, date);
  130.         return getFieldAcceleration(transform, stateVariables);
  131.     }

  132.     /**
  133.      * Evaluates the inertial acceleration vector in Field.
  134.      * @param inertialToPropagationFrame transform from inertial to propagation frame
  135.      * @param stateVariables state variables
  136.      * @param <T> field type
  137.      * @return acceleration
  138.      */
  139.     private <T extends CalculusFieldElement<T>> FieldVector3D<T> getFieldAcceleration(final FieldTransform<T> inertialToPropagationFrame,
  140.                                                                                       final T[] stateVariables) {
  141.         final FieldVector3D<T>  a1                = inertialToPropagationFrame.getCartesian().getAcceleration();
  142.         final FieldRotation<T> r1                = inertialToPropagationFrame.getAngular().getRotation();
  143.         final FieldVector3D<T>  o1                = inertialToPropagationFrame.getAngular().getRotationRate();
  144.         final FieldVector3D<T>  oDot1             = inertialToPropagationFrame.getAngular().getRotationAcceleration();

  145.         final FieldVector3D<T>  p2                = new FieldVector3D<>(stateVariables[0], stateVariables[1], stateVariables[2]);
  146.         final FieldVector3D<T>  v2                = new FieldVector3D<>(stateVariables[3], stateVariables[4], stateVariables[5]);

  147.         final FieldVector3D<T> crossCrossP        = FieldVector3D.crossProduct(o1,    FieldVector3D.crossProduct(o1, p2));
  148.         final FieldVector3D<T> crossV             = FieldVector3D.crossProduct(o1,    v2);
  149.         final FieldVector3D<T> crossDotP          = FieldVector3D.crossProduct(oDot1, p2);

  150.         return r1.applyTo(a1).subtract(new FieldVector3D<>(2, crossV, 1, crossCrossP, 1, crossDotP));
  151.     }
  152. }