OceanTides.java

  1. /* Copyright 2002-2018 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;

  18. import java.util.List;
  19. import java.util.stream.Stream;

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

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

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

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

  50.     /** Underlying attraction model. */
  51.     private final ForceModel attractionModel;

  52.     /** Simple constructor.
  53.      * <p>
  54.      * This constructor uses pole tides, the default {@link #DEFAULT_STEP step} and default
  55.      * {@link #DEFAULT_POINTS number of points} for the tides field interpolation.
  56.      * </p>
  57.      * @param centralBodyFrame rotating body frame
  58.      * @param ae central body reference radius
  59.      * @param mu central body attraction coefficient
  60.      * @param degree degree of the tide model to load
  61.      * @param order order of the tide model to load
  62.      * @param conventions IERS conventions used for loading ocean pole tide
  63.      * @param ut1 UT1 time scale
  64.      * @exception OrekitException if the ocean tides model cannot be read or the
  65.      * model does not support requested degree or order
  66.      * @see #DEFAULT_STEP
  67.      * @see #DEFAULT_POINTS
  68.      * @see #OceanTides(Frame, double, double, boolean, double, int, int, int, IERSConventions, UT1Scale)
  69.      * @see GravityFieldFactory#getOceanTidesWaves(int, int)
  70.      */
  71.     public OceanTides(final Frame centralBodyFrame, final double ae, final double mu,
  72.                       final int degree, final int order,
  73.                       final IERSConventions conventions, final UT1Scale ut1)
  74.         throws OrekitException {
  75.         this(centralBodyFrame, ae, mu, true,
  76.              DEFAULT_STEP, DEFAULT_POINTS, degree, order,
  77.              conventions, ut1);
  78.     }

  79.     /** Simple constructor.
  80.      * @param centralBodyFrame rotating body frame
  81.      * @param ae central body reference radius
  82.      * @param mu central body attraction coefficient
  83.      * @param poleTide if true, pole tide is computed
  84.      * @param step time step between sample points for interpolation
  85.      * @param nbPoints number of points to use for interpolation, if less than 2
  86.      * then no interpolation is performed (thus greatly increasing computation cost)
  87.      * @param degree degree of the tide model to load
  88.      * @param order order of the tide model to load
  89.      * @param conventions IERS conventions used for loading ocean pole tide
  90.      * @param ut1 UT1 time scale
  91.      * @exception OrekitException if the ocean tides model cannot be read or the
  92.      * model does not support requested degree or order
  93.      * @see GravityFieldFactory#getOceanTidesWaves(int, int)
  94.      */
  95.     public OceanTides(final Frame centralBodyFrame, final double ae, final double mu,
  96.                       final boolean poleTide, final double step, final int nbPoints,
  97.                       final int degree, final int order,
  98.                       final IERSConventions conventions, final UT1Scale ut1)
  99.         throws OrekitException {

  100.         // load the ocean tides model
  101.         final List<OceanTidesWave> waves = GravityFieldFactory.getOceanTidesWaves(degree, order);

  102.         final OceanTidesField raw =
  103.                 new OceanTidesField(ae, mu, waves,
  104.                                     conventions.getNutationArguments(ut1),
  105.                                     poleTide ? conventions.getOceanPoleTide(ut1.getEOPHistory()) : null);

  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.     /** {@inheritDoc} */
  119.     @Override
  120.     public boolean dependsOnPositionOnly() {
  121.         return attractionModel.dependsOnPositionOnly();
  122.     }

  123.     /** {@inheritDoc} */
  124.     @Override
  125.     public Vector3D acceleration(final SpacecraftState s, final double[] parameters)
  126.         throws OrekitException {
  127.         // delegate to underlying model
  128.         return attractionModel.acceleration(s, parameters);
  129.     }

  130.     /** {@inheritDoc} */
  131.     @Override
  132.     public <T extends RealFieldElement<T>> FieldVector3D<T> acceleration(final FieldSpacecraftState<T> s,
  133.                                                                          final T[] parameters)
  134.         throws OrekitException {
  135.         // delegate to underlying model
  136.         return attractionModel.acceleration(s, parameters);
  137.     }


  138.     /** {@inheritDoc} */
  139.     @Override
  140.     public Stream<EventDetector> getEventsDetectors() {
  141.         // delegate to underlying attraction model
  142.         return attractionModel.getEventsDetectors();
  143.     }

  144.     /** {@inheritDoc} */
  145.     @Override
  146.     public <T extends RealFieldElement<T>> Stream<FieldEventDetector<T>> getFieldEventsDetectors(final Field<T> field) {
  147.         // delegate to underlying attraction model
  148.         return attractionModel.getFieldEventsDetectors(field);
  149.     }

  150.     /** {@inheritDoc} */
  151.     @Override
  152.     public ParameterDriver[] getParametersDrivers() {
  153.         // delegate to underlying attraction model
  154.         return attractionModel.getParametersDrivers();
  155.     }

  156. }