OceanTides.java

  1. /* Copyright 2002-2022 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 java.util.stream.Stream;

  20. import org.hipparchus.Field;
  21. import org.hipparchus.CalculusFieldElement;
  22. import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
  23. import org.hipparchus.geometry.euclidean.threed.Vector3D;
  24. import org.orekit.annotation.DefaultDataContext;
  25. import org.orekit.data.DataContext;
  26. import org.orekit.forces.AbstractForceModel;
  27. import org.orekit.forces.ForceModel;
  28. import org.orekit.forces.gravity.potential.CachedNormalizedSphericalHarmonicsProvider;
  29. import org.orekit.forces.gravity.potential.GravityFields;
  30. import org.orekit.forces.gravity.potential.NormalizedSphericalHarmonicsProvider;
  31. import org.orekit.forces.gravity.potential.OceanTidesWave;
  32. import org.orekit.frames.Frame;
  33. import org.orekit.propagation.FieldSpacecraftState;
  34. import org.orekit.propagation.SpacecraftState;
  35. import org.orekit.propagation.events.EventDetector;
  36. import org.orekit.propagation.events.FieldEventDetector;
  37. import org.orekit.time.TimeScales;
  38. import org.orekit.time.UT1Scale;
  39. import org.orekit.utils.Constants;
  40. import org.orekit.utils.IERSConventions;
  41. import org.orekit.utils.OrekitConfiguration;
  42. import org.orekit.utils.ParameterDriver;

  43. /** Ocean tides force model.
  44.  * @since 6.1
  45.  * @author Luc Maisonobe
  46.  */
  47. public class OceanTides extends AbstractForceModel {

  48.     /** Default step for tides field sampling (seconds). */
  49.     public static final double DEFAULT_STEP = 600.0;

  50.     /** Default number of points tides field sampling. */
  51.     public static final int DEFAULT_POINTS = 12;

  52.     /** Underlying attraction model. */
  53.     private final ForceModel attractionModel;

  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.      * <p>This constructor uses the {@link DataContext#getDefault() default data context}.
  61.      *
  62.      * @param centralBodyFrame rotating body frame
  63.      * @param ae central body reference radius
  64.      * @param mu central body attraction coefficient
  65.      * @param degree degree of the tide model to load
  66.      * @param order order of the tide model to load
  67.      * @param conventions IERS conventions used for loading ocean pole tide
  68.      * @param ut1 UT1 time scale
  69.      * @see #DEFAULT_STEP
  70.      * @see #DEFAULT_POINTS
  71.      * @see #OceanTides(Frame, double, double, boolean, double, int, int, int, IERSConventions, UT1Scale)
  72.      * @see GravityFields#getOceanTidesWaves(int, int)
  73.      * @see #OceanTides(Frame, double, double, boolean, double, int, int, int,
  74.      * IERSConventions, UT1Scale, GravityFields)
  75.      */
  76.     @DefaultDataContext
  77.     public OceanTides(final Frame centralBodyFrame, final double ae, final double mu,
  78.                       final int degree, final int order,
  79.                       final IERSConventions conventions, final UT1Scale ut1) {
  80.         this(centralBodyFrame, ae, mu, true,
  81.              DEFAULT_STEP, DEFAULT_POINTS, degree, order,
  82.              conventions, ut1);
  83.     }

  84.     /** Simple constructor.
  85.      *
  86.      * <p>This constructor uses the {@link DataContext#getDefault() default data context}.
  87.      *
  88.      * @param centralBodyFrame rotating body frame
  89.      * @param ae central body reference radius
  90.      * @param mu central body attraction coefficient
  91.      * @param poleTide if true, pole tide is computed
  92.      * @param step time step between sample points for interpolation
  93.      * @param nbPoints number of points to use for interpolation, if less than 2
  94.      * then no interpolation is performed (thus greatly increasing computation cost)
  95.      * @param degree degree of the tide model to load
  96.      * @param order order of the tide model to load
  97.      * @param conventions IERS conventions used for loading ocean pole tide
  98.      * @param ut1 UT1 time scale
  99.      * @see GravityFields#getOceanTidesWaves(int, int)
  100.      * @see #OceanTides(Frame, double, double, boolean, double, int, int, int,
  101.      * IERSConventions, UT1Scale, GravityFields)
  102.      */
  103.     @DefaultDataContext
  104.     public OceanTides(final Frame centralBodyFrame, final double ae, final double mu,
  105.                       final boolean poleTide, final double step, final int nbPoints,
  106.                       final int degree, final int order,
  107.                       final IERSConventions conventions, final UT1Scale ut1) {
  108.         this(centralBodyFrame, ae, mu, poleTide, step, nbPoints, degree, order,
  109.                 conventions, ut1, DataContext.getDefault().getGravityFields());
  110.     }

  111.     /** Simple constructor.
  112.      * @param centralBodyFrame rotating body frame
  113.      * @param ae central body reference radius
  114.      * @param mu central body attraction coefficient
  115.      * @param poleTide if true, pole tide is computed
  116.      * @param step time step between sample points for interpolation
  117.      * @param nbPoints number of points to use for interpolation, if less than 2
  118.      * then no interpolation is performed (thus greatly increasing computation cost)
  119.      * @param degree degree of the tide model to load
  120.      * @param order order of the tide model to load
  121.      * @param conventions IERS conventions used for loading ocean pole tide
  122.      * @param ut1 UT1 time scale
  123.      * @param gravityFields used to compute ocean tides.
  124.      * @see GravityFields#getOceanTidesWaves(int, int)
  125.      * @since 10.1
  126.      */
  127.     public OceanTides(final Frame centralBodyFrame, final double ae, final double mu,
  128.                       final boolean poleTide, final double step, final int nbPoints,
  129.                       final int degree, final int order,
  130.                       final IERSConventions conventions, final UT1Scale ut1,
  131.                       final GravityFields gravityFields) {

  132.         // load the ocean tides model
  133.         final List<OceanTidesWave> waves = gravityFields.getOceanTidesWaves(degree, order);

  134.         final TimeScales timeScales = ut1.getEOPHistory().getTimeScales();
  135.         final OceanTidesField raw =
  136.                 new OceanTidesField(ae, mu, waves,
  137.                                     conventions.getNutationArguments(ut1, timeScales),
  138.                                     poleTide ? conventions.getOceanPoleTide(ut1.getEOPHistory()) : null);

  139.         final NormalizedSphericalHarmonicsProvider provider;
  140.         if (nbPoints < 2) {
  141.             provider = raw;
  142.         } else {
  143.             provider =
  144.                 new CachedNormalizedSphericalHarmonicsProvider(raw, step, nbPoints,
  145.                                                                OrekitConfiguration.getCacheSlotsNumber(),
  146.                                                                7 * Constants.JULIAN_DAY,
  147.                                                                0.5 * Constants.JULIAN_DAY);
  148.         }

  149.         attractionModel = new HolmesFeatherstoneAttractionModel(centralBodyFrame, provider);

  150.     }

  151.     /** {@inheritDoc} */
  152.     @Override
  153.     public boolean dependsOnPositionOnly() {
  154.         return attractionModel.dependsOnPositionOnly();
  155.     }

  156.     /** {@inheritDoc} */
  157.     @Override
  158.     public Vector3D acceleration(final SpacecraftState s, final double[] parameters) {
  159.         // delegate to underlying model
  160.         return attractionModel.acceleration(s, parameters);
  161.     }

  162.     /** {@inheritDoc} */
  163.     @Override
  164.     public <T extends CalculusFieldElement<T>> FieldVector3D<T> acceleration(final FieldSpacecraftState<T> s,
  165.                                                                          final T[] parameters) {
  166.         // delegate to underlying model
  167.         return attractionModel.acceleration(s, parameters);
  168.     }


  169.     /** {@inheritDoc} */
  170.     @Override
  171.     public Stream<EventDetector> getEventsDetectors() {
  172.         // delegate to underlying attraction model
  173.         return attractionModel.getEventsDetectors();
  174.     }

  175.     /** {@inheritDoc} */
  176.     @Override
  177.     public <T extends CalculusFieldElement<T>> Stream<FieldEventDetector<T>> getFieldEventsDetectors(final Field<T> field) {
  178.         // delegate to underlying attraction model
  179.         return attractionModel.getFieldEventsDetectors(field);
  180.     }

  181.     /** {@inheritDoc} */
  182.     @Override
  183.     public List<ParameterDriver> getParametersDrivers() {
  184.         // delegate to underlying attraction model
  185.         return attractionModel.getParametersDrivers();
  186.     }

  187. }