Loading [MathJax]/extensions/tex2jax.js
MeshKernel
All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Pages Concepts
BilinearInterpolationOnGriddedSamples.hpp
1//---- GPL ---------------------------------------------------------------------
2//
3// Copyright (C) Stichting Deltares, 2011-2021.
4//
5// This program is free software: you can redistribute it and/or modify
6// it under the terms of the GNU General Public License as published by
7// the Free Software Foundation version 3.
8//
9// This program is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with this program. If not, see <http://www.gnu.org/licenses/>.
16//
17// contact: delft3d.support@deltares.nl
18// Stichting Deltares
19// P.O. Box 177
20// 2600 MH Delft, The Netherlands
21//
22// All indications and logos of, and references to, "Delft3D" and "Deltares"
23// are registered trademarks of Stichting Deltares, and remain the property of
24// Stichting Deltares. All rights reserved.
25//
26//------------------------------------------------------------------------------
27
28#pragma once
29
30#include <MeshKernel/Mesh2D.hpp>
31#include <MeshKernel/MeshInterpolation.hpp>
32
33#include <concepts>
34#include <span>
35
36namespace meshkernel
37{
38
40 template <typename T>
41 concept InterpolatableType = std::same_as<T, short> ||
42 std::same_as<T, float> ||
43 std::same_as<T, double> ||
44 std::same_as<T, int>;
45
47 template <InterpolatableType T>
49 {
50 public:
59 UInt numXCoord,
60 UInt numYCoord,
61 const Point& origin,
62 double cellSize,
63 std::span<T const> values);
64
71 std::span<double const> xCoordinates,
72 std::span<double const> yCoordinates,
73 std::span<T const> values);
74
76 void Compute() override;
77
78 private:
82 [[nodiscard]] double Interpolation(const Point& point) const;
83
87 [[nodiscard]] double GetFractionalNumberOfColumns(const Point& point) const;
88
92 [[nodiscard]] double GetFractionalNumberOfRows(const Point& point) const;
93
96 [[nodiscard]] double GetGriddedValue(UInt columnIndex, UInt rowIndex) const;
97
98 const Mesh2D& m_mesh;
99 UInt m_numXCoord;
100 UInt m_numYCoord;
101 Point m_origin;
102 double m_cellSize = 0.0;
103
104 std::span<double const> m_xCoordinates;
105 std::span<double const> m_yCoordinates;
106 std::span<T const> m_values;
107 bool m_isCellSizeConstant;
108 };
109
110 template <InterpolatableType T>
112 UInt numXCoord,
113 UInt numYCoord,
114 const Point& origin,
115 double cellSize,
116 std::span<T const> values)
117 : m_mesh(mesh),
118 m_numXCoord(numXCoord),
119 m_numYCoord(numYCoord),
120 m_origin(origin),
121 m_cellSize(cellSize),
122 m_values(values),
123 m_isCellSizeConstant{true}
124 {
125 }
126
127 template <InterpolatableType T>
129 std::span<double const> xCoordinates,
130 std::span<double const> yCoordinates,
131 std::span<T const> values)
132 : m_mesh(mesh),
133 m_numXCoord(static_cast<UInt>(xCoordinates.size())),
134 m_numYCoord(static_cast<UInt>(yCoordinates.size())),
135 m_xCoordinates(xCoordinates),
136 m_yCoordinates(yCoordinates),
137 m_values{values},
138 m_isCellSizeConstant(false)
139 {
140 }
141
142 template <InterpolatableType T>
144 {
145 const auto numNodes = m_mesh.GetNumNodes();
146 const auto numEdges = m_mesh.GetNumEdges();
147 const auto numFaces = m_mesh.GetNumFaces();
148
149 m_nodeResults.resize(numNodes);
150 std::ranges::fill(m_nodeResults, constants::missing::doubleValue);
151 for (UInt n = 0; n < numNodes; ++n)
152 {
153 const auto node = m_mesh.Node(n);
154 m_nodeResults[n] = Interpolation(node);
155 }
156
157 m_edgeResults.resize(numEdges);
158 std::ranges::fill(m_edgeResults, constants::missing::doubleValue);
159 for (UInt e = 0; e < numEdges; ++e)
160 {
161 const auto& [first, second] = m_mesh.GetEdge(e);
162 m_edgeResults[e] = 0.5 * (m_nodeResults[first] + m_nodeResults[second]);
163 }
164
165 m_faceResults.resize(numFaces, constants::missing::doubleValue);
166 std::ranges::fill(m_faceResults, constants::missing::doubleValue);
167 for (UInt f = 0; f < numFaces; ++f)
168 {
169 m_faceResults[f] = Interpolation(m_mesh.m_facesMassCenters[f]);
170 }
171 }
172
173 template <InterpolatableType T>
175 {
176
177 double fractionalColumnIndex = GetFractionalNumberOfColumns(point);
178 double fractionalRowIndex = GetFractionalNumberOfRows(point);
179
180 double columnIndexTmp;
181 fractionalColumnIndex = std::modf(fractionalColumnIndex, &columnIndexTmp);
182
183 double rowIndexTmp;
184 fractionalRowIndex = std::modf(fractionalRowIndex, &rowIndexTmp);
185
186 if (columnIndexTmp < 0 || rowIndexTmp < 0)
187 {
188 return constants::missing::doubleValue;
189 }
190
191 UInt const columnIndex = static_cast<UInt>(columnIndexTmp);
192 UInt const rowIndex = static_cast<UInt>(rowIndexTmp);
193
194 if (columnIndex + 1 >= m_numXCoord || rowIndex + 1 >= m_numYCoord)
195 {
196 return constants::missing::doubleValue;
197 }
198
199 const auto result = fractionalColumnIndex * fractionalRowIndex * GetGriddedValue(columnIndex + 1, rowIndex + 1) +
200 (1.0 - fractionalColumnIndex) * fractionalRowIndex * GetGriddedValue(columnIndex, rowIndex + 1) +
201 (1.0 - fractionalColumnIndex) * (1.0 - fractionalRowIndex) * GetGriddedValue(columnIndex, rowIndex) +
202 fractionalColumnIndex * (1.0 - fractionalRowIndex) * GetGriddedValue(columnIndex + 1, rowIndex);
203 return result;
204 }
205
206 template <InterpolatableType T>
207 double BilinearInterpolationOnGriddedSamples<T>::GetFractionalNumberOfColumns(const Point& point) const
208 {
209 if (m_isCellSizeConstant)
210 {
211 return (point.x - m_origin.x) / m_cellSize;
212 }
213 double result = constants::missing::doubleValue;
214 if (m_xCoordinates.size() < 2)
215 {
216 return result;
217 }
218 for (UInt i = 0; i < m_xCoordinates.size() - 1; ++i)
219 {
220
221 if (point.x >= m_xCoordinates[i] && point.x < m_xCoordinates[i + 1])
222 {
223 const double dx = m_xCoordinates[i + 1] - m_xCoordinates[i];
224 result = static_cast<double>(i) + (point.x - m_xCoordinates[i]) / dx;
225 break;
226 }
227 }
228 return result;
229 }
230
231 template <InterpolatableType T>
232 double BilinearInterpolationOnGriddedSamples<T>::GetFractionalNumberOfRows(const Point& point) const
233 {
234 if (m_isCellSizeConstant)
235 {
236 return (point.y - m_origin.y) / m_cellSize;
237 }
238
239 double result = constants::missing::doubleValue;
240 if (m_yCoordinates.size() < 2)
241 {
242 return result;
243 }
244
245 for (UInt i = 0; i < m_yCoordinates.size() - 1; ++i)
246 {
247
248 if (point.y >= m_yCoordinates[i] && point.y < m_yCoordinates[i + 1])
249 {
250 const double dy = m_yCoordinates[i + 1] - m_yCoordinates[i];
251 result = static_cast<double>(i) + (point.y - m_yCoordinates[i]) / dy;
252 break;
253 }
254 }
255 return result;
256 }
257
258 template <InterpolatableType T>
259 double BilinearInterpolationOnGriddedSamples<T>::GetGriddedValue(UInt columnIndex, UInt rowIndex) const
260 {
261 const auto index = rowIndex * m_numXCoord + columnIndex;
262 return static_cast<double>(m_values[index]);
263 }
264
265} // namespace meshkernel
A class for performing bilinear interpolation on gridded samples.
Definition BilinearInterpolationOnGriddedSamples.hpp:49
void Compute() override
Compute interpolation.
Definition BilinearInterpolationOnGriddedSamples.hpp:143
BilinearInterpolationOnGriddedSamples(const Mesh2D &mesh, UInt numXCoord, UInt numYCoord, const Point &origin, double cellSize, std::span< T const > values)
Bilinear interpolation with constant cell size (faster because no linear search is performed for each...
Definition BilinearInterpolationOnGriddedSamples.hpp:111
A class derived from Mesh, which describes unstructures 2d meshes.
Definition Mesh2D.hpp:58
Interface for interpolation methods.
Definition MeshInterpolation.hpp:43
A struct describing a point in a two-dimensional space.
Definition Point.hpp:41
Defines the iterpolatable data types.
Definition BilinearInterpolationOnGriddedSamples.hpp:41
Contains the logic of the C++ static library.
Definition AveragingInterpolation.hpp:37
std::uint32_t UInt
Integer type used when indexing mesh graph entities.
Definition Definitions.hpp:39