MeshKernel
Smoother.hpp
1 //---- GPL ---------------------------------------------------------------------
2 //
3 // Copyright (C) Stichting Deltares, 2011-2021.
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 
30 #include "MeshKernel/Constants.hpp"
31 
32 namespace meshkernel
33 {
34  class Mesh2D;
35 
39  class Smoother
40  {
41 
42  public:
45  explicit Smoother(const Mesh2D& mesh);
46 
48  void Compute();
49 
54  [[nodiscard]] auto GetWeight(UInt node, int connectedNode) const
55  {
56  return m_weights[node][connectedNode];
57  }
58 
63  [[nodiscard]] auto GetConnectedNodeIndex(UInt node, int connectedNode) const
64  {
65  return m_connectedNodes[node][connectedNode];
66  }
67 
71  [[nodiscard]] auto GetNumConnectedNodes(UInt node) const
72  {
73  return m_numConnectedNodes[node];
74  }
75 
76  private:
78  struct InternalAngleData
79  {
80  UInt numSquaredTriangles = 0;
81  UInt numTriangles = 0;
82  double phiSquaredTriangles = 0.0;
83  double phiQuads = 0.0;
84  double phiTriangles = 0.0;
85  double phiTot = 0.0;
86  };
87 
89  void ComputeInternalAngle(const UInt currentNode,
90  const UInt numSharedFaces,
91  const std::vector<double>& thetaSquare,
92  const std::vector<bool>& isSquareFace,
93  InternalAngleData& internalAngleData,
94  UInt& numNonStencilQuad);
95 
97  void UpdateThetaForInteriorFaces(const UInt numSharedFaces, std::vector<double>& thetaSquare);
98 
100  void UpdateXiEtaForSharedFace(const UInt currentNode,
101  const UInt currentFace,
102  const UInt numFaceNodes,
103  const double dPhi,
104  const double phi0);
105 
107  void ComputeOptimalAngleForSharedFaces(const UInt currentNode,
108  const UInt numSharedFaces,
109  const std::vector<double>& thetaSquare,
110  const std::vector<bool>& isSquareFace,
111  const double mu,
112  const double muSquaredTriangles,
113  const double muTriangles);
114 
117  void Initialize();
118 
120  void ComputeTopologies();
121 
123  void ComputeOperators();
124 
128  bool ComputeCoordinates();
129 
131  void ComputeWeights();
132 
134  std::tuple<double, double> ComputeOperatorsForBoundaryNode(const UInt f, const UInt faceLeftIndex, const UInt currentTopology);
135 
137  std::tuple<double, double, double, double> ComputeOperatorsForInteriorNode(const UInt f,
138  const UInt edgeIndex,
139  const UInt faceLeftIndex,
140  const UInt faceRightIndex,
141  const UInt currentTopology);
142 
144  void ComputeNodeEdgeDerivative(const UInt f,
145  const UInt edgeIndex,
146  const UInt currentTopology,
147  const UInt faceLeftIndex,
148  const UInt faceRightIndex,
149  const double facxiL,
150  const double facetaL,
151  const double facxiR,
152  const double facetaR);
153 
156  void ComputeOperatorsNode(UInt currentNode);
157 
160  void NodeAdministration(UInt currentNode);
161 
164  void ComputeNodeXiEta(UInt currentNode);
165 
172  [[nodiscard]] double OptimalEdgeAngle(UInt numFaceNodes,
173  double theta1 = -1.0,
174  double theta2 = -1.0,
175  bool isBoundaryEdge = false) const;
176 
179  void AllocateNodeOperators(UInt topologyIndex);
180 
183  void SaveNodeTopologyIfNeeded(UInt currentNode);
184 
188  void ComputeJacobian(UInt currentNode, std::vector<double>& J) const;
189 
191  void ComputeCellCircumcentreCoefficients(const UInt currentNode, const UInt currentTopology);
192 
194  void ComputeNodeToNodeGradients(const UInt currentNode, const UInt currentTopology);
195 
197  void ComputeLaplacianSmootherWeights(const UInt currentNode, const UInt currentTopology);
198 
199  // The mesh to smooth
200  const Mesh2D& m_mesh;
201 
202  // Smoother weights
203  std::vector<std::vector<double>> m_weights;
204 
205  // Smoother operators
206  std::vector<std::vector<std::vector<double>>> m_Gxi;
207  std::vector<std::vector<std::vector<double>>> m_Geta;
208  std::vector<std::vector<double>> m_Divxi;
209  std::vector<std::vector<double>> m_Diveta;
210  std::vector<std::vector<std::vector<double>>> m_Az;
211  std::vector<std::vector<double>> m_Jxi;
212  std::vector<std::vector<double>> m_Jeta;
213  std::vector<std::vector<double>> m_ww2;
214 
215  // Smoother local caches
216  std::vector<UInt> m_sharedFacesCache;
217  std::vector<UInt> m_connectedNodesCache;
218  std::vector<std::vector<UInt>> m_faceNodeMappingCache;
219  std::vector<double> m_xiCache;
220  std::vector<double> m_etaCache;
221  std::vector<double> m_leftXFaceCenterCache;
222  std::vector<double> m_leftYFaceCenterCache;
223  std::vector<double> m_rightXFaceCenterCache;
224  std::vector<double> m_rightYFaceCenterCache;
225  std::vector<double> m_xisCache;
226  std::vector<double> m_etasCache;
227 
228  // Smoother topologies
229  std::vector<UInt> m_nodeTopologyMapping;
230  std::vector<std::vector<double>> m_topologyXi;
231  std::vector<std::vector<double>> m_topologyEta;
232  std::vector<std::vector<UInt>> m_topologySharedFaces;
233  std::vector<std::vector<std::vector<UInt>>> m_topologyFaceNodeMapping;
234  std::vector<std::vector<UInt>> m_topologyConnectedNodes;
235 
236  std::vector<UInt> m_numConnectedNodes;
237  std::vector<std::vector<UInt>> m_connectedNodes;
238 
239  // Class variables
240  UInt m_maximumNumConnectedNodes = 0;
241  UInt m_maximumNumSharedFaces = 0;
242 
243  static constexpr int m_topologyInitialSize = 10;
244  static constexpr double m_thetaTolerance = 1e-4;
245  };
246 } // namespace meshkernel
meshkernel::Smoother
Orthogonalizion (optimize the aspect ratios) and mesh smoothing (optimize internal face angles or are...
Definition: Smoother.hpp:39
meshkernel::Smoother::GetConnectedNodeIndex
auto GetConnectedNodeIndex(UInt node, int connectedNode) const
Get the index of the connected node as assigned by the smoother administration.
Definition: Smoother.hpp:63
meshkernel::Mesh2D
A class derived from Mesh, which describes unstructures 2d meshes.
Definition: Mesh2D.hpp:55
meshkernel::Smoother::GetNumConnectedNodes
auto GetNumConnectedNodes(UInt node) const
Get number of connected nodes.
Definition: Smoother.hpp:71
meshkernel::Smoother::Compute
void Compute()
Computes the smoother weights.
meshkernel::Smoother::GetWeight
auto GetWeight(UInt node, int connectedNode) const
Gets the weight for a certain node and connected node.
Definition: Smoother.hpp:54
meshkernel::Smoother::Smoother
Smoother(const Mesh2D &mesh)
Mesh2D constructor.
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