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,
75 std::span<T const> values);
84 [[nodiscard]]
double Interpolation(
const Point& point)
const;
89 [[nodiscard]]
double GetFractionalNumberOfColumns(
const Point& point)
const;
94 [[nodiscard]]
double GetFractionalNumberOfRows(
const Point& point)
const;
98 [[nodiscard]]
double GetGriddedValue(
UInt columnIndex,
UInt rowIndex)
const;
104 double m_cellSize = 0.0;
106 std::span<double const> m_xCoordinates;
107 std::span<double const> m_yCoordinates;
108 std::span<T const> m_values;
109 bool m_isCellSizeConstant;
112 template <InterpolatableType T>
118 std::span<T const> values)
120 m_numXCoord(numXCoord),
121 m_numYCoord(numYCoord),
123 m_cellSize(cellSize),
125 m_isCellSizeConstant{
true}
129 template <InterpolatableType T>
131 std::span<double const> xCoordinates,
132 std::span<double const> yCoordinates,
133 std::span<T const> values)
135 m_numXCoord(static_cast<
UInt>(xCoordinates.size())),
136 m_numYCoord(static_cast<
UInt>(yCoordinates.size())),
137 m_xCoordinates(xCoordinates),
138 m_yCoordinates(yCoordinates),
140 m_isCellSizeConstant(
false)
144 template <InterpolatableType T>
147 const auto numNodes = m_mesh.GetNumNodes();
148 const auto numEdges = m_mesh.GetNumEdges();
149 const auto numFaces = m_mesh.GetNumFaces();
151 m_nodeResults.resize(numNodes);
152 std::ranges::fill(m_nodeResults, constants::missing::doubleValue);
153 for (
UInt n = 0; n < numNodes; ++n)
155 const auto node = m_mesh.Node(n);
156 m_nodeResults[n] = Interpolation(node);
159 m_edgeResults.resize(numEdges);
160 std::ranges::fill(m_edgeResults, constants::missing::doubleValue);
161 for (
UInt e = 0; e < numEdges; ++e)
163 const auto& [first, second] = m_mesh.GetEdge(e);
164 m_edgeResults[e] = 0.5 * (m_nodeResults[first] + m_nodeResults[second]);
167 m_faceResults.resize(numFaces, constants::missing::doubleValue);
168 std::ranges::fill(m_faceResults, constants::missing::doubleValue);
169 for (
UInt f = 0; f < numFaces; ++f)
171 m_faceResults[f] = Interpolation(m_mesh.m_facesMassCenters[f]);
175 template <InterpolatableType T>
179 double fractionalColumnIndex = GetFractionalNumberOfColumns(point);
180 double fractionalRowIndex = GetFractionalNumberOfRows(point);
182 double columnIndexTmp;
183 fractionalColumnIndex = std::modf(fractionalColumnIndex, &columnIndexTmp);
186 fractionalRowIndex = std::modf(fractionalRowIndex, &rowIndexTmp);
188 if (columnIndexTmp < 0 || rowIndexTmp < 0)
190 return constants::missing::doubleValue;
193 UInt const columnIndex =
static_cast<UInt>(columnIndexTmp);
194 UInt const rowIndex =
static_cast<UInt>(rowIndexTmp);
196 if (columnIndex + 1 >= m_numXCoord || rowIndex + 1 >= m_numYCoord)
198 return constants::missing::doubleValue;
201 const auto result = fractionalColumnIndex * fractionalRowIndex * GetGriddedValue(columnIndex + 1, rowIndex + 1) +
202 (1.0 - fractionalColumnIndex) * fractionalRowIndex * GetGriddedValue(columnIndex, rowIndex + 1) +
203 (1.0 - fractionalColumnIndex) * (1.0 - fractionalRowIndex) * GetGriddedValue(columnIndex, rowIndex) +
204 fractionalColumnIndex * (1.0 - fractionalRowIndex) * GetGriddedValue(columnIndex + 1, rowIndex);
208 template <InterpolatableType T>
209 double BilinearInterpolationOnGriddedSamples<T>::GetFractionalNumberOfColumns(
const Point& point)
const
211 if (m_isCellSizeConstant)
213 return (point.x - m_origin.x) / m_cellSize;
215 double result = constants::missing::doubleValue;
216 if (m_xCoordinates.size() < 2)
220 for (
UInt i = 0; i < m_xCoordinates.size() - 1; ++i)
223 if (point.x >= m_xCoordinates[i] && point.x < m_xCoordinates[i + 1])
225 const double dx = m_xCoordinates[i + 1] - m_xCoordinates[i];
226 result =
static_cast<double>(i) + (point.x - m_xCoordinates[i]) / dx;
233 template <InterpolatableType T>
234 double BilinearInterpolationOnGriddedSamples<T>::GetFractionalNumberOfRows(
const Point& point)
const
236 if (m_isCellSizeConstant)
238 return (point.y - m_origin.y) / m_cellSize;
241 double result = constants::missing::doubleValue;
242 if (m_yCoordinates.size() < 2)
247 for (
UInt i = 0; i < m_yCoordinates.size() - 1; ++i)
250 if (point.y >= m_yCoordinates[i] && point.y < m_yCoordinates[i + 1])
252 const double dy = m_yCoordinates[i + 1] - m_yCoordinates[i];
253 result =
static_cast<double>(i) + (point.y - m_yCoordinates[i]) / dy;
260 template <InterpolatableType T>
261 double BilinearInterpolationOnGriddedSamples<T>::GetGriddedValue(
UInt columnIndex,
UInt rowIndex)
const
263 const auto index = rowIndex * m_numXCoord + columnIndex;
264 return static_cast<double>(m_values[index]);