OceanTidesWave.java

  1. /* Copyright 2002-2015 CS Systèmes d'Information
  2.  * Licensed to CS Systèmes d'Information (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.apache.commons.math3.util.FastMath;
  19. import org.orekit.data.BodiesElements;

  20. /** Container for ocen tides coefficients for one tide wave.
  21.  * @see org.orekit.forces.gravity.OceanTides
  22.  * @see org.orekit.forces.gravity.OceanTidesField
  23.  * @author Luc Maisonobe
  24.  * @since 6.1
  25.  * @see OceanTidesReader
  26.  */
  27. public class OceanTidesWave {

  28.     /** Waves of degree 0 and 1 do not affect spacecrafts. */
  29.     private static final int START_DEGREE = 2;

  30.     /** Maximum supported degree. */
  31.     private final int degree;

  32.     /** Maximum supported order. */
  33.     private final int order;

  34.     /** Doodson number for the wave. */
  35.     private final int doodson;

  36.     /** Coefficient for γ = GMST + π tide parameter. */
  37.     private final int cGamma;

  38.     /** Coefficient for mean anomaly of the Moon. */
  39.     private final int cL;

  40.     /** Coefficient for mean anomaly of the Sun. */
  41.     private final int cLPrime;

  42.     /** Coefficient for L - Ω where L is the mean longitude of the Moon. */
  43.     private final int cF;

  44.     /** Coefficient for mean elongation of the Moon from the Sun. */
  45.     private final int cD;

  46.     /** Coefficient for mean longitude of the ascending node of the Moon. */
  47.     private final int cOmega;

  48.     /** C<sub>n,m</sub><sup>+</sup> coefficients. */
  49.     private final double[][] cPlus;

  50.     /** S<sub>n,m</sub><sup>+</sup> coefficients. */
  51.     private final double[][] sPlus;

  52.     /** C<sub>n,m</sub><sup>-</sup> coefficients. */
  53.     private final double[][] cMinus;

  54.     /** S<sub>n,m</sub><sup>-</sup> coefficients. */
  55.     private final double[][] sMinus;

  56.     /** Simple constructor.
  57.      * @param doodson Doodson number for the wave
  58.      * @param degree max degree present in the coefficients array
  59.      * @param order max order present in the coefficients array
  60.      * @param coefficients C<sub>n,m</sub><sup>+</sup>, S<sub>n,m</sub><sup>+</sup>,
  61.      * C<sub>n,m</sub><sup>-</sup> and S<sub>n,m</sub><sup>-</sup> coefficients
  62.      */
  63.     public OceanTidesWave(final int doodson, final int degree, final int order,
  64.                           final double[][][] coefficients) {

  65.         this.doodson = doodson;

  66.         // compute Doodson arguments from Doodson number
  67.         final int cPs     = ( doodson           % 10) - 5;
  68.         final int cNPrime = ((doodson / 10)     % 10) - 5;
  69.         final int cP      = ((doodson / 100)    % 10) - 5;
  70.         final int cH      = ((doodson / 1000)   % 10) - 5;
  71.         final int cS      = ((doodson / 10000)  % 10) - 5;
  72.         final int cTau    =  (doodson / 100000) % 10;

  73.         // compute Delaunay arguments from Doodson arguments
  74.         this.cGamma  =  cTau;
  75.         this.cL      = -cP;
  76.         this.cLPrime = -cPs;
  77.         this.cF      = -cTau + cS + cH + cP + cPs;
  78.         this.cD      = -cH - cPs;
  79.         this.cOmega  = -cTau + cS + cH + cP - cNPrime + cPs;

  80.         this.degree   = degree;
  81.         this.order    = order;

  82.         // distribute the coefficients
  83.         this.cPlus  = new double[degree + 1][];
  84.         this.sPlus  = new double[degree + 1][];
  85.         this.cMinus = new double[degree + 1][];
  86.         this.sMinus = new double[degree + 1][];
  87.         for (int i = 0; i <= degree; ++i) {
  88.             final int m = FastMath.min(i, order) + 1;
  89.             final double[][] row = coefficients[i];
  90.             cPlus[i]  = new double[m];
  91.             sPlus[i]  = new double[m];
  92.             cMinus[i] = new double[m];
  93.             sMinus[i] = new double[m];
  94.             for (int j = 0; j < m; ++j) {
  95.                 cPlus[i][j]  = row[j][0];
  96.                 sPlus[i][j]  = row[j][1];
  97.                 cMinus[i][j] = row[j][2];
  98.                 sMinus[i][j] = row[j][3];
  99.             }
  100.         }

  101.     }

  102.     /** Get the maximum supported degree.
  103.      * @return maximum supported degree
  104.      */
  105.     public int getMaxDegree() {
  106.         return degree;
  107.     }

  108.     /** Get the maximum supported order.
  109.      * @return maximum supported order
  110.      */
  111.     public int getMaxOrder() {
  112.         return order;
  113.     }

  114.     /** Get the Doodson number for the wave.
  115.      * @return Doodson number for the wave
  116.      */
  117.     public int getDoodson() {
  118.         return doodson;
  119.     }

  120.     /** Add the contribution of the wave to Stokes coefficients.
  121.      * @param elements nutation elements
  122.      * @param cnm spherical harmonic cosine coefficients table to add contribution too
  123.      * @param snm spherical harmonic sine coefficients table to add contribution too
  124.      */
  125.     public void addContribution(final BodiesElements elements,
  126.                                 final double[][] cnm, final double[][] snm) {

  127.         final double thetaF = cGamma * elements.getGamma() +
  128.                               cL * elements.getL() + cLPrime * elements.getLPrime() + cF * elements.getF() +
  129.                               cD * elements.getD() + cOmega * elements.getOmega();
  130.         final double cos    = FastMath.cos(thetaF);
  131.         final double sin    = FastMath.sin(thetaF);

  132.         for (int i = START_DEGREE; i <= degree; ++i) {
  133.             for (int j = 0; j <= FastMath.min(i, order); ++j) {
  134.                 // from IERS conventions 2010, section 6.3, equation 6.15
  135.                 cnm[i][j] += (cPlus[i][j] + cMinus[i][j]) * cos + (sPlus[i][j] + sMinus[i][j]) * sin;
  136.                 snm[i][j] += (sPlus[i][j] - sMinus[i][j]) * cos - (cPlus[i][j] - cMinus[i][j]) * sin;
  137.             }
  138.         }

  139.     }

  140. }