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 "addMeshOption.H"
95  #include "addRegionOption.H"
97  (
98  "noTopology",
99  "skip checking the mesh topology"
100  );
102  (
103  "allGeometry",
104  "include bounding box checks"
105  );
107  (
108  "allTopology",
109  "include extra topology checks"
110  );
112  (
113  "meshQuality",
114  "read user-defined mesh quality criterions from system/meshQualityDict"
115  );
117  (
118  "writeSurfaces",
119  "reconstruct and write faceSets and cellSets of the problem faces"
120  );
122  (
123  "surfaceFormat",
124  "surfaceFormat",
125  "Format for faceSets and cellSets of the problem faces, defaults to vtk"
126  );
128  (
129  "writeSets",
130  "reconstruct and write pointSets of the problem points"
131  );
133  (
134  "setFormat",
135  "setFormat",
136  "Format for pointSets of the problem points, defaults to vtk"
137  );
139  (
140  "nonOrthThreshold",
141  "nonOrthThreshold",
142  "Threshold in degrees "
143  "for reporting non-orthogonality errors, default: 70"
144  );
146  (
147  "skewThreshold",
148  "skewThreshold",
149  "Threshold for reporting non-orthogonality errors, default: 4"
150  );
151 
152  #include "setRootCase.H"
153  #include "createTime.H"
155  #include "createSpecifiedPolyMesh.H"
156 
157  const bool noTopology = args.optionFound("noTopology");
158  const bool allGeometry = args.optionFound("allGeometry");
159  const bool allTopology = args.optionFound("allTopology");
160  const bool meshQuality = args.optionFound("meshQuality");
161  const bool writeSurfaces = args.optionFound("writeSurfaces");
162  const bool writeSets = args.optionFound("writeSets");
163 
164  word surfaceFormat(vtkSurfaceWriter::typeName);
165  args.optionReadIfPresent("surfaceFormat", surfaceFormat);
166 
167  word setFormat(vtkSetWriter::typeName);
168  args.optionReadIfPresent("surfaceFormat", setFormat);
169 
170  scalar nonOrthThreshold = 70;
171  args.optionReadIfPresent("nonOrthThreshold", nonOrthThreshold);
172  nonOrthThreshold = degToRad(nonOrthThreshold);
173 
174  scalar skewThreshold = 4;
175  args.optionReadIfPresent("skewThreshold", skewThreshold);
176 
177  if (noTopology)
178  {
179  Info<< "Disabling all topology checks." << nl << endl;
180  }
181  if (allTopology)
182  {
183  Info<< "Enabling all (cell, face, edge, point) topology checks."
184  << nl << endl;
185  }
186  if (allGeometry)
187  {
188  Info<< "Enabling all geometry checks." << nl << endl;
189  }
190  if (meshQuality)
191  {
192  Info<< "Enabling user-defined geometry checks." << nl << endl;
193  }
194  if (writeSurfaces)
195  {
196  Info<< "Reconstructing and writing surface representation of the "
197  << "faceSets and cellSets of problem faces in "
198  << surfaceFormat << " format" << nl << endl;
199  }
200  if (writeSets)
201  {
202  Info<< "Reconstructing and writing the problem points in "
203  << setFormat << " format"
204  << nl << endl;
205  }
206 
207 
208  autoPtr<IOdictionary> qualDict;
209  if (meshQuality)
210  {
211  qualDict.reset
212  (
213  new IOdictionary
214  (
215  IOobject
216  (
217  "meshQualityDict",
218  mesh.time().system(),
219  mesh,
222  )
223  )
224  );
225  }
226 
228  if (writeSurfaces)
229  {
231  (
232  surfaceFormat,
233  mesh.time().writeFormat(),
235  );
236  }
237 
239  if (writeSets)
240  {
242  (
243  setFormat,
244  mesh.time().writeFormat(),
246  );
247  }
248 
249 
250  forAll(timeDirs, timeI)
251  {
252  runTime.setTime(timeDirs[timeI], timeI);
253 
255 
256  if
257  (
258  !timeI
259  || state == polyMesh::TOPO_CHANGE
260  || state == polyMesh::TOPO_PATCH_CHANGE
261  )
262  {
263  Info<< "Time = " << runTime.userTimeName() << nl << endl;
264 
265  // Reconstruct globalMeshData
266  mesh.globalData();
267 
268  meshCheck::printMeshStats(mesh, allTopology);
269 
270  label nFailedChecks = 0;
271 
272  if (!noTopology)
273  {
274  nFailedChecks += meshCheck::checkTopology
275  (
276  mesh,
277  allTopology,
279  setWriter
280  );
281  }
282 
283  nFailedChecks += meshCheck::checkGeometry
284  (
285  mesh,
286  allGeometry,
287  nonOrthThreshold,
288  skewThreshold,
290  setWriter
291  );
292 
293  if (meshQuality)
294  {
295  nFailedChecks +=
296  checkMeshQuality(mesh, qualDict(), surfaceWriter);
297  }
298 
299 
300  // Note: no reduction in nFailedChecks necessary since is
301  // counter of checks, not counter of failed cells,faces etc.
302 
303  if (nFailedChecks == 0)
304  {
305  Info<< "\nMesh OK.\n" << endl;
306  }
307  else
308  {
309  Info<< "\nFailed " << nFailedChecks << " mesh checks.\n"
310  << endl;
311  }
312  }
313  else if (state == polyMesh::POINTS_MOVED)
314  {
315  Info<< "Time = " << runTime.userTimeName() << nl << endl;
316 
317  label nFailedChecks = meshCheck::checkGeometry
318  (
319  mesh,
320  allGeometry,
321  nonOrthThreshold,
322  skewThreshold,
324  setWriter
325  );
326 
327  if (meshQuality)
328  {
329  nFailedChecks +=
330  checkMeshQuality(mesh, qualDict(), surfaceWriter);
331  }
332 
333 
334  if (nFailedChecks)
335  {
336  Info<< "\nFailed " << nFailedChecks << " mesh checks.\n"
337  << endl;
338  }
339  else
340  {
341  Info<< "\nMesh OK.\n" << endl;
342  }
343  }
344  }
345 
346  Info<< "End\n" << endl;
347 
348  return 0;
349 }
350 
351 
352 // ************************************************************************* //
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:433
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 const word & system()
Return system name.
Definition: TimePaths.H:112
IOstream::streamFormat writeFormat() const
Default write format.
Definition: Time.H:281
IOstream::compressionType writeCompression() const
Default write compression.
Definition: Time.H:293
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:255
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
const Time & time() const
Return the top-level database.
Definition: fvMesh.H:420
readUpdateState readUpdate(const stitchType stitch=stitchType::geometric)
Update the mesh based on the mesh files saved in time.
Definition: fvMesh.C:866
readUpdateState
Enumeration defining the state of the mesh after a read update.
Definition: polyMesh.H:90
@ TOPO_PATCH_CHANGE
Definition: polyMesh.H:94
const globalMeshData & globalData() const
Return parallel info.
Definition: polyMesh.C:1521
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
Foam::fvMesh mesh(Foam::IOobject(regionName, runTime.name(), runTime, Foam::IOobject::MUST_READ), false)
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:258
messageStream Info
label checkMeshQuality(const polyMesh &, const dictionary &, const autoPtr< surfaceWriter > &)
static const char nl
Definition: Ostream.H:267
Foam::argList args(argc, argv)
word setFormat(propsDict.lookup< word >("setFormat"))