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.ionosphere;
18  
19  import org.hipparchus.CalculusFieldElement;
20  import org.hipparchus.util.FastMath;
21  
22  /**
23   * Single Layer Model (SLM) ionospheric mapping function.
24   * <p>
25   * The SLM mapping function assumes a single ionospheric layer with a constant height
26   * for the computation of the mapping factor.
27   * </p>
28   * @see "N. Ya’acob, M. Abdullah and M. Ismail, Determination of the GPS
29   *       total electron content using single layer model (SLM) ionospheric
30   *       mapping function, in International Journal of Computer Science and
31   *       Network Security, vol. 8, no. 9, pp. 154-160, 2008."
32   *
33   * @author Bryan Cazabonne
34   * @since 10.2
35   */
36  public class SingleLayerModelMappingFunction implements IonosphericMappingFunction {
37  
38      /** Default value for the height of the ionospheric single layer in meters. */
39      private static final double DEFAULT_HEIGHT = 450e3;
40  
41      /** Mean Earth radius in meters. */
42      private static final double RE = 6371e3;
43  
44      /** Height of the ionospheric single layer in meters.*/
45      private final double hIon;
46  
47      /**
48       * Constructor with default value.
49       * <p>
50       * Using this constructor, the height of the ionospheric single
51       * layer is equal to 450 kilometers as recommended by the IERS
52       * Convention 2010.
53       * </p>
54       */
55      public SingleLayerModelMappingFunction() {
56          this(DEFAULT_HEIGHT);
57      }
58  
59      /**
60       * Constructor.
61       * @param hIon height of the ionospheric single layer in meters
62       */
63      public SingleLayerModelMappingFunction(final double hIon) {
64          this.hIon = hIon;
65      }
66  
67      /** {@inheritDoc} */
68      @Override
69      public double mappingFactor(final double elevation) {
70          // Calculate the zenith angle from the elevation
71          final double z = FastMath.abs(0.5 * FastMath.PI - elevation);
72          // Distance ratio
73          final double ratio = RE / (RE + hIon);
74          // Mapping function
75          final double coef = FastMath.sin(z) * ratio;
76          return 1.0 / FastMath.sqrt(1.0 - coef * coef);
77      }
78  
79      /** {@inheritDoc} */
80      @Override
81      public <T extends CalculusFieldElement<T>> T mappingFactor(final T elevation) {
82          // Calculate the zenith angle from the elevation
83          final T z = FastMath.abs(elevation.negate().add(elevation.getPi().multiply(0.5)));
84          // Distance ratio
85          final double ratio = RE / (RE + hIon);
86          // Mapping function
87          final T coef = FastMath.sin(z).multiply(ratio);
88          return FastMath.sqrt(coef.multiply(coef).negate().add(1.0)).reciprocal();
89      }
90  
91  }