MeshKernel
Mesh2DToCurvilinear.hpp
1 //---- GPL ---------------------------------------------------------------------
2 //
3 // Copyright (C) Stichting Deltares, 2011-2023.
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 #include <memory>
30 
31 #include "MeshKernel/CurvilinearGrid/CurvilinearGrid.hpp"
32 #include "MeshKernel/Definitions.hpp"
33 #include "MeshKernel/Mesh2D.hpp"
34 #include "MeshKernel/Point.hpp"
35 #include "Utilities/LinearAlgebra.hpp"
36 
37 using namespace meshkernel::constants;
38 
39 namespace meshkernel
40 {
43  {
44  public:
47  explicit Mesh2DToCurvilinear(Mesh2D& mesh);
48 
52  std::unique_ptr<CurvilinearGrid> Compute(const Point& point);
53 
54  private:
57  class MatrixWithNegativeIndices
58  {
59  public:
64  int getValue(int j, int i) const
65  {
66  const auto jIndex = j - m_minJ;
67  const auto iIndex = i - m_minI;
68  const auto value = m_matrix(jIndex, iIndex);
69  return value;
70  }
75  void setValue(int j, int i, int value)
76  {
77  const auto jIndex = j - m_minJ;
78  const auto iIndex = i - m_minI;
79  m_matrix(jIndex, iIndex) = value;
80  }
81 
86  bool IsValid(int j, int i) const
87  {
88  const auto jIndex = j - m_minJ;
89  const auto iIndex = i - m_minI;
90  return m_matrix(jIndex, iIndex) != missing::intValue;
91  }
92 
95  [[nodiscard]] int rows() const
96  {
97  return static_cast<int>(m_matrix.rows());
98  }
99 
102  [[nodiscard]] int cols() const
103  {
104  return static_cast<int>(m_matrix.cols());
105  }
106 
109  [[nodiscard]] int minCol() const
110  {
111  return m_minI;
112  }
113 
116  [[nodiscard]] int maxCol() const
117  {
118  return m_maxI;
119  }
120 
123  [[nodiscard]] int minRow() const
124  {
125  return m_minJ;
126  }
127 
130  [[nodiscard]] int maxRow() const
131  {
132  return m_maxJ;
133  }
134 
140  void resize(int minJ, int minI, int maxJ, int maxI)
141  {
142  // Determine the size change needed
143  const int extraRowsTop = std::max(m_minJ - minJ, 0);
144  const int extraRowsBottom = std::max(maxJ - m_maxJ, 0);
145  const int extraColsLeft = std::max(m_minI - minI, 0);
146  const int extraColsRight = std::max(maxI - m_maxI, 0);
147 
148  if (extraRowsTop == 0 && extraRowsBottom == 0 && extraColsLeft == 0 && extraColsRight == 0)
149  {
150  return;
151  }
152 
153  // Create new matrix with the new size and initialize to missing value
154  const auto newRows = static_cast<int>(m_matrix.rows()) + extraRowsTop + extraRowsBottom;
155  const auto newCols = static_cast<int>(m_matrix.cols()) + extraColsLeft + extraColsRight;
156  lin_alg::Matrix<int> newMatrix(newRows, newCols);
157  newMatrix.setConstant(missing::intValue);
158 
159  // Copy the existing matrix into the new one
160  newMatrix.block(extraRowsTop, extraColsLeft, m_matrix.rows(), m_matrix.cols()) = m_matrix;
161 
162  // Update matrix and bounds
163  m_matrix.swap(newMatrix);
164  m_minI = std::min(m_minI, minI);
165  m_minJ = std::min(m_minJ, minJ);
166  m_maxI = std::max(m_maxI, maxI);
167  m_maxJ = std::max(m_maxJ, maxJ);
168  }
169 
170  private:
171  lin_alg::Matrix<int> m_matrix = lin_alg::Matrix<int>(1, 1);
172  int m_minI = 0;
173  int m_minJ = 0;
174  int m_maxI = 0;
175  int m_maxJ = 0;
176  };
177 
179  [[nodiscard]] Eigen::Matrix<UInt, 2, 2> ComputeLocalNodeMapping(UInt face) const;
180 
182  [[nodiscard]] UInt ComputeNeighbouringFaceNodes(const UInt face,
183  const Eigen::Matrix<UInt, 2, 2>& localNodeMapping,
184  const UInt d,
185  const std::vector<bool>& visitedFace);
186 
188  [[nodiscard]] bool CheckGridLine(const UInt validNode, const UInt candidateNode) const;
189 
191  bool IsConnectionValid(const UInt candidateNode, const int iCandidate, const int jCandidate);
192 
194  [[nodiscard]] lin_alg::Matrix<Point> ComputeCurvilinearMatrix();
195 
196  Mesh2D& m_mesh;
197  std::vector<int> m_i;
198  std::vector<int> m_j;
199 
200  const std::array<std::array<int, 2>, 4> m_nodeFrom = {{{0, 0},
201  {0, 0},
202  {1, 0},
203  {1, 1}}};
204 
205  const std::array<std::array<int, 2>, 4> m_nodeTo = {{{0, 1},
206  {1, 0},
207  {1, 1},
208  {0, 1}}};
209 
210  const std::array<std::array<int, 2>, 4> m_directionsDeltas = {{{-1, 0},
211  {0, -1},
212  {1, 0},
213  {0, 1}}};
214 
215  const int n_maxNumRowsColumns = 1000000;
216 
217  MatrixWithNegativeIndices m_mapping;
218  };
219 
220 } // namespace meshkernel
meshkernel::Mesh2D
A class derived from Mesh, which describes unstructures 2d meshes.
Definition: Mesh2D.hpp:55
meshkernel::Point
A struct describing a point in a two-dimensional space.
Definition: Point.hpp:40
meshkernel
Contains the logic of the C++ static library.
Definition: AveragingInterpolation.hpp:36
meshkernel::UInt
std::uint32_t UInt
Integer type used when indexing mesh graph entities.
Definition: Definitions.hpp:38
meshkernel::Mesh2DToCurvilinear
Construct a curvilinear grid from an unstructured mesh.
Definition: Mesh2DToCurvilinear.hpp:42