ITURP834AtmosphericRefraction.java

  1. /* Copyright 2013 Applied Defense Solutions, Inc.
  2.  * Licensed to CS Communication & Systèmes (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;

  18. import org.hipparchus.optim.MaxEval;
  19. import org.hipparchus.optim.nonlinear.scalar.GoalType;
  20. import org.hipparchus.optim.univariate.BrentOptimizer;
  21. import org.hipparchus.optim.univariate.SearchInterval;
  22. import org.hipparchus.optim.univariate.UnivariateObjectiveFunction;
  23. import org.hipparchus.util.FastMath;
  24. import org.orekit.models.AtmosphericRefractionModel;
  25. import org.orekit.models.earth.troposphere.iturp834.ITURP834PathDelay;

  26. /** Implementation of refraction model for Earth exponential atmosphere based on ITU-R P.834 recommendation.
  27.  * <p>
  28.  * This class implements the ray bending part, i.e. section 1 of the recommendation.
  29.  * The excess radio path length part of the model, i.e. section 6 of the recommendation,
  30.  * is implemented in the {@link ITURP834PathDelay} class.
  31.  * </p>
  32.  *
  33.  * @author Thierry Ceolin
  34.  * @since 7.1
  35.  * @see <a href="https://www.itu.int/rec/R-REC-P.834/en">P.834 : Effects of tropospheric refraction on radiowave propagation</a>
  36.  */

  37. public class ITURP834AtmosphericRefraction implements AtmosphericRefractionModel {

  38.     /** Altitude conversion factor. */
  39.     private static final double KM_TO_M = 1000.0;

  40.     /** Coefficients conversion factor. */
  41.     private static final double INV_DEG_TO_INV_RAD = 180.0 / FastMath.PI;

  42.     /** Default a coefficients to compute refractive index for a typical atmosphere. */
  43.     private static final double DEFAULT_CORRECTION_ACOEF = 0.000315;

  44.     /** Default b coefficients to compute refractive index for a typical atmosphere. */
  45.     private static final double DEFAULT_CORRECTION_BCOEF = 0.1361 / KM_TO_M;

  46.     /** Earth ray as defined in ITU-R P.834-9 (m). */
  47.     private static final double EARTH_RAY = 6370.0 * KM_TO_M;

  48.     /** Default coefficients array for Tau function (formula number 9).
  49.      * The coefficients have been converted to SI units
  50.      */
  51.     private static final double[] CCOEF = {
  52.         INV_DEG_TO_INV_RAD * 1.314,  INV_DEG_TO_INV_RAD * 0.6437,  INV_DEG_TO_INV_RAD * 0.02869,
  53.         INV_DEG_TO_INV_RAD * 0.2305 / KM_TO_M, INV_DEG_TO_INV_RAD * 0.09428 / KM_TO_M, INV_DEG_TO_INV_RAD * 0.01096 / KM_TO_M,
  54.         INV_DEG_TO_INV_RAD * 0.008583 / (KM_TO_M * KM_TO_M)
  55.     };

  56.     /** Default coefficients array for TauZero function (formula number 14).
  57.      * The coefficients have been converted to SI units
  58.      */
  59.     private static final double[] CCOEF0 = {
  60.         INV_DEG_TO_INV_RAD * 1.728, INV_DEG_TO_INV_RAD * 0.5411, INV_DEG_TO_INV_RAD * 0.03723,
  61.         INV_DEG_TO_INV_RAD * 0.1815 / KM_TO_M, INV_DEG_TO_INV_RAD * 0.06272 / KM_TO_M, INV_DEG_TO_INV_RAD * 0.011380 / KM_TO_M,
  62.         INV_DEG_TO_INV_RAD * 0.01727 / (KM_TO_M * KM_TO_M), INV_DEG_TO_INV_RAD * 0.008288 / (KM_TO_M * KM_TO_M)
  63.     };

  64.     /** Serializable UID. */
  65.     private static final long serialVersionUID = 20160118L;

  66.     /** station altitude (m). */
  67.     private final double altitude;

  68.     /** minimal elevation angle for the station (rad). */
  69.     private final double thetamin;

  70.     /** minimal elevation angle under free-space propagation (rad). */
  71.     private final double theta0;

  72.     /** elevation where elevation+refraction correction is minimal (near inequality formula number 11 validity domain). */
  73.     private final double elev_star;

  74.     /** refraction correction value where elevation+refraction correction is minimal (near inequality 11 validity domain). */
  75.     private final double refrac_star;

  76.     /** Creates a new default instance.
  77.      * @param altitude altitude of the ground station from which measurement is performed (m)
  78.      */
  79.     public ITURP834AtmosphericRefraction(final double altitude) {
  80.         this.altitude = altitude;
  81.         thetamin = getMinimalElevation(altitude);
  82.         theta0   = thetamin - getTau(thetamin);

  83.         final double rel = 1.e-5;
  84.         final double abs = 1.e-10;
  85.         final BrentOptimizer optimizer = new BrentOptimizer(rel, abs);

  86.         // Call optimizer
  87.         elev_star = optimizer.optimize(new MaxEval(200),
  88.                                        new UnivariateObjectiveFunction(e -> e + getBaseRefraction(e)),
  89.                                        GoalType.MINIMIZE,
  90.                                        new SearchInterval(-FastMath.PI / 30., FastMath.PI / 4)).getPoint();
  91.         refrac_star = getBaseRefraction(elev_star);
  92.     }

  93.     /** Compute the refractive index correction in the case of a typical atmosphere.
  94.      * ITU-R P.834-9, formula number 8, page 3
  95.      * @param alt altitude of the station at the Earth surface (m)
  96.      * @return the refractive index
  97.      */
  98.     private double getRefractiveIndex(final double alt) {

  99.         return 1.0 + DEFAULT_CORRECTION_ACOEF * FastMath.exp(-DEFAULT_CORRECTION_BCOEF * alt);
  100.     }

  101.     /** Compute the minimal elevation angle for a station.
  102.      * ITU-R P.834-9, formula number 10, page 3
  103.      * @param alt altitude of the station at the Earth surface (m)
  104.      * @return the minimal elevation angle (rad)
  105.      */
  106.     private double getMinimalElevation(final double alt) {

  107.         return -FastMath.acos( EARTH_RAY / (EARTH_RAY + alt) * getRefractiveIndex(0.0) / getRefractiveIndex(alt));
  108.     }


  109.     /** Compute the refraction correction in the case of a reference atmosphere.
  110.      * ITU-R P.834-9, formula number 9, page 3
  111.      * @param elevation elevation angle (rad)
  112.      * @return the refraction correction angle (rad)
  113.      */
  114.     private double getTau(final double elevation) {

  115.         final double eld = FastMath.toDegrees(elevation);
  116.         final double tmp0 = CCOEF[0] + (CCOEF[1] + CCOEF[2] * eld) * eld;
  117.         final double tmp1 = altitude * (CCOEF[3] + (CCOEF[4] + CCOEF[5] * eld) * eld);
  118.         final double tmp2 = altitude * altitude * CCOEF[6];
  119.         return 1.0 / (tmp0 + tmp1 + tmp2);
  120.     }


  121.     /** Compute the refraction correction in the case of a reference atmosphere.
  122.      * ITU-R P.834-9, formula number 14, page 4
  123.      * @param elevationZero elevation angle (rad)
  124.      * @return the refraction correction angle (rad)
  125.      */

  126.     private double getTauZero(final double elevationZero) {

  127.         final double eld = FastMath.toDegrees(elevationZero);
  128.         final double tmp0 = CCOEF0[0] + (CCOEF0[1] + CCOEF0[2] * eld) * eld;
  129.         final double tmp1 = altitude * (CCOEF0[3] + (CCOEF0[4] + CCOEF0[5] * eld) * eld);
  130.         final double tmp2 = altitude * altitude * (CCOEF0[6] + CCOEF0[7] * eld);
  131.         return 1.0 / (tmp0 + tmp1 + tmp2);
  132.     }

  133.     /** Compute the refraction correction in the case of a reference atmosphere without validity domain.
  134.      * The computation is done even if the inequality (formula number 11) is not verified
  135.      * ITU-R P.834-9, formula number 14, page 3
  136.      * @param elevation elevation angle (rad)
  137.      * @return the refraction correction angle (rad)
  138.      */
  139.     private double getBaseRefraction(final double elevation) {
  140.         return getTauZero(elevation);
  141.     }

  142.     /** Get the station minimal elevation angle.
  143.      * @return the minimal elevation angle (rad)
  144.      */
  145.     public double getThetaMin() {
  146.         return thetamin;
  147.     }

  148.     /** Get the station elevation angle under free-space propagation .
  149.      * @return the elevation angle under free-space propagation (rad)
  150.      */
  151.     public double getTheta0() {
  152.         return theta0;
  153.     }

  154.     /** {@inheritDoc} */
  155.     @Override
  156.     public double getRefraction(final double elevation) {
  157.         if (elevation < elev_star ) {
  158.             return refrac_star;
  159.         }
  160.         // The validity of the formula is extended for negative elevation,
  161.         // ensuring that the refraction correction angle doesn't make visible a satellite with a too negative elevation
  162.         // elev_star is used instead of thetam (minimal elevation angle).
  163.         return getTauZero(elevation);
  164.     }

  165. }