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.models.earth.displacement;
18  
19  import org.orekit.data.BodiesElements;
20  
21  /**
22   * Class representing a tide.
23   * @since 9.1
24   * @author Luc Maisonobe
25   */
26  public class Tide {
27  
28      /** M₂ tide. */
29      public static final Tide M2 = new Tide(255555);
30  
31      /** S₂ tide. */
32      public static final Tide S2 = new Tide(273555);
33  
34      /** N₂ tide. */
35      public static final Tide N2 = new Tide(245655);
36  
37      /** K₂ tide. */
38      public static final Tide K2 = new Tide(275555);
39  
40      /** K₁ tide. */
41      public static final Tide K1 = new Tide(165555);
42  
43      /** O₁ tide. */
44      public static final Tide O1 = new Tide(145555);
45  
46      /** P₁ tide. */
47      public static final Tide P1 = new Tide(163555);
48  
49      /** Q₁ tide. */
50      public static final Tide Q1 = new Tide(135655);
51  
52      /** Mf tide. */
53      public static final Tide MF = new Tide(75555);
54  
55      /** Mm tide. */
56      public static final Tide MM = new Tide(65455);
57  
58      /** Ssa tide. */
59      public static final Tide SSA = new Tide(57555);
60  
61      /** Doodson number. */
62      private final int doodsonNumber;
63  
64      /** Multipliers for Doodson arguments (τ, s, h, p, N', ps). */
65      private final int[] doodsonMultipliers;
66  
67      /** Multipliers for Delaunay arguments (l, l', F, D, Ω). */
68      private final int[] delaunayMultipliers;
69  
70      /** Simple constructor.
71       * @param cTau coefficient for mean lunar time
72       * @param cS coefficient for mean longitude of the Moon
73       * @param cH coefficient for mean longitude of the Sun
74       * @param cP coefficient for longitude of Moon mean perigee
75       * @param cNprime negative of the longitude of the Moon's mean ascending node on the ecliptic
76       * @param cPs coefficient for longitude of Sun mean perigee
77       */
78      public Tide(final int cTau, final int cS, final int cH, final int cP, final int cNprime, final int cPs) {
79          doodsonNumber      = doodsonMultipliersToDoodsonNumber(cTau, cS, cH, cP, cNprime, cPs);
80          doodsonMultipliers = new int[] {
81              cTau, cS, cH, cP, cNprime, cPs
82          };
83          this.delaunayMultipliers = doodsonMultipliersToDelaunayMultipliers(doodsonMultipliers);
84      }
85  
86      /** Simple constructor.
87       * @param doodsonNumber Doodson Number
88       */
89      public Tide(final int doodsonNumber) {
90          this.doodsonNumber       = doodsonNumber;
91          this.doodsonMultipliers  = doodsonNumberToDoodsonMultipliers(doodsonNumber);
92          this.delaunayMultipliers = doodsonMultipliersToDelaunayMultipliers(doodsonMultipliers);
93      }
94  
95      /** Convert Doodson number to Doodson mutipliers.
96       * @param doodsonNumber Doodson number
97       * @return Doodson multipliers
98       */
99      private static int[] doodsonNumberToDoodsonMultipliers(final int doodsonNumber) {
100         // CHECKSTYLE: stop Indentation check
101         return new int[] {
102              (doodsonNumber / 100000) % 10,
103             ((doodsonNumber /  10000) % 10) - 5,
104             ((doodsonNumber /   1000) % 10) - 5,
105             ((doodsonNumber /    100) % 10) - 5,
106             ((doodsonNumber /     10) % 10) - 5,
107             (doodsonNumber            % 10) - 5
108         };
109         // CHECKSTYLE: resume Indentation check
110     }
111 
112     /** Convert Doodson mutipliers to Doodson number.
113      * @param cTau coefficient for mean lunar time
114      * @param cS coefficient for mean longitude of the Moon
115      * @param cH coefficient for mean longitude of the Sun
116      * @param cP coefficient for longitude of Moon mean perigee
117      * @param cNprime negative of the longitude of the Moon's mean ascending node on the ecliptic
118      * @param cPs coefficient for longitude of Sun mean perigee
119      * @return Doodson number
120      */
121     private static int doodsonMultipliersToDoodsonNumber(final int cTau, final int cS, final int cH,
122                                                          final int cP, final int cNprime, final int cPs) {
123         return ((((cTau * 10 + (cS + 5)) * 10 + (cH + 5)) * 10 + (cP + 5)) * 10 + (cNprime + 5)) * 10 + (cPs + 5);
124     }
125 
126     /** Convert Doodson mutipliers to Delaunay multipliers.
127      * @param dom Doodson multipliers
128      * @return Delaunay multipliers
129      */
130     private static int[] doodsonMultipliersToDelaunayMultipliers(final int[] dom) {
131         return new int[] {
132             dom[3],
133             dom[5],
134             dom[0] - dom[1] - dom[2] - dom[3] - dom[5],
135             dom[2] + dom[5],
136             dom[0] - dom[1] - dom[2] - dom[3] + dom[4] - dom[5]
137         };
138     }
139 
140     /** Get the multipliers for Delaunay arguments (l, l', F, D, Ω).
141      * <p>
142      * Beware that for tides the multipliers for Delaunay arguments have an opposite
143      * sign with respect to the convention used for nutation computation! Here, we
144      * obey the tides convention.
145      * </p>
146      * @return multipliers for Delaunay arguments (l, l', F, D, Ω)
147      */
148     public int[] getDelaunayMultipliers() {
149         return delaunayMultipliers.clone();
150     }
151 
152     /** Get the multipliers for Doodson arguments (τ, s, h, p, N', ps).
153      * @return multipliers for Doodson arguments (τ, s, h, p, N', ps)
154      */
155     public int[] getDoodsonMultipliers() {
156         return doodsonMultipliers.clone();
157     }
158 
159     /** Get the Doodson number.
160      * @return Doodson number
161      */
162     public int getDoodsonNumber() {
163         return doodsonNumber;
164     }
165 
166     /** Get the multiplier for the τ Doodson argument.
167      * <p>
168      * This multiplier identifies semi-diurnal tides (2),
169      * diurnal tides (1) and long period tides (0)
170      * </p>
171      * @return multiplier for the τ Doodson argument
172      */
173     public int getTauMultiplier() {
174         return doodsonMultipliers[0];
175     }
176 
177     /** Get the phase of the tide.
178      * @param elements elements to use
179      * @return phase of the tide (radians)
180      */
181     public double getPhase(final BodiesElements elements) {
182         return doodsonMultipliers[0]  * elements.getGamma()  -
183                delaunayMultipliers[0] * elements.getL()      -
184                delaunayMultipliers[1] * elements.getLPrime() -
185                delaunayMultipliers[2] * elements.getF()      -
186                delaunayMultipliers[3] * elements.getD()      -
187                delaunayMultipliers[4] * elements.getOmega();
188     }
189 
190     /** Get the angular rate of the tide.
191      * @param elements elements to use
192      * @return angular rate of the tide (radians/second)
193      */
194     public double getRate(final BodiesElements elements) {
195         return doodsonMultipliers[0]  * elements.getGammaDot()  -
196                delaunayMultipliers[0] * elements.getLDot()      -
197                delaunayMultipliers[1] * elements.getLPrimeDot() -
198                delaunayMultipliers[2] * elements.getFDot()      -
199                delaunayMultipliers[3] * elements.getDDot()      -
200                delaunayMultipliers[4] * elements.getOmegaDot();
201     }
202 
203     @Override
204     public boolean equals(final Object object) {
205         if (object instanceof Tide) {
206             return doodsonNumber == ((Tide) object).doodsonNumber;
207         }
208         return false;
209     }
210 
211     @Override
212     public int hashCode() {
213         return doodsonNumber;
214     }
215 
216 }
217