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);
154 m_nodeResults[n] = Interpolation(node);
157 m_edgeResults.resize(numEdges);
158 std::ranges::fill(m_edgeResults, constants::missing::doubleValue);
159 for (
UInt e = 0; e < numEdges; ++e)
161 const auto& [first, second] = m_mesh.GetEdge(e);
162 m_edgeResults[e] = 0.5 * (m_nodeResults[first] + m_nodeResults[second]);
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)
169 m_faceResults[f] = Interpolation(m_mesh.m_facesMassCenters[f]);
173 template <InterpolatableType T>
177 double fractionalColumnIndex = GetFractionalNumberOfColumns(point);
178 double fractionalRowIndex = GetFractionalNumberOfRows(point);
180 double columnIndexTmp;
181 fractionalColumnIndex = std::modf(fractionalColumnIndex, &columnIndexTmp);
184 fractionalRowIndex = std::modf(fractionalRowIndex, &rowIndexTmp);
186 if (columnIndexTmp < 0 || rowIndexTmp < 0)
188 return constants::missing::doubleValue;
191 UInt const columnIndex =
static_cast<UInt>(columnIndexTmp);
192 UInt const rowIndex =
static_cast<UInt>(rowIndexTmp);
194 if (columnIndex + 1 >= m_numXCoord || rowIndex + 1 >= m_numYCoord)
196 return constants::missing::doubleValue;
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);
206 template <InterpolatableType T>
207 double BilinearInterpolationOnGriddedSamples<T>::GetFractionalNumberOfColumns(
const Point& point)
const
209 if (m_isCellSizeConstant)
211 return (point.x - m_origin.x) / m_cellSize;
213 double result = constants::missing::doubleValue;
214 if (m_xCoordinates.size() < 2)
218 for (
UInt i = 0; i < m_xCoordinates.size() - 1; ++i)
221 if (point.x >= m_xCoordinates[i] && point.x < m_xCoordinates[i + 1])
223 const double dx = m_xCoordinates[i + 1] - m_xCoordinates[i];
224 result =
static_cast<double>(i) + (point.x - m_xCoordinates[i]) / dx;
231 template <InterpolatableType T>
232 double BilinearInterpolationOnGriddedSamples<T>::GetFractionalNumberOfRows(
const Point& point)
const
234 if (m_isCellSizeConstant)
236 return (point.y - m_origin.y) / m_cellSize;
239 double result = constants::missing::doubleValue;
240 if (m_yCoordinates.size() < 2)
245 for (
UInt i = 0; i < m_yCoordinates.size() - 1; ++i)
248 if (point.y >= m_yCoordinates[i] && point.y < m_yCoordinates[i + 1])
250 const double dy = m_yCoordinates[i + 1] - m_yCoordinates[i];
251 result =
static_cast<double>(i) + (point.y - m_yCoordinates[i]) / dy;
258 template <InterpolatableType T>
259 double BilinearInterpolationOnGriddedSamples<T>::GetGriddedValue(
UInt columnIndex,
UInt rowIndex)
const
261 const auto index = rowIndex * m_numXCoord + columnIndex;
262 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: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