CartesianToleranceProvider.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.propagation;

  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.orekit.orbits.CartesianOrbit;
  23. import org.orekit.orbits.FieldCartesianOrbit;
  24. import org.orekit.propagation.numerical.FieldNumericalPropagator;
  25. import org.orekit.propagation.numerical.NumericalPropagator;
  26. import org.orekit.utils.AbsolutePVCoordinates;
  27. import org.orekit.utils.FieldAbsolutePVCoordinates;

  28. import java.util.Arrays;


  29. /**
  30.  * Interface to define integration tolerances for adaptive schemes (like the embedded Runge-Kutta ones) propagating
  31.  * the position-velocity vector and the mass, for a total of 7 primary dependent variables (in that order).
  32.  * The tolerances are given as an array of array: each row has 7 elements, whilst the first column is the absolute tolerances and the second the relative ones.
  33.  *
  34.  * @see NumericalPropagator
  35.  * @see FieldNumericalPropagator
  36.  * @see CartesianToleranceProvider
  37.  * @since 13.0
  38.  * @author Romain Serra
  39.  */
  40. public interface CartesianToleranceProvider {

  41.     /** Default absolute tolerance for mass integration. */
  42.     double DEFAULT_ABSOLUTE_MASS_TOLERANCE = 1e-6;

  43.     /**
  44.      * Retrieve the integration tolerances given reference position and velocity vectors.
  45.      * @param position reference position vector
  46.      * @param velocity reference velocity vector
  47.      * @return absolute and relative tolerances
  48.      */
  49.     double[][] getTolerances(Vector3D position, Vector3D velocity);

  50.     /**
  51.      * Retrieve the integration tolerances given reference position and velocity Field vectors.
  52.      * @param position reference position vector
  53.      * @param velocity reference velocity vector
  54.      * @param <T> field type
  55.      * @return absolute and relative tolerances
  56.      */
  57.     default <T extends CalculusFieldElement<T>> double[][] getTolerances(FieldVector3D<T> position,
  58.                                                                          FieldVector3D<T> velocity) {
  59.         return getTolerances(position.toVector3D(), velocity.toVector3D());
  60.     }

  61.     /**
  62.      * Retrieve the integration tolerances given a reference Cartesian orbit.
  63.      * @param cartesianOrbit reference orbit
  64.      * @return absolute and relative tolerances
  65.      */
  66.     default double[][] getTolerances(CartesianOrbit cartesianOrbit) {
  67.         return getTolerances(cartesianOrbit.getPosition(), cartesianOrbit.getPVCoordinates().getVelocity());
  68.     }

  69.     /**
  70.      * Retrieve the integration tolerances given a reference Cartesian orbit.
  71.      * @param cartesianOrbit reference orbit
  72.      * @param <T> field type
  73.      * @return absolute and relative tolerances
  74.      */
  75.     default <T extends CalculusFieldElement<T>> double[][] getTolerances(FieldCartesianOrbit<T> cartesianOrbit) {
  76.         return getTolerances(cartesianOrbit.toOrbit());
  77.     }

  78.     /**
  79.      * Retrieve the integration tolerances given a reference absolute position-velocity vector.
  80.      * @param absolutePVCoordinates reference position-velocity
  81.      * @return absolute and relative tolerances
  82.      */
  83.     default double[][] getTolerances(AbsolutePVCoordinates absolutePVCoordinates) {
  84.         return getTolerances(absolutePVCoordinates.getPosition(), absolutePVCoordinates.getPVCoordinates().getVelocity());
  85.     }

  86.     /**
  87.      * Retrieve the integration tolerances given a reference absolute position-velocity vector.
  88.      * @param absolutePVCoordinates reference position-velocity
  89.      * @param <T> field type
  90.      * @return absolute and relative tolerances
  91.      */
  92.     default <T extends CalculusFieldElement<T>> double[][] getTolerances(FieldAbsolutePVCoordinates<T> absolutePVCoordinates) {
  93.         return getTolerances(absolutePVCoordinates.toAbsolutePVCoordinates());
  94.     }

  95.     /**
  96.      * Build a provider based on expected errors for position, velocity and mass respectively.
  97.      *
  98.      * <p>
  99.      * The tolerances are only <em>orders of magnitude</em>, and integrator tolerances
  100.      * are only local estimates, not global ones. So some care must be taken when using
  101.      * these tolerances. Setting 1mm as a position error does NOT mean the tolerances
  102.      * will guarantee a 1mm error position after several orbits integration.
  103.      * </p>
  104.      *
  105.      * @param dP expected position error
  106.      * @param dV expected velocity error
  107.      * @param dM expected mass error
  108.      * @return tolerance provider
  109.      */
  110.     static CartesianToleranceProvider of(final double dP, final double dV, final double dM) {
  111.         return (position, velocity) -> {
  112.             final double[] absTol = new double[7];
  113.             final double[] relTol = absTol.clone();
  114.             Arrays.fill(absTol, 0, 3, dP);
  115.             Arrays.fill(absTol, 3, 6, dV);
  116.             absTol[6] = dM;
  117.             final double relPos = dP / position.getNorm();
  118.             Arrays.fill(relTol, 0, 3, relPos);
  119.             final double relVel = dV / velocity.getNorm();
  120.             Arrays.fill(relTol, 3, 6, relVel);
  121.             relTol[6] = FastMath.min(relPos, relVel);
  122.             return new double[][] { absTol, relTol };
  123.         };
  124.     }

  125.     /**
  126.      * Build a provider based on expected errors for position only.
  127.      *
  128.      * <p>
  129.      * The tolerances are only <em>orders of magnitude</em>, and integrator tolerances
  130.      * are only local estimates, not global ones. So some care must be taken when using
  131.      * these tolerances. Setting 1mm as a position error does NOT mean the tolerances
  132.      * will guarantee a 1mm error position after several orbits integration.
  133.      * </p>
  134.      *
  135.      * @param dP expected position error
  136.      * @return tolerance provider
  137.      */
  138.     static CartesianToleranceProvider of(final double dP) {
  139.         return (position, velocity) -> {
  140.             final double[] absTol = new double[7];
  141.             final double[] relTol = absTol.clone();
  142.             final double relPos = dP / position.getNorm();
  143.             final double dV = relPos * velocity.getNorm();
  144.             Arrays.fill(absTol, 0, 3, dP);
  145.             Arrays.fill(absTol, 3, 6, dV);
  146.             absTol[6] = DEFAULT_ABSOLUTE_MASS_TOLERANCE;
  147.             Arrays.fill(relTol, 0, 7, relPos);
  148.             return new double[][] { absTol, relTol };
  149.         };
  150.     }
  151. }