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.found("minFaceFlatness")
81  ? dict.lookup<scalar>("minFaceFlatness", true)
82  : -1.0
83  );
84  const scalar minDet
85  (
86  dict.lookup<scalar>("minDeterminant", true)
87  );
88 
89  // Counter for bad faces
90  label nWrongFaces = 0;
91 
92  Info<< "Checking faces in error :" << endl;
93 
94  if (maxNonOrtho < degToRad(180.0)-small)
95  {
97  (
98  report,
99  maxNonOrtho,
100  mesh,
101  mesh.cellCentres(),
102  mesh.faceAreas(),
103  checkFaces,
104  baffles,
105  &wrongFaces
106  );
107 
108  const label nNewWrongFaces =
109  returnReduce(wrongFaces.size(), sumOp<label>());
110 
111  Info<< " non-orthogonality > "
112  << setw(3) << radToDeg(maxNonOrtho)
113  << " degrees : "
114  << nNewWrongFaces - nWrongFaces << endl;
115 
116  nWrongFaces = nNewWrongFaces;
117  }
118 
119  if (minVol > -great)
120  {
121  const scalar refVol = pow3(mesh.bounds().minDim());
122 
124  (
125  report,
126  minVol*refVol,
127  mesh,
128  mesh.cellCentres(),
129  mesh.points(),
130  checkFaces,
131  baffles,
132  &wrongFaces
133  );
134 
135  const label nNewWrongFaces =
136  returnReduce(wrongFaces.size(), sumOp<label>());
137 
138  Info<< " faces with face pyramid volume < "
139  << setw(5) << minVol << " : "
140  << nNewWrongFaces - nWrongFaces << endl;
141 
142  nWrongFaces = nNewWrongFaces;
143  }
144 
145  if (minTetQuality > -great)
146  {
148  (
149  report,
150  minTetQuality,
151  mesh,
152  mesh.cellCentres(),
153  mesh.faceCentres(),
154  mesh.points(),
155  checkFaces,
156  baffles,
157  &wrongFaces
158  );
159 
160  const label nNewWrongFaces =
161  returnReduce(wrongFaces.size(), sumOp<label>());
162 
163  Info<< " faces with face-decomposition tet quality < "
164  << setw(5) << minTetQuality << " : "
165  << nNewWrongFaces - nWrongFaces << endl;
166 
167  nWrongFaces = nNewWrongFaces;
168  }
169 
170  if (maxConcave < degToRad(180.0)-small)
171  {
173  (
174  report,
175  maxConcave,
176  mesh,
177  mesh.faceAreas(),
178  mesh.points(),
179  checkFaces,
180  &wrongFaces
181  );
182 
183  const label nNewWrongFaces =
184  returnReduce(wrongFaces.size(), sumOp<label>());
185 
186  Info<< " faces with concavity > "
187  << setw(3) << radToDeg(maxConcave)
188  << " degrees : "
189  << nNewWrongFaces - nWrongFaces << endl;
190 
191  nWrongFaces = nNewWrongFaces;
192  }
193 
194  if (maxIntSkew > 0 || maxBounSkew > 0)
195  {
197  (
198  report,
199  maxIntSkew,
200  maxBounSkew,
201  mesh,
202  mesh.points(),
203  mesh.cellCentres(),
204  mesh.faceCentres(),
205  mesh.faceAreas(),
206  checkFaces,
207  baffles,
208  &wrongFaces
209  );
210 
211  const label nNewWrongFaces =
212  returnReduce(wrongFaces.size(), sumOp<label>());
213 
214  Info<< " faces with skewness > "
215  << setw(3) << maxIntSkew
216  << " (internal) or " << setw(3) << maxBounSkew
217  << " (boundary) : " << nNewWrongFaces - nWrongFaces << endl;
218 
219  nWrongFaces = nNewWrongFaces;
220  }
221 
222  if (minWeight >= 0 && minWeight < 1)
223  {
225  (
226  report,
227  minWeight,
228  mesh,
229  mesh.cellCentres(),
230  mesh.faceCentres(),
231  mesh.faceAreas(),
232  checkFaces,
233  baffles,
234  &wrongFaces
235  );
236 
237  const label nNewWrongFaces =
238  returnReduce(wrongFaces.size(), sumOp<label>());
239 
240  Info<< " faces with interpolation weights (0..1) < "
241  << setw(5) << minWeight
242  << " : "
243  << nNewWrongFaces - nWrongFaces << endl;
244 
245  nWrongFaces = nNewWrongFaces;
246  }
247 
248  if (minVolRatio >= 0)
249  {
251  (
252  report,
253  minVolRatio,
254  mesh,
255  mesh.cellVolumes(),
256  checkFaces,
257  baffles,
258  &wrongFaces
259  );
260 
261  const label nNewWrongFaces =
262  returnReduce(wrongFaces.size(), sumOp<label>());
263 
264  Info<< " faces with volume ratio of neighbour cells < "
265  << setw(5) << minVolRatio
266  << " : "
267  << nNewWrongFaces - nWrongFaces << endl;
268 
269  nWrongFaces = nNewWrongFaces;
270  }
271 
272  if (minTwist > -1)
273  {
275  (
276  report,
277  minTwist,
278  mesh,
279  mesh.cellCentres(),
280  mesh.faceAreas(),
281  mesh.faceCentres(),
282  mesh.points(),
283  checkFaces,
284  &wrongFaces
285  );
286 
287  const label nNewWrongFaces =
288  returnReduce(wrongFaces.size(), sumOp<label>());
289 
290  Info<< " faces with face twist < "
291  << setw(5) << minTwist
292  << " : "
293  << nNewWrongFaces - nWrongFaces << endl;
294 
295  nWrongFaces = nNewWrongFaces;
296  }
297 
298  if (minFaceFlatness > -small)
299  {
301  (
302  report,
303  minFaceFlatness,
304  mesh,
305  mesh.faceAreas(),
306  mesh.faceCentres(),
307  mesh.points(),
308  checkFaces,
309  &wrongFaces
310  );
311 
312  const label nNewWrongFaces =
313  returnReduce(wrongFaces.size(), sumOp<label>());
314 
315  Info<< " faces with flatness < "
316  << setw(5) << minFaceFlatness
317  << " : "
318  << nNewWrongFaces - nWrongFaces << endl;
319 
320  nWrongFaces = nNewWrongFaces;
321  }
322 
323  if (minDet > -1)
324  {
326  (
327  report,
328  minDet,
329  mesh,
330  mesh.faceAreas(),
331  checkFaces,
332  &wrongFaces
333  );
334 
335  const label nNewWrongFaces =
336  returnReduce(wrongFaces.size(), sumOp<label>());
337 
338  Info<< " faces on cells with determinant < "
339  << setw(5) << minDet << " : "
340  << nNewWrongFaces - nWrongFaces << endl;
341 
342  nWrongFaces = nNewWrongFaces;
343  }
344 
345  return nWrongFaces > 0;
346 }
347 
348 
350 (
351  const bool report,
352  const polyMesh& mesh,
353  const dictionary& dict,
354  const labelList& checkFaces,
355  labelHashSet& wrongFaces
356 )
357 {
358  const List<labelPair> emptyBaffles;
359 
360  return checkMesh
361  (
362  report,
363  mesh,
364  dict,
365  checkFaces,
366  emptyBaffles,
367  wrongFaces
368  );
369 }
370 
371 
373 (
374  const bool report,
375  const polyMesh& mesh,
376  const dictionary& dict,
377  labelHashSet& wrongFaces
378 )
379 {
380  return checkMesh
381  (
382  report,
383  mesh,
384  dict,
386  wrongFaces
387  );
388 }
389 
390 
391 // ************************************************************************* //
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 keywords followed by any number of values (e.g. words and numbers) or sub-dictionaries.
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:1331
const boundBox & bounds() const
Return mesh bounding box.
Definition: polyMesh.H:407
const vectorField & faceCentres() const
const scalarField & cellVolumes() const
const vectorField & cellCentres() const
const vectorField & faceAreas() const
label nFaces() const
Foam::fvMesh mesh(Foam::IOobject(regionName, runTime.name(), runTime, Foam::IOobject::MUST_READ), false)
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:258
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)
void pow3(LagrangianPatchField< scalar > &f, const LagrangianPatchField< scalar > &f1)
labelList identityMap(const label len)
Create identity map (map[i] == i) of given length.
Definition: ListOps.C:104
const unitConversion unitDegrees
dictionary dict