checkMesh.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2011-2024 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include "meshCheck.H"
27 #include "IOmanip.H"
28 #include "unitConversion.H"
29 
30 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
31 
33 (
34  const bool report,
35  const polyMesh& mesh,
36  const dictionary& dict,
37  const labelList& checkFaces,
38  const List<labelPair>& baffles,
39  labelHashSet& wrongFaces
40 )
41 {
42  const scalar maxNonOrtho
43  (
44  dict.lookup<scalar>("maxNonOrtho", unitDegrees, true)
45  );
46  const scalar minVol
47  (
48  dict.lookup<scalar>("minVol", true)
49  );
50  const scalar minTetQuality
51  (
52  dict.lookup<scalar>("minTetQuality", true)
53  );
54  const scalar maxConcave
55  (
56  dict.lookup<scalar>("maxConcave", unitDegrees, true)
57  );
58  const scalar maxIntSkew
59  (
60  dict.lookup<scalar>("maxInternalSkewness", true)
61  );
62  const scalar maxBounSkew
63  (
64  dict.lookup<scalar>("maxBoundarySkewness", true)
65  );
66  const scalar minWeight
67  (
68  dict.lookup<scalar>("minFaceWeight", true)
69  );
70  const scalar minVolRatio
71  (
72  dict.lookup<scalar>("minVolRatio", true)
73  );
74  const scalar minTwist
75  (
76  dict.lookup<scalar>("minTwist", true)
77  );
78  const scalar minFaceFlatness
79  (
80  dict.lookupOrDefault("minFaceFlatness", -1.0, true)
81  );
82  const scalar minDet
83  (
84  dict.lookup<scalar>("minDeterminant", true)
85  );
86 
87  // Counter for bad faces
88  label nWrongFaces = 0;
89 
90  Info<< "Checking faces in error :" << endl;
91 
92  if (maxNonOrtho < degToRad(180.0)-small)
93  {
95  (
96  report,
97  maxNonOrtho,
98  mesh,
99  mesh.cellCentres(),
100  mesh.faceAreas(),
101  checkFaces,
102  baffles,
103  &wrongFaces
104  );
105 
106  const label nNewWrongFaces =
107  returnReduce(wrongFaces.size(), sumOp<label>());
108 
109  Info<< " non-orthogonality > "
110  << setw(3) << radToDeg(maxNonOrtho)
111  << " degrees : "
112  << nNewWrongFaces - nWrongFaces << endl;
113 
114  nWrongFaces = nNewWrongFaces;
115  }
116 
117  if (minVol > -great)
118  {
119  const scalar refVol = pow3(mesh.bounds().minDim());
120 
122  (
123  report,
124  minVol*refVol,
125  mesh,
126  mesh.cellCentres(),
127  mesh.points(),
128  checkFaces,
129  baffles,
130  &wrongFaces
131  );
132 
133  const label nNewWrongFaces =
134  returnReduce(wrongFaces.size(), sumOp<label>());
135 
136  Info<< " faces with face pyramid volume < "
137  << setw(5) << minVol << " : "
138  << nNewWrongFaces - nWrongFaces << endl;
139 
140  nWrongFaces = nNewWrongFaces;
141  }
142 
143  if (minTetQuality > -great)
144  {
146  (
147  report,
148  minTetQuality,
149  mesh,
150  mesh.cellCentres(),
151  mesh.faceCentres(),
152  mesh.points(),
153  checkFaces,
154  baffles,
155  &wrongFaces
156  );
157 
158  const label nNewWrongFaces =
159  returnReduce(wrongFaces.size(), sumOp<label>());
160 
161  Info<< " faces with face-decomposition tet quality < "
162  << setw(5) << minTetQuality << " : "
163  << nNewWrongFaces - nWrongFaces << endl;
164 
165  nWrongFaces = nNewWrongFaces;
166  }
167 
168  if (maxConcave < degToRad(180.0)-small)
169  {
171  (
172  report,
173  maxConcave,
174  mesh,
175  mesh.faceAreas(),
176  mesh.points(),
177  checkFaces,
178  &wrongFaces
179  );
180 
181  const label nNewWrongFaces =
182  returnReduce(wrongFaces.size(), sumOp<label>());
183 
184  Info<< " faces with concavity > "
185  << setw(3) << radToDeg(maxConcave)
186  << " degrees : "
187  << nNewWrongFaces - nWrongFaces << endl;
188 
189  nWrongFaces = nNewWrongFaces;
190  }
191 
192  if (maxIntSkew > 0 || maxBounSkew > 0)
193  {
195  (
196  report,
197  maxIntSkew,
198  maxBounSkew,
199  mesh,
200  mesh.points(),
201  mesh.cellCentres(),
202  mesh.faceCentres(),
203  mesh.faceAreas(),
204  checkFaces,
205  baffles,
206  &wrongFaces
207  );
208 
209  const label nNewWrongFaces =
210  returnReduce(wrongFaces.size(), sumOp<label>());
211 
212  Info<< " faces with skewness > "
213  << setw(3) << maxIntSkew
214  << " (internal) or " << setw(3) << maxBounSkew
215  << " (boundary) : " << nNewWrongFaces - nWrongFaces << endl;
216 
217  nWrongFaces = nNewWrongFaces;
218  }
219 
220  if (minWeight >= 0 && minWeight < 1)
221  {
223  (
224  report,
225  minWeight,
226  mesh,
227  mesh.cellCentres(),
228  mesh.faceCentres(),
229  mesh.faceAreas(),
230  checkFaces,
231  baffles,
232  &wrongFaces
233  );
234 
235  const label nNewWrongFaces =
236  returnReduce(wrongFaces.size(), sumOp<label>());
237 
238  Info<< " faces with interpolation weights (0..1) < "
239  << setw(5) << minWeight
240  << " : "
241  << nNewWrongFaces - nWrongFaces << endl;
242 
243  nWrongFaces = nNewWrongFaces;
244  }
245 
246  if (minVolRatio >= 0)
247  {
249  (
250  report,
251  minVolRatio,
252  mesh,
253  mesh.cellVolumes(),
254  checkFaces,
255  baffles,
256  &wrongFaces
257  );
258 
259  const label nNewWrongFaces =
260  returnReduce(wrongFaces.size(), sumOp<label>());
261 
262  Info<< " faces with volume ratio of neighbour cells < "
263  << setw(5) << minVolRatio
264  << " : "
265  << nNewWrongFaces - nWrongFaces << endl;
266 
267  nWrongFaces = nNewWrongFaces;
268  }
269 
270  if (minTwist > -1)
271  {
273  (
274  report,
275  minTwist,
276  mesh,
277  mesh.cellCentres(),
278  mesh.faceAreas(),
279  mesh.faceCentres(),
280  mesh.points(),
281  checkFaces,
282  &wrongFaces
283  );
284 
285  const label nNewWrongFaces =
286  returnReduce(wrongFaces.size(), sumOp<label>());
287 
288  Info<< " faces with face twist < "
289  << setw(5) << minTwist
290  << " : "
291  << nNewWrongFaces - nWrongFaces << endl;
292 
293  nWrongFaces = nNewWrongFaces;
294  }
295 
296  if (minFaceFlatness > -small)
297  {
299  (
300  report,
301  minFaceFlatness,
302  mesh,
303  mesh.faceAreas(),
304  mesh.faceCentres(),
305  mesh.points(),
306  checkFaces,
307  &wrongFaces
308  );
309 
310  const label nNewWrongFaces =
311  returnReduce(wrongFaces.size(), sumOp<label>());
312 
313  Info<< " faces with flatness < "
314  << setw(5) << minFaceFlatness
315  << " : "
316  << nNewWrongFaces - nWrongFaces << endl;
317 
318  nWrongFaces = nNewWrongFaces;
319  }
320 
321  if (minDet > -1)
322  {
324  (
325  report,
326  minDet,
327  mesh,
328  mesh.faceAreas(),
329  checkFaces,
330  &wrongFaces
331  );
332 
333  const label nNewWrongFaces =
334  returnReduce(wrongFaces.size(), sumOp<label>());
335 
336  Info<< " faces on cells with determinant < "
337  << setw(5) << minDet << " : "
338  << nNewWrongFaces - nWrongFaces << endl;
339 
340  nWrongFaces = nNewWrongFaces;
341  }
342 
343  return nWrongFaces > 0;
344 }
345 
346 
348 (
349  const bool report,
350  const polyMesh& mesh,
351  const dictionary& dict,
352  const labelList& checkFaces,
353  labelHashSet& wrongFaces
354 )
355 {
356  const List<labelPair> emptyBaffles;
357 
358  return checkMesh
359  (
360  report,
361  mesh,
362  dict,
363  checkFaces,
364  emptyBaffles,
365  wrongFaces
366  );
367 }
368 
369 
371 (
372  const bool report,
373  const polyMesh& mesh,
374  const dictionary& dict,
375  labelHashSet& wrongFaces
376 )
377 {
378  return checkMesh
379  (
380  report,
381  mesh,
382  dict,
383  identityMap(mesh.nFaces()),
384  wrongFaces
385  );
386 }
387 
388 
389 // ************************************************************************* //
Istream and Ostream manipulators taking arguments.
label size() const
Return number of elements in table.
Definition: HashTableI.H:65
scalar minDim() const
Smallest length/height/width dimension.
Definition: boundBoxI.H:108
A list of keyword definitions, which are a keyword followed by any number of values (e....
Definition: dictionary.H:162
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:80
virtual const pointField & points() const
Return raw points.
Definition: polyMesh.C:1313
const boundBox & bounds() const
Return mesh bounding box.
Definition: polyMesh.H:410
const vectorField & faceCentres() const
const scalarField & cellVolumes() const
const vectorField & cellCentres() const
label nFaces() const
const vectorField & faceAreas() const
Functions for checking mesh topology and geometry.
bool checkMesh(const bool report, const polyMesh &mesh, const dictionary &dict, const labelList &checkFaces, const List< labelPair > &baffles, labelHashSet &wrongFaces)
Check (subset of mesh including baffles) with mesh settings in dict.
Definition: checkMesh.C:33
bool checkFacePyramids(const bool report, const scalar minPyrVol, const polyMesh &, const vectorField &cellCentres, const pointField &p, const labelList &checkFaces, const List< labelPair > &baffles, labelHashSet *)
Check face pyramid volumes.
bool checkFaceTwist(const bool report, const scalar minTwist, const polyMesh &, const vectorField &cellCentres, const vectorField &faceAreas, const vectorField &faceCentres, const pointField &p, const labelList &checkFaces, labelHashSet *setPtr)
Check the difference between normals of individual face-triangles (from.
bool checkFaceWeights(const bool report, const scalar warnWeight, const polyMesh &mesh, const vectorField &cellCentres, const vectorField &faceCentres, const vectorField &faceAreas, const labelList &checkFaces, const List< labelPair > &baffles, labelHashSet *setPtr)
Check interpolation weights (0.5 for regular mesh)
bool checkCellDeterminant(const polyMesh &mesh, const bool report, labelHashSet *setPtr)
bool checkFaceAngles(const bool report, const scalar maxConcave, const polyMesh &mesh, const vectorField &faceAreas, const pointField &p, const labelList &checkFaces, labelHashSet *setPtr)
Check convexity of angles in a face. See primitiveMesh for explanation.
bool checkVolRatio(const polyMesh &mesh, const bool report, const scalar minRatio=0.01, labelHashSet *setPtr=nullptr)
Check for neighbouring cell volumes.
bool checkFaceTets(const bool report, const scalar minPyrVol, const polyMesh &, const vectorField &cellCentres, const vectorField &faceCentres, const pointField &p, const labelList &checkFaces, const List< labelPair > &baffles, labelHashSet *)
Check face tetrahedra volumes.
bool checkFaceFlatness(const bool report, const scalar minFlatness, const polyMesh &, const vectorField &faceAreas, const vectorField &faceCentres, const pointField &p, const labelList &checkFaces, labelHashSet *setPtr)
Check for face areas v.s. sum of face-triangle (from face-centre.
bool checkFaceOrthogonality(const polyMesh &mesh, const scalar nonOrthThreshold, const bool report=false, labelHashSet *setPtr=nullptr)
Check face orthogonality.
bool checkFaceSkewness(const polyMesh &mesh, const scalar skewThreshold, const bool report=false, labelHashSet *setPtr=nullptr)
Check face skewness.
scalar radToDeg(const scalar rad)
Convert radians to degrees.
scalar degToRad(const scalar deg)
Convert degrees to radians.
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:257
dimensionedScalar pow3(const dimensionedScalar &ds)
Omanip< int > setw(const int i)
Definition: IOmanip.H:199
messageStream Info
T returnReduce(const T &Value, const BinaryOp &bop, const int tag=Pstream::msgType(), const label comm=UPstream::worldComm)
labelList identityMap(const label len)
Create identity map (map[i] == i) of given length.
Definition: ListOps.C:104
const unitConversion unitDegrees
dictionary dict