PiecewiseSphericalHarmonics.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.potential;

  18. import org.hipparchus.util.FastMath;
  19. import org.hipparchus.util.SinCos;
  20. import org.orekit.time.AbsoluteDate;
  21. import org.orekit.utils.TimeSpanMap;

  22. /** Piecewise gravity fields with time-dependent models in each interval.
  23.  * @author Luc Maisonobe
  24.  * @since 11.1
  25.  */
  26. class PiecewiseSphericalHarmonics implements RawSphericalHarmonicsProvider {

  27.     /** Constant part of the field. */
  28.     private final ConstantSphericalHarmonics constant;

  29.     /** Reference dates. */
  30.     private final AbsoluteDate[] references;

  31.     /** Pulsations (rad/s). */
  32.     private final double[] pulsations;

  33.     /** Piecewise parts. */
  34.     private final TimeSpanMap<PiecewisePart> pieces;

  35.     /** Maximum supported degree. */
  36.     private final int maxDegree;

  37.     /** Maximum supported order. */
  38.     private final int maxOrder;

  39.     /** Simple constructor.
  40.      * @param constant constant part of the field
  41.      * @param references references dates
  42.      * @param pulsations pulsations (rad/s)
  43.      * @param pieces piecewise parts
  44.      */
  45.     PiecewiseSphericalHarmonics(final ConstantSphericalHarmonics constant,
  46.                                 final AbsoluteDate[] references, final double[] pulsations,
  47.                                 final TimeSpanMap<PiecewisePart> pieces) {
  48.         this.constant   = constant;
  49.         this.references = references.clone();
  50.         this.pulsations = pulsations.clone();
  51.         this.pieces     = pieces;

  52.         // get limits
  53.         int d = constant.getMaxDegree();
  54.         int o = constant.getMaxOrder();
  55.         for (TimeSpanMap.Span<PiecewisePart> span = pieces.getFirstSpan(); span != null; span = span.next()) {
  56.             final PiecewisePart piece = span.getData();
  57.             if (piece != null) {
  58.                 d = FastMath.max(d, piece.getMaxDegree());
  59.                 o = FastMath.max(o, piece.getMaxOrder());
  60.             }
  61.         }
  62.         this.maxDegree = d;
  63.         this.maxOrder  = o;

  64.     }

  65.     /** Get the constant part of the field.
  66.      * @return constant part of the field
  67.      */
  68.     public ConstantSphericalHarmonics getConstant() {
  69.         return constant;
  70.     }

  71.     /** {@inheritDoc} */
  72.     public int getMaxDegree() {
  73.         return maxDegree;
  74.     }

  75.     /** {@inheritDoc} */
  76.     public int getMaxOrder() {
  77.         return maxOrder;
  78.     }

  79.     /** {@inheritDoc} */
  80.     public double getMu() {
  81.         return constant.getMu();
  82.     }

  83.     /** {@inheritDoc} */
  84.     public double getAe() {
  85.         return constant.getAe();
  86.     }

  87.     /** {@inheritDoc} */
  88.     public AbsoluteDate getReferenceDate() {
  89.         AbsoluteDate last = AbsoluteDate.PAST_INFINITY;
  90.         for (final AbsoluteDate date : references) {
  91.             if (date.isAfter(last)) {
  92.                 last = date;
  93.             }
  94.         }
  95.         return last;
  96.     }

  97.     /** {@inheritDoc} */
  98.     public TideSystem getTideSystem() {
  99.         return constant.getTideSystem();
  100.     }

  101.     /** Get the raw spherical harmonic coefficients on a specific date.
  102.      * @param date to evaluate the spherical harmonics
  103.      * @return the raw spherical harmonics on {@code date}.
  104.      */
  105.     public RawSphericalHarmonics onDate(final AbsoluteDate date) {

  106.         // raw (constant) harmonics
  107.         final RawSphericalHarmonics raw = constant.onDate(date);

  108.         // select part of the piecewise model that is active at specified date
  109.         final PiecewisePart piece = pieces.get(date);

  110.         // pre-compute canonical functions
  111.         final double[]   offsets = new double[references.length];
  112.         final SinCos[][] sinCos  = new SinCos[references.length][pulsations.length];
  113.         for (int i = 0; i < references.length; ++i) {
  114.             final double offset = date.durationFrom(references[i]);
  115.             offsets[i] = offset;
  116.             for (int j = 0; j < pulsations.length; ++j) {
  117.                 sinCos[i][j] = FastMath.sinCos(offset * pulsations[j]);
  118.             }
  119.         }

  120.         return new RawSphericalHarmonics() {

  121.             @Override
  122.             public AbsoluteDate getDate() {
  123.                 return date;
  124.             }

  125.             /** {@inheritDoc} */
  126.             public double getRawCnm(final int n, final int m) {
  127.                 return raw.getRawCnm(n, m) + piece.computeCnm(n, m, offsets, sinCos);
  128.             }

  129.             /** {@inheritDoc} */
  130.             public double getRawSnm(final int n, final int m) {
  131.                 return raw.getRawSnm(n, m) + piece.computeSnm(n, m, offsets, sinCos);
  132.             }

  133.         };

  134.     }

  135. }