FieldPenalizedCartesianFuelCost.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.cost;

  18. import org.hipparchus.CalculusFieldElement;
  19. import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
  20. import org.orekit.errors.OrekitException;
  21. import org.orekit.errors.OrekitMessages;

  22. /**
  23.  * Abstract class for fuel cost with a penalty term proportional to a weight parameter epsilon.
  24.  * This is typically used in a continuation method, starting from epsilon equal to 1
  25.  * and going towards 0 where the fuel cost is recovered. The point is to enhance convergence.
  26.  * The control vector is the normalized (by the upper bound on magnitude) thrust force in propagation frame.
  27.  * See the following reference:
  28.  * BERTRAND, Régis et EPENOY, Richard. New smoothing techniques for solving bang–bang optimal control problems—numerical results and statistical interpretation.
  29.  * Optimal Control Applications and Methods, 2002, vol. 23, no 4, p. 171-197.
  30.  *
  31.  * @author Romain Serra
  32.  * @since 13.0
  33.  * @see FieldCartesianFuelCost
  34.  * @see PenalizedCartesianFuelCost
  35.  */
  36. public abstract class FieldPenalizedCartesianFuelCost<T extends CalculusFieldElement<T>>
  37.         extends FieldAbstractCartesianCost<T> {

  38.     /** Maximum value of thrust force Euclidean norm. */
  39.     private final T maximumThrustMagnitude;

  40.     /** Penalty weight. */
  41.     private final T epsilon;

  42.     /**
  43.      * Constructor.
  44.      *
  45.      * @param name               adjoint name
  46.      * @param massFlowRateFactor mass flow rate factor
  47.      * @param maximumThrustMagnitude maximum thrust magnitude
  48.      * @param epsilon penalty weight
  49.      */
  50.     protected FieldPenalizedCartesianFuelCost(final String name, final T massFlowRateFactor,
  51.                                               final T maximumThrustMagnitude, final T epsilon) {
  52.         super(name, massFlowRateFactor);
  53.         final double epsilonReal = epsilon.getReal();
  54.         if (epsilonReal < 0 || epsilonReal > 1) {
  55.             throw new OrekitException(OrekitMessages.INVALID_PARAMETER_RANGE, "epsilon", epsilonReal, 0, 1);
  56.         }
  57.         this.maximumThrustMagnitude = maximumThrustMagnitude;
  58.         this.epsilon = epsilon;
  59.     }

  60.     /** Getter for the penalty weight epsilon.
  61.      * @return epsilon
  62.      */
  63.     public T getEpsilon() {
  64.         return epsilon;
  65.     }

  66.     /** Getter for maximum thrust magnitude.
  67.      * @return maximum thrust
  68.      */
  69.     public T getMaximumThrustMagnitude() {
  70.         return maximumThrustMagnitude;
  71.     }

  72.     /**
  73.      * Evaluate the penalty term (without the weight), assumed to be a function of the control norm.
  74.      * @param controlNorm Euclidean norm of control vector
  75.      * @return penalty function
  76.      */
  77.     public abstract T evaluateFieldPenaltyFunction(T controlNorm);

  78.     /**
  79.      * Computes the direction of thrust.
  80.      * @param adjointVariables adjoint vector
  81.      * @return thrust direction
  82.      */
  83.     protected FieldVector3D<T> getFieldThrustDirection(final T[] adjointVariables) {
  84.         return new FieldVector3D<>(adjointVariables[3], adjointVariables[4], adjointVariables[5]).normalize();
  85.     }

  86.     /** {@inheritDoc} */
  87.     @Override
  88.     public T getFieldHamiltonianContribution(final T[] adjointVariables, final T mass) {
  89.         final FieldVector3D<T> thrustForce = getFieldThrustAccelerationVector(adjointVariables,
  90.                 mass).scalarMultiply(mass);
  91.         final T controlNorm = thrustForce.getNorm().divide(getMaximumThrustMagnitude());
  92.         return controlNorm.add(getEpsilon().multiply(evaluateFieldPenaltyFunction(controlNorm)))
  93.                 .multiply(getMaximumThrustMagnitude().negate());
  94.     }

  95. }