OceanTidesField.java

  1. /* Copyright 2002-2024 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 java.util.List;

  19. import org.hipparchus.util.FastMath;
  20. import org.orekit.data.BodiesElements;
  21. import org.orekit.data.FundamentalNutationArguments;
  22. import org.orekit.forces.gravity.potential.NormalizedSphericalHarmonicsProvider;
  23. import org.orekit.forces.gravity.potential.OceanTidesWave;
  24. import org.orekit.forces.gravity.potential.TideSystem;
  25. import org.orekit.time.AbsoluteDate;
  26. import org.orekit.time.TimeVectorFunction;

  27. /** Gravity field corresponding to ocean tides.
  28.  * <p>
  29.  * This ocean tides force model implementation corresponds to the method described
  30.  * in <a href="http://www.iers.org/nn_11216/IERS/EN/Publications/TechnicalNotes/tn36.html">
  31.  * IERS conventions (2010)</a>, chapter 6, section 6.3.
  32.  * </p>
  33.  * <p>
  34.  * Note that this class is <em>not</em> thread-safe, and that tides computation
  35.  * are computer intensive if repeated. So this class is really expected to
  36.  * be wrapped within a {@link
  37.  * org.orekit.forces.gravity.potential.CachedNormalizedSphericalHarmonicsProvider}
  38.  * that will both ensure thread safety and improve performances using caching.
  39.  * </p>
  40.  * @see OceanTides
  41.  * @author Luc Maisonobe
  42.  * @since 6.1
  43.  */
  44. class OceanTidesField implements NormalizedSphericalHarmonicsProvider {

  45.     /** Maximum degree. */
  46.     private final int degree;

  47.     /** Maximum order. */
  48.     private final int order;

  49.     /** Central body reference radius. */
  50.     private final double ae;

  51.     /** Central body attraction coefficient. */
  52.     private final double mu;

  53.     /** Tides model. */
  54.     private final List<OceanTidesWave> waves;

  55.     /** Object computing the fundamental arguments. */
  56.     private final FundamentalNutationArguments arguments;

  57.     /** Function computing pole tide terms (ΔC₂₁, ΔS₂₁). */
  58.     private final TimeVectorFunction poleTideFunction;

  59.     /** Simple constructor.
  60.      * @param ae central body reference radius
  61.      * @param mu central body attraction coefficient
  62.      * @param waves ocean tides waves
  63.      * @param arguments object computing the fundamental arguments
  64.      * @param poleTideFunction function computing ocean pole tide terms (ΔC₂₁, ΔS₂₁), may be null
  65.      */
  66.     OceanTidesField(final double ae, final double mu,
  67.                            final List<OceanTidesWave> waves,
  68.                            final FundamentalNutationArguments arguments,
  69.                            final TimeVectorFunction poleTideFunction) {

  70.         // store mode parameters
  71.         this.ae  = ae;
  72.         this.mu  = mu;

  73.         // waves
  74.         this.waves = waves;
  75.         int m = 0;
  76.         int n = 0;
  77.         for (final OceanTidesWave wave : waves) {
  78.             m = FastMath.max(m, wave.getMaxDegree());
  79.             n = FastMath.max(n, wave.getMaxOrder());
  80.         }
  81.         degree = m;
  82.         order  = n;

  83.         this.arguments = arguments;

  84.         // pole tide
  85.         this.poleTideFunction = poleTideFunction;

  86.     }

  87.     /** {@inheritDoc} */
  88.     @Override
  89.     public int getMaxDegree() {
  90.         return degree;
  91.     }

  92.     /** {@inheritDoc} */
  93.     @Override
  94.     public int getMaxOrder() {
  95.         return order;
  96.     }

  97.     /** {@inheritDoc} */
  98.     @Override
  99.     public double getMu() {
  100.         return mu;
  101.     }

  102.     /** {@inheritDoc} */
  103.     @Override
  104.     public double getAe() {
  105.         return ae;
  106.     }

  107.     /** {@inheritDoc} */
  108.     @Override
  109.     public AbsoluteDate getReferenceDate() {
  110.         return AbsoluteDate.ARBITRARY_EPOCH;
  111.     }

  112.     /** {@inheritDoc} */
  113.     @Override
  114.     public TideSystem getTideSystem() {
  115.         // not really used here, but for consistency we can state that either
  116.         // we add the permanent tide or it was already in the central attraction
  117.         return TideSystem.ZERO_TIDE;
  118.     }

  119.     /** {@inheritDoc} */
  120.     @Override
  121.     public NormalizedSphericalHarmonics onDate(final AbsoluteDate date) {

  122.         // computed Cnm and Snm coefficients
  123.         final int        rows = degree + 1;
  124.         final double[][] cnm  = new double[rows][];
  125.         final double[][] snm  = new double[rows][];
  126.         for (int i = 0; i <= degree; ++i) {
  127.             final int m = FastMath.min(i, order) + 1;
  128.             cnm[i] = new double[m];
  129.             snm[i] = new double[m];
  130.         }

  131.         final BodiesElements bodiesElements = arguments.evaluateAll(date);
  132.         for (final OceanTidesWave wave : waves) {
  133.             wave.addContribution(bodiesElements, cnm, snm);
  134.         }

  135.         if (poleTideFunction != null && degree > 1 && order > 0) {
  136.             // add pole tide
  137.             poleTide(date, cnm, snm);
  138.         }

  139.         return new TideHarmonics(date, cnm, snm);

  140.     }

  141.     /** Update coefficients applying pole tide.
  142.      * @param date current date
  143.      * @param cnm the Cnm coefficients. Modified in place.
  144.      * @param snm the Snm coefficients. Modified in place.
  145.      */
  146.     private void poleTide(final AbsoluteDate date, final double[][] cnm, final double[][] snm) {
  147.         final double[] deltaCS = poleTideFunction.value(date);
  148.         cnm[2][1] += deltaCS[0]; // ΔC₂₁
  149.         snm[2][1] += deltaCS[1]; // ΔS₂₁
  150.     }

  151.     /** The Tidal geopotential evaluated on a specific date. */
  152.     private static class TideHarmonics implements NormalizedSphericalHarmonics {

  153.         /** evaluation date. */
  154.         private final AbsoluteDate date;

  155.         /** Cached cnm. */
  156.         private final double[][] cnm;

  157.         /** Cached snm. */
  158.         private final double[][] snm;

  159.         /** Construct the tidal harmonics on the given date.
  160.          *
  161.          * @param date of evaluation
  162.          * @param cnm the Cnm coefficients. Not copied.
  163.          * @param snm the Snm coeffiecients. Not copied.
  164.          */
  165.         private TideHarmonics(final AbsoluteDate date,
  166.                               final double[][] cnm,
  167.                               final double[][] snm) {
  168.             this.date = date;
  169.             this.cnm = cnm;
  170.             this.snm = snm;
  171.         }

  172.         /** {@inheritDoc} */
  173.         @Override
  174.         public AbsoluteDate getDate() {
  175.             return date;
  176.         }

  177.         /** {@inheritDoc} */
  178.         @Override
  179.         public double getNormalizedCnm(final int n, final int m) {
  180.             return cnm[n][m];
  181.         }

  182.         /** {@inheritDoc} */
  183.         @Override
  184.         public double getNormalizedSnm(final int n, final int m) {
  185.             return snm[n][m];
  186.         }

  187.     }

  188. }