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 }