ThirdBodyAttractionEpoch.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.forces.gravity;

  18. import org.hipparchus.analysis.differentiation.Gradient;
  19. import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
  20. import org.hipparchus.geometry.euclidean.threed.Vector3D;
  21. import org.orekit.bodies.CelestialBody;
  22. import org.orekit.propagation.SpacecraftState;

  23. /** Third body attraction force model.
  24.  * This class is a copy of {@link ThirdBodyAttraction} class.
  25.  * The computation of derivatives of the acceleration
  26.  * w.r.t. the Epoch has been added.
  27.  *
  28.  * @author Fabien Maussion
  29.  * @author Véronique Pommier-Maurussane
  30.  * @since 10.2
  31.  */
  32. public class ThirdBodyAttractionEpoch extends ThirdBodyAttraction {

  33.     /** Simple constructor.
  34.      * @param body the third body to consider
  35.      * (ex: {@link org.orekit.bodies.CelestialBodyFactory#getSun()} or
  36.      * {@link org.orekit.bodies.CelestialBodyFactory#getMoon()})
  37.      */
  38.     public ThirdBodyAttractionEpoch(final CelestialBody body) {
  39.         super(body);
  40.     }

  41.     /** Compute acceleration.
  42.      * @param s current state information: date, kinematics, attitude
  43.      * @param parameters values of the force model parameters
  44.      * @return acceleration in same frame as state
  45.      */
  46.     private FieldVector3D<Gradient> accelerationToEpoch(final SpacecraftState s, final double[] parameters) {

  47.         final double gm = parameters[0];

  48.         // compute bodies separation vectors and squared norm
  49.         final Vector3D centralToBody = getBodyPosition(s.getDate(), s.getFrame());

  50.         // Spacecraft Position
  51.         final double rx = centralToBody.getX();
  52.         final double ry = centralToBody.getY();
  53.         final double rz = centralToBody.getZ();

  54.         final int freeParameters = 3;
  55.         final Gradient fpx = Gradient.variable(freeParameters, 0, rx);
  56.         final Gradient fpy = Gradient.variable(freeParameters, 1, ry);
  57.         final Gradient fpz = Gradient.variable(freeParameters, 2, rz);

  58.         final FieldVector3D<Gradient> centralToBodyFV = new FieldVector3D<>(new Gradient[] {fpx, fpy, fpz});


  59.         final Gradient                r2Central = centralToBodyFV.getNormSq();
  60.         final FieldVector3D<Gradient> satToBody = centralToBodyFV.subtract(s.getPosition());
  61.         final Gradient                r2Sat     = satToBody.getNormSq();

  62.         return new FieldVector3D<>(gm, satToBody.scalarMultiply(r2Sat.multiply(r2Sat.sqrt()).reciprocal()),
  63.                                   -gm, centralToBodyFV.scalarMultiply(r2Central.multiply(r2Central.sqrt()).reciprocal()));
  64.     }

  65.     /** Compute derivatives of the state w.r.t epoch.
  66.      * @param s current state information: date, kinematics, attitude
  67.      * @param parameters values of the force model parameters
  68.      * @return derivatives
  69.      */
  70.     public double[] getDerivativesToEpoch(final SpacecraftState s, final double[] parameters) {

  71.         final FieldVector3D<Gradient> acc = accelerationToEpoch(s, parameters);
  72.         final Vector3D centralToBodyVelocity = getBodyPVCoordinates(s.getDate(), s.getFrame()).getVelocity();

  73.         final double[] dAccxdR1i = acc.getX().getGradient();
  74.         final double[] dAccydR1i = acc.getY().getGradient();
  75.         final double[] dAcczdR1i = acc.getZ().getGradient();
  76.         final double[] v = centralToBodyVelocity.toArray();

  77.         return new double[] {
  78.             dAccxdR1i[0] * v[0] + dAccxdR1i[1] * v[1] + dAccxdR1i[2] * v[2],
  79.             dAccydR1i[0] * v[0] + dAccydR1i[1] * v[1] + dAccydR1i[2] * v[2],
  80.             dAcczdR1i[0] * v[0] + dAcczdR1i[1] * v[1] + dAcczdR1i[2] * v[2]
  81.         };

  82.     }

  83. }