AbstractVienna.java

  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.models.earth.troposphere;

  18. import java.util.Collections;
  19. import java.util.List;

  20. import org.hipparchus.CalculusFieldElement;
  21. import org.hipparchus.util.FastMath;
  22. import org.hipparchus.util.FieldSinCos;
  23. import org.hipparchus.util.SinCos;
  24. import org.orekit.bodies.FieldGeodeticPoint;
  25. import org.orekit.bodies.GeodeticPoint;
  26. import org.orekit.time.AbsoluteDate;
  27. import org.orekit.time.FieldAbsoluteDate;
  28. import org.orekit.time.TimeScale;
  29. import org.orekit.utils.FieldTrackingCoordinates;
  30. import org.orekit.utils.ParameterDriver;
  31. import org.orekit.utils.TrackingCoordinates;

  32. /** The Vienna tropospheric delay model for radio techniques.
  33.  * @since 12.1
  34.  * @author Bryan Cazabonne
  35.  * @author Luc Maisonobe
  36.  */
  37. public abstract class AbstractVienna implements TroposphericModel, TroposphereMappingFunction {

  38.     /** C coefficient from Chen and Herring gradient mapping function.
  39.      * @see "Modeling tropospheric delays for space geodetic techniques, Daniel Landskron, 2017, section 2.2"
  40.      */
  41.     private static final double C = 0.0032;

  42.     /** Provider for a<sub>h</sub> and a<sub>w</sub> coefficients. */
  43.     private final ViennaAProvider aProvider;

  44.     /** Provider for {@link AzimuthalGradientCoefficients} and {@link FieldAzimuthalGradientCoefficients}. */
  45.     private final AzimuthalGradientProvider gProvider;

  46.     /** Provider for zenith delays. */
  47.     private final TroposphericModel zenithDelayProvider;

  48.     /** UTC time scale. */
  49.     private final TimeScale utc;

  50.     /** Build a new instance.
  51.      * @param aProvider provider for a<sub>h</sub> and a<sub>w</sub> coefficients
  52.      * @param gProvider provider for {@link AzimuthalGradientCoefficients} and {@link FieldAzimuthalGradientCoefficients}
  53.      * @param zenithDelayProvider provider for zenith delays
  54.      * @param utc                 UTC time scale
  55.      */
  56.     protected AbstractVienna(final ViennaAProvider aProvider,
  57.                              final AzimuthalGradientProvider gProvider,
  58.                              final TroposphericModel zenithDelayProvider,
  59.                              final TimeScale utc) {
  60.         this.aProvider           = aProvider;
  61.         this.gProvider           = gProvider;
  62.         this.zenithDelayProvider = zenithDelayProvider;
  63.         this.utc                 = utc;
  64.     }

  65.     /** {@inheritDoc} */
  66.     @Override
  67.     public TroposphericDelay pathDelay(final TrackingCoordinates trackingCoordinates,
  68.                                        final GeodeticPoint point,
  69.                                        final double[] parameters, final AbsoluteDate date) {
  70.         // zenith delay
  71.         final TroposphericDelay delays =
  72.                         zenithDelayProvider.pathDelay(trackingCoordinates, point, parameters, date);

  73.         // mapping function
  74.         final double[] mappingFunction = mappingFactors(trackingCoordinates, point, date);

  75.         // horizontal gradient
  76.         final AzimuthalGradientCoefficients agc = gProvider.getGradientCoefficients(point, date);
  77.         final double gh;
  78.         final double gw;
  79.         if (agc != null) {

  80.             // Chen and Herring gradient mapping function
  81.             final double sinE = FastMath.sin(trackingCoordinates.getElevation());
  82.             final double tanE = FastMath.tan(trackingCoordinates.getElevation());
  83.             final double mfh  = 1.0 / (sinE * tanE + C);

  84.             final SinCos sc = FastMath.sinCos(trackingCoordinates.getAzimuth());
  85.             gh = mfh * (agc.getGnh() * sc.cos() + agc.getGeh() * sc.sin());
  86.             gw = mfh * (agc.getGnw() * sc.cos() + agc.getGew() * sc.sin());

  87.         } else {
  88.             gh = 0;
  89.             gw = 0;
  90.         }

  91.         // Tropospheric path delay
  92.         return new TroposphericDelay(delays.getZh(),
  93.                                      delays.getZw(),
  94.                                      delays.getZh() * mappingFunction[0] + gh,
  95.                                      delays.getZw() * mappingFunction[1] + gw);

  96.     }

  97.     /** {@inheritDoc} */
  98.     @Override
  99.     public <T extends CalculusFieldElement<T>> FieldTroposphericDelay<T> pathDelay(final FieldTrackingCoordinates<T> trackingCoordinates,
  100.                                                                                    final FieldGeodeticPoint<T> point,
  101.                                                                                    final T[] parameters, final FieldAbsoluteDate<T> date) {
  102.         // zenith delay
  103.         final FieldTroposphericDelay<T> delays =
  104.                         zenithDelayProvider.pathDelay(trackingCoordinates, point, parameters, date);

  105.         // mapping function
  106.         final T[] mappingFunction = mappingFactors(trackingCoordinates, point, date);

  107.         // horizontal gradient
  108.         final FieldAzimuthalGradientCoefficients<T> agc = gProvider.getGradientCoefficients(point, date);
  109.         final T gh;
  110.         final T gw;
  111.         if (agc != null) {

  112.             // Chen and Herring gradient mapping function
  113.             final T sinE = FastMath.sin(trackingCoordinates.getElevation());
  114.             final T tanE = FastMath.tan(trackingCoordinates.getElevation());
  115.             final T mfh  = sinE.multiply(tanE).add(C).reciprocal();

  116.             final FieldSinCos<T> sc = FastMath.sinCos(trackingCoordinates.getAzimuth());
  117.             gh = mfh.multiply(agc.getGnh().multiply(sc.cos()).add(agc.getGeh().multiply(sc.sin())));
  118.             gw = mfh.multiply(agc.getGnw().multiply(sc.cos()).add(agc.getGew().multiply(sc.sin())));

  119.         } else {
  120.             gh = date.getField().getZero();
  121.             gw = date.getField().getZero();
  122.         }

  123.         // Tropospheric path delay
  124.         return new FieldTroposphericDelay<>(delays.getZh(),
  125.                                             delays.getZw(),
  126.                                             delays.getZh().multiply(mappingFunction[0]).add(gh),
  127.                                             delays.getZw().multiply(mappingFunction[1]).add(gw));

  128.     }

  129.     /** {@inheritDoc} */
  130.     @Override
  131.     public List<ParameterDriver> getParametersDrivers() {
  132.         return Collections.emptyList();
  133.     }

  134.     /** Get provider for Vienna a<sub>h</sub> and a<sub>w</sub> coefficients.
  135.      * @return provider for Vienna a<sub>h</sub> and a<sub>w</sub> coefficients
  136.      */
  137.     protected ViennaAProvider getAProvider() {
  138.         return aProvider;
  139.     }

  140.     /** Get day of year.
  141.      * @param date date
  142.      * @return day of year
  143.      */
  144.     protected double getDayOfYear(final AbsoluteDate date) {
  145.         return date.getDayOfYear(utc);
  146.     }

  147.     /** Get day of year.
  148.      * @param <T> type of the field elements
  149.      * @param date date
  150.      * @return day of year
  151.      * @since 13.0
  152.      */
  153.     protected <T extends CalculusFieldElement<T>> T getDayOfYear(final FieldAbsoluteDate<T> date) {
  154.         return date.getDayOfYear(utc);
  155.     }

  156. }