1   /* Copyright 2002-2025 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  
19  import org.orekit.bodies.CelestialBody;
20  import org.orekit.forces.ForceModel;
21  import org.orekit.forces.ForceModelModifier;
22  import org.orekit.forces.gravity.potential.CachedNormalizedSphericalHarmonicsProvider;
23  import org.orekit.forces.gravity.potential.NormalizedSphericalHarmonicsProvider;
24  import org.orekit.forces.gravity.potential.TideSystem;
25  import org.orekit.frames.Frame;
26  import org.orekit.time.TimeScales;
27  import org.orekit.time.UT1Scale;
28  import org.orekit.utils.Constants;
29  import org.orekit.utils.IERSConventions;
30  import org.orekit.utils.OrekitConfiguration;
31  
32  /** Solid tides force model.
33   * @since 6.1
34   * @author Luc Maisonobe
35   */
36  public class SolidTides implements ForceModelModifier {
37  
38      /**
39       * Default step for tides field sampling (seconds).
40       */
41      public static final double DEFAULT_STEP = 600.0;
42  
43      /**
44       * Default number of points tides field sampling.
45       */
46      public static final int DEFAULT_POINTS = 12;
47  
48      /**
49       * Underlying attraction model.
50       */
51      private final ForceModel attractionModel;
52  
53      /**
54       * Simple constructor.
55       * <p>
56       * This constructor uses pole tides, the default {@link #DEFAULT_STEP step} and default
57       * {@link #DEFAULT_POINTS number of points} for the tides field interpolation.
58       * </p>
59       *
60       * @param centralBodyFrame  rotating body frame
61       * @param ae                central body reference radius
62       * @param mu                central body attraction coefficient
63       * @param centralTideSystem tide system used in the central attraction model
64       * @param conventions       IERS conventions used for loading Love numbers
65       * @param ut1               UT1 time scale
66       * @param bodies            tide generating bodies (typically Sun and Moon)
67       * @see #DEFAULT_STEP
68       * @see #DEFAULT_POINTS
69       * @see #SolidTides(Frame, double, double, TideSystem, boolean, double, int, IERSConventions, UT1Scale, CelestialBody...)
70       */
71      public SolidTides(final Frame centralBodyFrame, final double ae, final double mu,
72                        final TideSystem centralTideSystem,
73                        final IERSConventions conventions, final UT1Scale ut1,
74                        final CelestialBody... bodies) {
75          this(centralBodyFrame, ae, mu, centralTideSystem, true,
76                  DEFAULT_STEP, DEFAULT_POINTS, conventions, ut1, bodies);
77      }
78  
79      /**
80       * Simple constructor.
81       *
82       * @param centralBodyFrame  rotating body frame
83       * @param ae                central body reference radius
84       * @param mu                central body attraction coefficient
85       * @param centralTideSystem tide system used in the central attraction model
86       * @param poleTide          if true, pole tide is computed
87       * @param step              time step between sample points for interpolation
88       * @param nbPoints          number of points to use for interpolation, if less than 2
89       *                          then no interpolation is performed (thus greatly increasing computation cost)
90       * @param conventions       IERS conventions used for loading Love numbers
91       * @param ut1               UT1 time scale
92       * @param bodies            tide generating bodies (typically Sun and Moon)
93       */
94      public SolidTides(final Frame centralBodyFrame, final double ae, final double mu,
95                        final TideSystem centralTideSystem, final boolean poleTide,
96                        final double step, final int nbPoints,
97                        final IERSConventions conventions, final UT1Scale ut1,
98                        final CelestialBody... bodies) {
99          final TimeScales timeScales = ut1.getEOPHistory().getTimeScales();
100         final SolidTidesField raw =
101                 new SolidTidesField(conventions.getLoveNumbers(),
102                         conventions.getTideFrequencyDependenceFunction(ut1, timeScales),
103                         conventions.getPermanentTide(),
104                         poleTide ? conventions.getSolidPoleTide(ut1.getEOPHistory()) : null,
105                         centralBodyFrame, ae, mu, centralTideSystem, bodies);
106         final NormalizedSphericalHarmonicsProvider provider;
107         if (nbPoints < 2) {
108             provider = raw;
109         } else {
110             provider =
111                     new CachedNormalizedSphericalHarmonicsProvider(raw, step, nbPoints,
112                             OrekitConfiguration.getCacheSlotsNumber(),
113                             7 * Constants.JULIAN_DAY,
114                             0.5 * Constants.JULIAN_DAY);
115         }
116         attractionModel = new HolmesFeatherstoneAttractionModel(centralBodyFrame, provider);
117     }
118 
119     @Override
120     public ForceModel getUnderlyingModel() {
121         return attractionModel;
122     }
123 }