30#include <MeshKernel/Mesh2D.hpp>
31#include <MeshKernel/MeshInterpolation.hpp>
42 std::same_as<T, float> ||
43 std::same_as<T, double> ||
47 template <InterpolatableType T>
63 std::span<T const> values);
71 std::span<double const> xCoordinates,
72 std::span<double const> yCoordinates,
73 std::span<T const> values);
82 [[nodiscard]]
double Interpolation(
const Point& point)
const;
87 [[nodiscard]]
double GetFractionalNumberOfColumns(
const Point& point)
const;
92 [[nodiscard]]
double GetFractionalNumberOfRows(
const Point& point)
const;
96 [[nodiscard]]
double GetGriddedValue(
UInt columnIndex,
UInt rowIndex)
const;
102 double m_cellSize = 0.0;
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;
110 template <InterpolatableType T>
116 std::span<T const> values)
118 m_numXCoord(numXCoord),
119 m_numYCoord(numYCoord),
121 m_cellSize(cellSize),
123 m_isCellSizeConstant{true}
127 template <InterpolatableType T>
129 std::span<double const> xCoordinates,
130 std::span<double const> yCoordinates,
131 std::span<T const> values)
133 m_numXCoord(static_cast<
UInt>(xCoordinates.size())),
134 m_numYCoord(static_cast<
UInt>(yCoordinates.size())),
135 m_xCoordinates(xCoordinates),
136 m_yCoordinates(yCoordinates),
138 m_isCellSizeConstant(false)
142 template <InterpolatableType T>
145 const auto numNodes = m_mesh.GetNumNodes();
146 const auto numEdges = m_mesh.GetNumEdges();
147 const auto numFaces = m_mesh.GetNumFaces();
149 m_nodeResults.resize(numNodes);
150 std::ranges::fill(m_nodeResults, constants::missing::doubleValue);
151 for (
UInt n = 0; n < numNodes; ++n)
153 const auto node = m_mesh.Node(n);
157 m_nodeResults[n] = Interpolation(node);
161 m_edgeResults.resize(numEdges);
162 std::ranges::fill(m_edgeResults, constants::missing::doubleValue);
163 for (
UInt e = 0; e < numEdges; ++e)
165 const auto& [first, second] = m_mesh.GetEdge(e);
167 if (first != constants::missing::uintValue && second != constants::missing::uintValue)
169 m_edgeResults[e] = 0.5 * (m_nodeResults[first] + m_nodeResults[second]);
173 m_faceResults.resize(numFaces, constants::missing::doubleValue);
174 std::ranges::fill(m_faceResults, constants::missing::doubleValue);
175 for (
UInt f = 0; f < numFaces; ++f)
177 if (m_mesh.m_facesMassCenters[f].IsValid())
179 m_faceResults[f] = Interpolation(m_mesh.m_facesMassCenters[f]);
184 template <InterpolatableType T>
188 double fractionalColumnIndex = GetFractionalNumberOfColumns(point);
189 double fractionalRowIndex = GetFractionalNumberOfRows(point);
191 double columnIndexTmp;
192 fractionalColumnIndex = std::modf(fractionalColumnIndex, &columnIndexTmp);
195 fractionalRowIndex = std::modf(fractionalRowIndex, &rowIndexTmp);
197 if (columnIndexTmp < 0 || rowIndexTmp < 0)
199 return constants::missing::doubleValue;
202 UInt const columnIndex =
static_cast<UInt>(columnIndexTmp);
203 UInt const rowIndex =
static_cast<UInt>(rowIndexTmp);
205 if (columnIndex + 1 >= m_numXCoord || rowIndex + 1 >= m_numYCoord)
207 return constants::missing::doubleValue;
210 const auto result = fractionalColumnIndex * fractionalRowIndex * GetGriddedValue(columnIndex + 1, rowIndex + 1) +
211 (1.0 - fractionalColumnIndex) * fractionalRowIndex * GetGriddedValue(columnIndex, rowIndex + 1) +
212 (1.0 - fractionalColumnIndex) * (1.0 - fractionalRowIndex) * GetGriddedValue(columnIndex, rowIndex) +
213 fractionalColumnIndex * (1.0 - fractionalRowIndex) * GetGriddedValue(columnIndex + 1, rowIndex);
217 template <InterpolatableType T>
218 double BilinearInterpolationOnGriddedSamples<T>::GetFractionalNumberOfColumns(
const Point& point)
const
220 if (m_isCellSizeConstant)
222 return (point.x - m_origin.x) / m_cellSize;
224 double result = constants::missing::doubleValue;
225 if (m_xCoordinates.size() < 2)
229 for (
UInt i = 0; i < m_xCoordinates.size() - 1; ++i)
232 if (point.x >= m_xCoordinates[i] && point.x < m_xCoordinates[i + 1])
234 const double dx = m_xCoordinates[i + 1] - m_xCoordinates[i];
235 result =
static_cast<double>(i) + (point.x - m_xCoordinates[i]) / dx;
242 template <InterpolatableType T>
243 double BilinearInterpolationOnGriddedSamples<T>::GetFractionalNumberOfRows(
const Point& point)
const
245 if (m_isCellSizeConstant)
247 return (point.y - m_origin.y) / m_cellSize;
250 double result = constants::missing::doubleValue;
251 if (m_yCoordinates.size() < 2)
256 for (
UInt i = 0; i < m_yCoordinates.size() - 1; ++i)
259 if (point.y >= m_yCoordinates[i] && point.y < m_yCoordinates[i + 1])
261 const double dy = m_yCoordinates[i + 1] - m_yCoordinates[i];
262 result =
static_cast<double>(i) + (point.y - m_yCoordinates[i]) / dy;
269 template <InterpolatableType T>
270 double BilinearInterpolationOnGriddedSamples<T>::GetGriddedValue(
UInt columnIndex,
UInt rowIndex)
const
272 const auto index = rowIndex * m_numXCoord + columnIndex;
273 return static_cast<double>(m_values[index]);
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:59
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