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 namespace meshkernel
38 {
41  {
42  public:
45  explicit Mesh2DToCurvilinear(Mesh2D& mesh);
46 
50  std::unique_ptr<CurvilinearGrid> Compute(const Point& point);
51 
52  private:
55  class MatrixWithNegativeIndices
56  {
57  public:
62  int getValue(int j, int i) const
63  {
64  const auto jIndex = j - m_minJ;
65  const auto iIndex = i - m_minI;
66  const auto value = m_matrix(jIndex, iIndex);
67  return value;
68  }
73  void setValue(int j, int i, int value)
74  {
75  const auto jIndex = j - m_minJ;
76  const auto iIndex = i - m_minI;
77  m_matrix(jIndex, iIndex) = value;
78  }
79 
84  bool IsValid(int j, int i) const
85  {
86  const auto jIndex = j - m_minJ;
87  const auto iIndex = i - m_minI;
88  return m_matrix(jIndex, iIndex) != constants::missing::intValue;
89  }
90 
93  [[nodiscard]] int rows() const
94  {
95  return static_cast<int>(m_matrix.rows());
96  }
97 
100  [[nodiscard]] int cols() const
101  {
102  return static_cast<int>(m_matrix.cols());
103  }
104 
107  [[nodiscard]] int minCol() const
108  {
109  return m_minI;
110  }
111 
114  [[nodiscard]] int maxCol() const
115  {
116  return m_maxI;
117  }
118 
121  [[nodiscard]] int minRow() const
122  {
123  return m_minJ;
124  }
125 
128  [[nodiscard]] int maxRow() const
129  {
130  return m_maxJ;
131  }
132 
138  void resize(int minJ, int minI, int maxJ, int maxI)
139  {
140  // Determine the size change needed
141  const int extraRowsTop = std::max(m_minJ - minJ, 0);
142  const int extraRowsBottom = std::max(maxJ - m_maxJ, 0);
143  const int extraColsLeft = std::max(m_minI - minI, 0);
144  const int extraColsRight = std::max(maxI - m_maxI, 0);
145 
146  if (extraRowsTop == 0 && extraRowsBottom == 0 && extraColsLeft == 0 && extraColsRight == 0)
147  {
148  return;
149  }
150 
151  // Create new matrix with the new size and initialize to missing value
152  const auto newRows = static_cast<int>(m_matrix.rows()) + extraRowsTop + extraRowsBottom;
153  const auto newCols = static_cast<int>(m_matrix.cols()) + extraColsLeft + extraColsRight;
154  lin_alg::Matrix<int> newMatrix(newRows, newCols);
155  newMatrix.setConstant(constants::missing::intValue);
156 
157  // Copy the existing matrix into the new one
158  newMatrix.block(extraRowsTop, extraColsLeft, m_matrix.rows(), m_matrix.cols()) = m_matrix;
159 
160  // Update matrix and bounds
161  m_matrix.swap(newMatrix);
162  m_minI = std::min(m_minI, minI);
163  m_minJ = std::min(m_minJ, minJ);
164  m_maxI = std::max(m_maxI, maxI);
165  m_maxJ = std::max(m_maxJ, maxJ);
166  }
167 
168  private:
169  lin_alg::Matrix<int> m_matrix = lin_alg::Matrix<int>(1, 1);
170  int m_minI = 0;
171  int m_minJ = 0;
172  int m_maxI = 0;
173  int m_maxJ = 0;
174  };
175 
177  [[nodiscard]] Eigen::Matrix<UInt, 2, 2> ComputeLocalNodeMapping(UInt face) const;
178 
180  [[nodiscard]] UInt ComputeNeighbouringFaceNodes(const UInt face,
181  const Eigen::Matrix<UInt, 2, 2>& localNodeMapping,
182  const UInt d,
183  const std::vector<bool>& visitedFace);
184 
186  [[nodiscard]] bool CheckGridLine(const UInt validNode, const UInt candidateNode) const;
187 
189  bool IsConnectionValid(const UInt candidateNode, const int iCandidate, const int jCandidate);
190 
192  [[nodiscard]] lin_alg::Matrix<Point> ComputeCurvilinearMatrix();
193 
194  Mesh2D& m_mesh;
195  std::vector<int> m_i;
196  std::vector<int> m_j;
197 
198  const std::array<std::array<int, 2>, 4> m_nodeFrom = {{{0, 0},
199  {0, 0},
200  {1, 0},
201  {1, 1}}};
202 
203  const std::array<std::array<int, 2>, 4> m_nodeTo = {{{0, 1},
204  {1, 0},
205  {1, 1},
206  {0, 1}}};
207 
208  const std::array<std::array<int, 2>, 4> m_directionsDeltas = {{{-1, 0},
209  {0, -1},
210  {1, 0},
211  {0, 1}}};
212 
213  const int n_maxNumRowsColumns = 1000000;
214 
215  MatrixWithNegativeIndices m_mapping;
216  };
217 
218 } // 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::Mesh2DToCurvilinear::Mesh2DToCurvilinear
Mesh2DToCurvilinear(Mesh2D &mesh)
Constructor.
meshkernel::UInt
std::uint32_t UInt
Integer type used when indexing mesh graph entities.
Definition: Definitions.hpp:38
meshkernel::Mesh2DToCurvilinear::Compute
std::unique_ptr< CurvilinearGrid > Compute(const Point &point)
Computes the curvilinear grid starting from a specific point.
meshkernel::Mesh2DToCurvilinear
Construct a curvilinear grid from an unstructured mesh.
Definition: Mesh2DToCurvilinear.hpp:40