OceanTidesWave.java
/* Copyright 2002-2024 CS GROUP
* Licensed to CS GROUP (CS) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* CS licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.orekit.forces.gravity.potential;
import org.hipparchus.util.FastMath;
import org.hipparchus.util.SinCos;
import org.orekit.data.BodiesElements;
/** Container for ocen tides coefficients for one tide wave.
* @see org.orekit.forces.gravity.OceanTides
* @author Luc Maisonobe
* @since 6.1
* @see OceanTidesReader
*/
public class OceanTidesWave {
/** Waves of degree 0 and 1 do not affect spacecrafts. */
private static final int START_DEGREE = 2;
/** Maximum supported degree. */
private final int degree;
/** Maximum supported order. */
private final int order;
/** Doodson number for the wave. */
private final int doodson;
/** Coefficient for γ = GMST + π tide parameter. */
private final int cGamma;
/** Coefficient for mean anomaly of the Moon. */
private final int cL;
/** Coefficient for mean anomaly of the Sun. */
private final int cLPrime;
/** Coefficient for L - Ω where L is the mean longitude of the Moon. */
private final int cF;
/** Coefficient for mean elongation of the Moon from the Sun. */
private final int cD;
/** Coefficient for mean longitude of the ascending node of the Moon. */
private final int cOmega;
/** C<sub>n,m</sub><sup>+</sup> coefficients. */
private final double[][] cPlus;
/** S<sub>n,m</sub><sup>+</sup> coefficients. */
private final double[][] sPlus;
/** C<sub>n,m</sub><sup>-</sup> coefficients. */
private final double[][] cMinus;
/** S<sub>n,m</sub><sup>-</sup> coefficients. */
private final double[][] sMinus;
/** Simple constructor.
* @param doodson Doodson number for the wave
* @param degree max degree present in the coefficients array
* @param order max order present in the coefficients array
* @param coefficients C<sub>n,m</sub><sup>+</sup>, S<sub>n,m</sub><sup>+</sup>,
* C<sub>n,m</sub><sup>-</sup> and S<sub>n,m</sub><sup>-</sup> coefficients
*/
public OceanTidesWave(final int doodson, final int degree, final int order,
final double[][][] coefficients) {
this.doodson = doodson;
// compute Doodson arguments from Doodson number
final int cPs = ( doodson % 10) - 5;
final int cNPrime = ((doodson / 10) % 10) - 5;
final int cP = ((doodson / 100) % 10) - 5;
final int cH = ((doodson / 1000) % 10) - 5;
final int cS = ((doodson / 10000) % 10) - 5;
final int cTau = (doodson / 100000) % 10;
// compute Delaunay arguments from Doodson arguments
this.cGamma = cTau;
this.cL = -cP;
this.cLPrime = -cPs;
this.cF = -cTau + cS + cH + cP + cPs;
this.cD = -cH - cPs;
this.cOmega = -cTau + cS + cH + cP - cNPrime + cPs;
this.degree = degree;
this.order = order;
// distribute the coefficients
final int rows = degree + 1;
this.cPlus = new double[rows][];
this.sPlus = new double[rows][];
this.cMinus = new double[rows][];
this.sMinus = new double[rows][];
for (int i = 0; i <= degree; ++i) {
final int m = FastMath.min(i, order) + 1;
final double[][] row = coefficients[i];
cPlus[i] = new double[m];
sPlus[i] = new double[m];
cMinus[i] = new double[m];
sMinus[i] = new double[m];
for (int j = 0; j < m; ++j) {
cPlus[i][j] = row[j][0];
sPlus[i][j] = row[j][1];
cMinus[i][j] = row[j][2];
sMinus[i][j] = row[j][3];
}
}
}
/** Get the maximum supported degree.
* @return maximum supported degree
*/
public int getMaxDegree() {
return degree;
}
/** Get the maximum supported order.
* @return maximum supported order
*/
public int getMaxOrder() {
return order;
}
/** Get the Doodson number for the wave.
* @return Doodson number for the wave
*/
public int getDoodson() {
return doodson;
}
/** Add the contribution of the wave to Stokes coefficients.
* @param elements nutation elements
* @param cnm spherical harmonic cosine coefficients table to add contribution too
* @param snm spherical harmonic sine coefficients table to add contribution too
*/
public void addContribution(final BodiesElements elements,
final double[][] cnm, final double[][] snm) {
final double thetaF = cGamma * elements.getGamma() +
cL * elements.getL() + cLPrime * elements.getLPrime() + cF * elements.getF() +
cD * elements.getD() + cOmega * elements.getOmega();
final SinCos sc = FastMath.sinCos(thetaF);
for (int i = START_DEGREE; i <= degree; ++i) {
for (int j = 0; j <= FastMath.min(i, order); ++j) {
// from IERS conventions 2010, section 6.3, equation 6.15
cnm[i][j] += (cPlus[i][j] + cMinus[i][j]) * sc.cos() + (sPlus[i][j] + sMinus[i][j]) * sc.sin();
snm[i][j] += (sPlus[i][j] - sMinus[i][j]) * sc.cos() - (cPlus[i][j] - cMinus[i][j]) * sc.sin();
}
}
}
}