1   /* Copyright 2022-2025 Thales Alenia Space
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.weather;
18  
19  import java.util.function.Function;
20  
21  import org.hipparchus.CalculusFieldElement;
22  import org.hipparchus.Field;
23  import org.hipparchus.analysis.interpolation.FieldBilinearInterpolatingFunction;
24  import org.hipparchus.util.MathArrays;
25  
26  /** Interpolator within a grid cell.
27   * @param <T> type of the field elements
28   * @author Luc Maisonobe
29   * @since 12.1
30   */
31  public class FieldCellInterpolator<T extends CalculusFieldElement<T>> {
32  
33      /** Latitude of point of interest. */
34      private final T latitude;
35  
36      /** Longitude of point of interest. */
37      private final T longitude;
38  
39      /** South-West grid entry. */
40      private final FieldEvaluatedGridEntry<T> southWest;
41  
42      /** South-East grid entry. */
43      private final FieldEvaluatedGridEntry<T> southEast;
44  
45      /** North-West grid entry. */
46      private final FieldEvaluatedGridEntry<T> northWest;
47  
48      /** North-East grid entry. */
49      private final FieldEvaluatedGridEntry<T> northEast;
50  
51      /** Simple constructor.
52       * @param latitude latitude of point of interest
53       * @param longitude longitude of point of interest
54       * @param southWest South-West grid entry
55       * @param southEast South-East grid entry
56       * @param northWest North-West grid entry
57       * @param northEast North-East grid entry
58       */
59      FieldCellInterpolator(final T latitude, final T longitude,
60                            final FieldEvaluatedGridEntry<T> southWest, final FieldEvaluatedGridEntry<T> southEast,
61                            final FieldEvaluatedGridEntry<T> northWest, final FieldEvaluatedGridEntry<T> northEast) {
62          this.latitude  = latitude;
63          this.longitude = longitude;
64          this.southWest = southWest;
65          this.southEast = southEast;
66          this.northWest = northWest;
67          this.northEast = northEast;
68      }
69  
70      /** Interpolate a grid function.
71       * @param gridGetter getter for the grid function
72       * @return interpolated function
73       * @since 13.0
74       */
75      T fieldInterpolate(final Function<FieldEvaluatedGridEntry<T>, T> gridGetter) {
76  
77          final Field<T> field = latitude.getField();
78          final T        zero  = field.getZero();
79  
80          // cell surrounding the point
81          final T[] xVal = MathArrays.buildArray(field, 2);
82          xVal[0] = zero.newInstance(southWest.getEntry().getLongitude());
83          xVal[1] = zero.newInstance(northEast.getEntry().getLongitude());
84          final T[] yVal = MathArrays.buildArray(field, 2);
85          yVal[0] = zero.newInstance(southWest.getEntry().getLatitude());
86          yVal[1] = zero.newInstance(northEast.getEntry().getLatitude());
87  
88          // evaluate grid points at specified day
89          final T[][] fval = MathArrays.buildArray(field, 2, 2);
90          fval[0][0] = gridGetter.apply(southWest);
91          fval[0][1] = gridGetter.apply(northWest);
92          fval[1][0] = gridGetter.apply(southEast);
93          fval[1][1] = gridGetter.apply(northEast);
94  
95          // perform interpolation in the grid
96          return new FieldBilinearInterpolatingFunction<>(xVal, yVal, fval).value(longitude, latitude);
97  
98      }
99  
100 }