OceanTidesField.java

  1. /* Copyright 2002-2020 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 double getOffset(final AbsoluteDate date) {
  115.         return date.durationFrom(getReferenceDate());
  116.     }

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

  124.     /** {@inheritDoc} */
  125.     @Override
  126.     public NormalizedSphericalHarmonics onDate(final AbsoluteDate date) {

  127.         // computed Cnm and Snm coefficients
  128.         final int        rows = degree + 1;
  129.         final double[][] cnm  = new double[rows][];
  130.         final double[][] snm  = new double[rows][];
  131.         for (int i = 0; i <= degree; ++i) {
  132.             final int m = FastMath.min(i, order) + 1;
  133.             cnm[i] = new double[m];
  134.             snm[i] = new double[m];
  135.         }

  136.         final BodiesElements bodiesElements = arguments.evaluateAll(date);
  137.         for (final OceanTidesWave wave : waves) {
  138.             wave.addContribution(bodiesElements, cnm, snm);
  139.         }

  140.         if (poleTideFunction != null && degree > 1 && order > 0) {
  141.             // add pole tide
  142.             poleTide(date, cnm, snm);
  143.         }

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

  145.     }

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

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

  158.         /** evaluation date. */
  159.         private final AbsoluteDate date;

  160.         /** Cached cnm. */
  161.         private final double[][] cnm;

  162.         /** Cached snm. */
  163.         private final double[][] snm;

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

  177.         /** {@inheritDoc} */
  178.         @Override
  179.         public AbsoluteDate getDate() {
  180.             return date;
  181.         }

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

  187.         /** {@inheritDoc} */
  188.         @Override
  189.         public double getNormalizedSnm(final int n, final int m) {
  190.             return snm[n][m];
  191.         }

  192.     }

  193. }