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 Application
25  checkMesh
26 
27 Description
28  Checks validity of a mesh.
29 
30 Usage
31  \b checkMesh [OPTION]
32 
33  Options:
34  - \par noTopology
35  Skip checking the mesh topology
36 
37  - \par -allTopology
38  Check all (including non finite-volume specific) addressing
39 
40  - \par -allGeometry
41  Check all (including non finite-volume specific) geometry
42 
43  - \par -meshQuality
44  Check against user defined (in \a system/meshQualityDict) quality
45  settings
46 
47  - \par -region <name>
48  Specify an alternative mesh region.
49 
50  - \par -writeSurfaces
51  Reconstruct cellSets and faceSets of problem faces and write to
52  postProcessing directory.
53 
54  - \par -surfaceFormat <format>
55  Format used to write the cellSets and faceSets surfaces
56  e.g. vtk or ensight.
57 
58  - \par -writeSets
59  Reconstruct pointSets of problem points nd write to
60  postProcessing directory.
61 
62  - \par -setFormat <format>
63  Format used to write the pointSets
64  e.g. vtk or ensight.
65 
66  - \par -nonOrthThreshold <threshold value in degrees>
67  Threshold in degrees for reporting non-orthogonality errors,
68  default: 70"
69 
70  - \par -skewThreshold <threshold value>
71  Threshold for reporting skewness errors, default: 4.
72 
73 \*---------------------------------------------------------------------------*/
74 
75 #include "argList.H"
76 #include "timeSelector.H"
77 #include "Time.H"
78 #include "polyMesh.H"
79 #include "globalMeshData.H"
80 #include "vtkSurfaceWriter.H"
81 #include "vtkSetWriter.H"
82 #include "IOdictionary.H"
83 
84 #include "meshCheck.H"
85 #include "checkMeshQuality.H"
86 
87 using namespace Foam;
88 
89 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
90 
91 int main(int argc, char *argv[])
92 {
94  #include "addRegionOption.H"
96  (
97  "noTopology",
98  "skip checking the mesh topology"
99  );
101  (
102  "allGeometry",
103  "include bounding box checks"
104  );
106  (
107  "allTopology",
108  "include extra topology checks"
109  );
111  (
112  "meshQuality",
113  "read user-defined mesh quality criterions from system/meshQualityDict"
114  );
116  (
117  "writeSurfaces",
118  "reconstruct and write faceSets and cellSets of the problem faces"
119  );
121  (
122  "surfaceFormat",
123  "surfaceFormat",
124  "Format for faceSets and cellSets of the problem faces, defaults to vtk"
125  );
127  (
128  "writeSets",
129  "reconstruct and write pointSets of the problem points"
130  );
132  (
133  "setFormat",
134  "setFormat",
135  "Format for pointSets of the problem points, defaults to vtk"
136  );
138  (
139  "nonOrthThreshold",
140  "nonOrthThreshold",
141  "Threshold in degrees "
142  "for reporting non-orthogonality errors, default: 70"
143  );
145  (
146  "skewThreshold",
147  "skewThreshold",
148  "Threshold for reporting non-orthogonality errors, default: 4"
149  );
150 
151  #include "setRootCase.H"
152  #include "createTime.H"
154  #include "createNamedPolyMesh.H"
155 
156  const bool noTopology = args.optionFound("noTopology");
157  const bool allGeometry = args.optionFound("allGeometry");
158  const bool allTopology = args.optionFound("allTopology");
159  const bool meshQuality = args.optionFound("meshQuality");
160  const bool writeSurfaces = args.optionFound("writeSurfaces");
161  const bool writeSets = args.optionFound("writeSets");
162 
163  word surfaceFormat(vtkSurfaceWriter::typeName);
164  args.optionReadIfPresent("surfaceFormat", surfaceFormat);
165 
166  word setFormat(vtkSetWriter::typeName);
167  args.optionReadIfPresent("surfaceFormat", setFormat);
168 
169  scalar nonOrthThreshold = 70;
170  args.optionReadIfPresent("nonOrthThreshold", nonOrthThreshold);
171  nonOrthThreshold = degToRad(nonOrthThreshold);
172 
173  scalar skewThreshold = 4;
174  args.optionReadIfPresent("skewThreshold", skewThreshold);
175 
176  if (noTopology)
177  {
178  Info<< "Disabling all topology checks." << nl << endl;
179  }
180  if (allTopology)
181  {
182  Info<< "Enabling all (cell, face, edge, point) topology checks."
183  << nl << endl;
184  }
185  if (allGeometry)
186  {
187  Info<< "Enabling all geometry checks." << nl << endl;
188  }
189  if (meshQuality)
190  {
191  Info<< "Enabling user-defined geometry checks." << nl << endl;
192  }
193  if (writeSurfaces)
194  {
195  Info<< "Reconstructing and writing surface representation of the "
196  << "faceSets and cellSets of problem faces in "
197  << surfaceFormat << " format" << nl << endl;
198  }
199  if (writeSets)
200  {
201  Info<< "Reconstructing and writing the problem points in "
202  << setFormat << " format"
203  << nl << endl;
204  }
205 
206 
207  autoPtr<IOdictionary> qualDict;
208  if (meshQuality)
209  {
210  qualDict.reset
211  (
212  new IOdictionary
213  (
214  IOobject
215  (
216  "meshQualityDict",
217  mesh.time().system(),
218  mesh,
221  )
222  )
223  );
224  }
225 
227  if (writeSurfaces)
228  {
230  (
231  surfaceFormat,
232  mesh.time().writeFormat(),
233  mesh.time().writeCompression()
234  );
235  }
236 
238  if (writeSets)
239  {
241  (
242  setFormat,
243  mesh.time().writeFormat(),
244  mesh.time().writeCompression()
245  );
246  }
247 
248 
249  forAll(timeDirs, timeI)
250  {
251  runTime.setTime(timeDirs[timeI], timeI);
252 
253  polyMesh::readUpdateState state = mesh.readUpdate();
254 
255  if
256  (
257  !timeI
258  || state == polyMesh::TOPO_CHANGE
259  || state == polyMesh::TOPO_PATCH_CHANGE
260  )
261  {
262  Info<< "Time = " << runTime.userTimeName() << nl << endl;
263 
264  // Reconstruct globalMeshData
265  mesh.globalData();
266 
267  meshCheck::printMeshStats(mesh, allTopology);
268 
269  label nFailedChecks = 0;
270 
271  if (!noTopology)
272  {
273  nFailedChecks += meshCheck::checkTopology
274  (
275  mesh,
276  allTopology,
278  setWriter
279  );
280  }
281 
282  nFailedChecks += meshCheck::checkGeometry
283  (
284  mesh,
285  allGeometry,
286  nonOrthThreshold,
287  skewThreshold,
289  setWriter
290  );
291 
292  if (meshQuality)
293  {
294  nFailedChecks +=
295  checkMeshQuality(mesh, qualDict(), surfaceWriter);
296  }
297 
298 
299  // Note: no reduction in nFailedChecks necessary since is
300  // counter of checks, not counter of failed cells,faces etc.
301 
302  if (nFailedChecks == 0)
303  {
304  Info<< "\nMesh OK.\n" << endl;
305  }
306  else
307  {
308  Info<< "\nFailed " << nFailedChecks << " mesh checks.\n"
309  << endl;
310  }
311  }
312  else if (state == polyMesh::POINTS_MOVED)
313  {
314  Info<< "Time = " << runTime.userTimeName() << nl << endl;
315 
316  label nFailedChecks = meshCheck::checkGeometry
317  (
318  mesh,
319  allGeometry,
320  nonOrthThreshold,
321  skewThreshold,
323  setWriter
324  );
325 
326  if (meshQuality)
327  {
328  nFailedChecks +=
329  checkMeshQuality(mesh, qualDict(), surfaceWriter);
330  }
331 
332 
333  if (nFailedChecks)
334  {
335  Info<< "\nFailed " << nFailedChecks << " mesh checks.\n"
336  << endl;
337  }
338  else
339  {
340  Info<< "\nMesh OK.\n" << endl;
341  }
342  }
343  }
344 
345  Info<< "End\n" << endl;
346 
347  return 0;
348 }
349 
350 
351 // ************************************************************************* //
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:434
Routines for checking mesh quality.
IOdictionary is derived from dictionary and IOobject to give the dictionary automatic IO functionalit...
Definition: IOdictionary.H:57
IOobject defines the attributes of an object for which implicit objectRegistry management is supporte...
Definition: IOobject.H:99
static void addOption(const word &opt, const string &param="", const string &usage="")
Add to an option to validOptions with usage information.
Definition: argList.C:128
static void addBoolOption(const word &opt, const string &usage="")
Add to a bool option to validOptions with usage information.
Definition: argList.C:118
bool optionFound(const word &opt) const
Return true if the named option is found.
Definition: argListI.H:114
bool optionReadIfPresent(const word &opt, T &) const
Read a value from the named option if present.
Definition: argListI.H:204
An auto-pointer similar to the STL auto_ptr but with automatic casting to a reference to the type and...
Definition: autoPtr.H:51
void reset(T *=nullptr)
If object pointer already set, delete object and set to given.
Definition: autoPtrI.H:114
readUpdateState
Enumeration defining the state of the mesh after a read update.
Definition: polyMesh.H:90
@ TOPO_PATCH_CHANGE
Definition: polyMesh.H:94
Base class for writing coordinate sets with data.
Definition: setWriter.H:64
static autoPtr< setWriter > New(const word &writeType, const IOstream::streamFormat writeFormat=IOstream::ASCII, const IOstream::compressionType writeCompression=IOstream::UNCOMPRESSED)
Select given write options.
Definition: setWriter.C:286
Base class for surface writers.
Definition: surfaceWriter.H:55
static autoPtr< surfaceWriter > New(const word &writeType, const IOstream::streamFormat writeFormat, const IOstream::compressionType writeCompression)
Select given write options.
Definition: surfaceWriter.C:75
static void addOptions(const bool constant=true, const bool withZero=false)
Add the options handled by timeSelector to argList::validOptions.
Definition: timeSelector.C:114
static instantList select0(Time &runTime, const argList &args)
Return the set of times selected based on the argList options.
Definition: timeSelector.C:252
A class for handling words, derived from string.
Definition: word.H:62
int main(int argc, char *argv[])
Definition: financialFoam.C:44
static instantList timeDirs
Definition: globalFoam.H:44
Functions for checking mesh topology and geometry.
label checkTopology(const polyMesh &mesh, const bool allTopology, const autoPtr< surfaceWriter > &surfWriter, const autoPtr< setWriter > &setWriter)
Check the topology.
Definition: checkTopology.C:42
label checkGeometry(const polyMesh &mesh, const bool allGeometry, const scalar nonOrthThreshold, const scalar skewThreshold, const autoPtr< surfaceWriter > &, const autoPtr< setWriter > &)
Check the geometry.
void printMeshStats(const polyMesh &mesh, const bool allTopology)
Print mesh statistics.
Definition: mergeAndWrite.C:50
Namespace for OpenFOAM.
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
messageStream Info
label checkMeshQuality(const polyMesh &, const dictionary &, const autoPtr< surfaceWriter > &)
static const char nl
Definition: Ostream.H:266
Foam::argList args(argc, argv)
word setFormat(propsDict.lookup< word >("setFormat"))