checkMesh.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2011-2017 OpenFOAM Foundation
9  Copyright (C) 2015-2023 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 Application
28  checkMesh
29 
30 Group
31  grpMeshManipulationUtilities
32 
33 Description
34  Checks validity of a mesh.
35 
36 Usage
37  \b checkMesh [OPTION]
38 
39  Options:
40  - \par -allGeometry
41  Checks all (including non finite-volume specific) geometry
42 
43  - \par -allTopology
44  Checks all (including non finite-volume specific) addressing
45 
46  - \par -meshQuality
47  Checks against user defined (in \a system/meshQualityDict) quality
48  settings
49 
50  - \par -region <name>
51  Specify an alternative mesh region.
52 
53  - \par -allRegions
54  Check all regions in regionProperties.
55 
56  \param -writeSets <surfaceFormat> \n
57  Reconstruct all cellSets and faceSets geometry and write to postProcessing
58  directory according to surfaceFormat (e.g. vtk or ensight). Additionally
59  reconstructs all pointSets and writes as vtk format.
60 
61  \param -writeAllFields \n
62  Writes all mesh quality measures as fields.
63 
64  \param -writeAllSurfaceFields \n
65  Adds writing of surface fields when used in combination with writeAllFields.
66 
67  \param -writeFields '(<fieldName>)' \n
68  Writes selected mesh quality measures as fields.
69 
70  \param -write-edges \n
71  Write bad edges (possibly relevant for finite-area) in VTK format.
72 
73 \*---------------------------------------------------------------------------*/
74 
75 #include "argList.H"
76 #include "timeSelector.H"
77 #include "Time.H"
78 #include "fvMesh.H"
79 #include "globalMeshData.H"
80 #include "vtkCoordSetWriter.H"
81 #include "vtkSurfaceWriter.H"
82 #include "IOdictionary.H"
83 #include "regionProperties.H"
84 #include "polyMeshTools.H"
85 
86 #include "checkTools.H"
87 #include "checkTopology.H"
88 #include "checkGeometry.H"
89 #include "checkMeshQuality.H"
90 #include "writeFields.H"
91 
92 using namespace Foam;
93 
94 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
95 
96 int main(int argc, char *argv[])
97 {
99  (
100  "Checks validity of a mesh"
101  );
102 
104  #include "addAllRegionOptions.H"
105 
107  (
108  "noTopology",
109  "Skip checking the mesh topology"
110  );
112  (
113  "allGeometry",
114  "Include bounding box checks"
115  );
117  (
118  "allTopology",
119  "Include extra topology checks"
120  );
122  (
123  "writeAllFields",
124  "Write volFields with mesh quality parameters"
125  );
127  (
128  "writeAllSurfaceFields",
129  "Write surfaceFields with mesh quality parameters"
130  );
132  (
133  "writeFields",
134  "wordList",
135  "Write volFields with selected mesh quality parameters"
136  );
138  (
139  "meshQuality",
140  "Read user-defined mesh quality criteria from system/meshQualityDict"
141  );
143  (
144  "writeSets",
145  "surfaceFormat",
146  "Reconstruct and write all faceSets and cellSets in selected format"
147  );
149  (
150  "write-edges",
151  "Write bad edges (possibly relevant for finite-area) in vtk format"
152  );
153 
154  #include "setRootCase.H"
155  #include "createTime.H"
156  #include "getAllRegionOptions.H"
158  #include "createNamedMeshes.H"
159 
160  const bool noTopology = args.found("noTopology");
161  const bool allGeometry = args.found("allGeometry");
162  const bool allTopology = args.found("allTopology");
163  const bool meshQuality = args.found("meshQuality");
164  const bool optWriteEdges = args.found("write-edges");
165 
166  const word surfaceFormat = args.getOrDefault<word>("writeSets", "");
167  const bool writeSets = surfaceFormat.size();
168 
169 
170  // All potential writeable fields
171  const wordHashSet allFields
172  ({
173  "nonOrthoAngle",
174  "faceWeight",
175  "skewness",
176  "cellDeterminant",
177  "aspectRatio",
178  "cellShapes",
179  "cellVolume",
180  "cellVolumeRatio",
181  "cellAspectRatio",
182  "minTetVolume",
183  "minPyrVolume",
184  "cellRegion",
185  "wallDistance",
186  "cellZone",
187  "faceZone"
188  });
189 
190  const bool writeFaceFields = args.found("writeAllSurfaceFields");
191  wordHashSet selectedFields;
192  if (args.found("writeFields"))
193  {
194  selectedFields = args.getList<word>("writeFields");
195  const wordHashSet badFields(selectedFields - allFields);
196 
197  if (!badFields.empty())
198  {
200  << "Illegal field(s): "
201  << flatOutput(badFields.sortedToc()) << nl
202  << "Valid fields: "
203  << flatOutput(allFields.sortedToc()) << nl
204  << exit(FatalError);
205  }
206  }
207  else if (args.found("writeAllFields"))
208  {
209  selectedFields = allFields;
210  }
211  else if (writeFaceFields)
212  {
214  << "Option 'writeAllSurfaceFields' only valid in combination"
215  << " with 'writeFields' or 'writeAllFields'"
216  << nl << exit(FatalError);
217  }
218 
219 
220  Info<< "Check mesh..." << nl;
221  Info().incrIndent();
222 
223  if (noTopology)
224  {
225  Info<< indent
226  << "Disabling all topology checks." << nl;
227  }
228  if (allTopology)
229  {
230  Info<< indent
231  << "Enabling all (cell, face, edge, point) topology checks." << nl;
232  }
233  if (allGeometry)
234  {
235  Info<< indent
236  << "Enabling all geometry checks." << nl;
237  }
238  if (meshQuality)
239  {
240  Info<< indent
241  << "Enabling user-defined geometry checks." << nl;
242  }
243  if (writeSets)
244  {
245  Info<< indent
246  << "Reconstructing and writing " << surfaceFormat
247  << " representation of all faceSets and cellSets." << nl;
248  }
249  if (selectedFields.size())
250  {
251  Info<< indent
252  << "Writing mesh quality as fields "
253  << flatOutput(selectedFields.sortedToc()) << nl;
254  }
255  if (optWriteEdges)
256  {
257  Info<< indent
258  << "Writing any bad edges in vtk format" << nl;
259  }
260  Info().decrIndent();
261  Info<< endl;
262 
263 
264  PtrList<IOdictionary> qualDict(meshes.size());
265  if (meshQuality)
266  {
267  forAll(meshes, meshi)
268  {
269  qualDict.set
270  (
271  meshi,
272  new IOdictionary
273  (
274  IOobject
275  (
276  "meshQualityDict",
277  meshes[meshi].time().system(),
278  meshes[meshi],
281  )
282  )
283  );
284  }
285  }
286 
287 
288  autoPtr<surfaceWriter> surfWriter;
289  autoPtr<coordSetWriter> setWriter;
290  if (writeSets)
291  {
292  surfWriter = surfaceWriter::New(surfaceFormat);
293  setWriter = coordSetWriter::New(coordSetWriters::vtkWriter::typeName);
294  }
295 
296 
297  forAll(timeDirs, timei)
298  {
299  runTime.setTime(timeDirs[timei], timei);
300 
301  // Get most changed of all meshes
303  for (auto& mesh : meshes)
304  {
305  state = polyMeshTools::combine(state, mesh.readUpdate());
306  }
307 
308 
309  if
310  (
311  !timei
312  || state == polyMesh::TOPO_CHANGE
313  || state == polyMesh::TOPO_PATCH_CHANGE
314  )
315  {
316  Info<< "Time = " << runTime.timeName() << nl << endl;
317 
318  forAll(meshes, meshi)
319  {
320  const auto& mesh = meshes[meshi];
321 
322  // Reconstruct globalMeshData
323  mesh.globalData();
324 
325  printMeshStats(mesh, allTopology);
326 
327  label nFailedChecks = 0;
328 
329  if (!noTopology)
330  {
331  nFailedChecks += checkTopology
332  (
333  mesh,
334  allTopology,
335  allGeometry,
336  surfWriter,
337  setWriter,
338  optWriteEdges
339  );
340  }
341 
342  nFailedChecks += checkGeometry
343  (
344  mesh,
345  allGeometry,
346  surfWriter,
347  setWriter
348  );
349 
350  if (meshQuality)
351  {
352  nFailedChecks +=
353  checkMeshQuality(mesh, qualDict[meshi], surfWriter);
354  }
355 
356 
357  // Note: no reduction in nFailedChecks necessary since is
358  // counter of checks, not counter of failed cells,faces
359  // etc.
360 
361  if (nFailedChecks == 0)
362  {
363  Info<< "\nMesh OK.\n" << endl;
364  }
365  else
366  {
367  Info<< "\nFailed " << nFailedChecks << " mesh checks.\n"
368  << endl;
369  }
370 
371 
372  // Write selected fields
373  Foam::writeFields(mesh, selectedFields, writeFaceFields);
374  }
375  }
376  else if (state == polyMesh::POINTS_MOVED)
377  {
378  Info<< "Time = " << runTime.timeName() << nl << endl;
379 
380  forAll(meshes, meshi)
381  {
382  const auto& mesh = meshes[meshi];
383 
384  label nFailedChecks = checkGeometry
385  (
386  mesh,
387  allGeometry,
388  surfWriter,
389  setWriter
390  );
391 
392  if (meshQuality)
393  {
394  nFailedChecks +=
395  checkMeshQuality(mesh, qualDict[meshi], surfWriter);
396  }
397 
398 
399  if (nFailedChecks)
400  {
401  Info<< "\nFailed " << nFailedChecks << " mesh checks.\n"
402  << endl;
403  }
404  else
405  {
406  Info<< "\nMesh OK.\n" << endl;
407  }
408 
409 
410  // Write selected fields
411  Foam::writeFields(mesh, selectedFields, writeFaceFields);
412  }
413  }
414  }
415 
416  Info<< "End\n" << endl;
417 
418  return 0;
419 }
420 
421 
422 // ************************************************************************* //
static void addNote(const string &note)
Add extra notes for the usage information.
Definition: argList.C:462
Ostream & indent(Ostream &os)
Indent stream.
Definition: Ostream.H:449
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:125
error FatalError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL ERROR&#39; header text and sta...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:578
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:49
label checkTopology(const polyMesh &mesh, const bool allTopology, const bool allGeometry, autoPtr< surfaceWriter > &surfWriter, autoPtr< coordSetWriter > &setWriter, const bool writeBadEdges=false)
engineTime & runTime
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:487
List< T > getList(const label index) const
Get a List of values from the argument at index.
static void addBoolOption(const word &optName, const string &usage="", bool advanced=false)
Add a bool option to validOptions with usage information.
Definition: argList.C:374
Ignore writing from objectRegistry::writeObject()
T getOrDefault(const word &optName, const T &deflt) const
Get a value from the named option if present, or return default.
Definition: argListI.H:300
IOdictionary is derived from dictionary and IOobject to give the dictionary automatic IO functionalit...
Definition: IOdictionary.H:50
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:414
label size() const noexcept
The number of elements in table.
Definition: HashTable.H:331
static autoPtr< coordSetWriter > New(const word &writeFormat)
Return a reference to the selected writer.
dynamicFvMesh & mesh
virtual readUpdateState readUpdate()
Update the mesh based on the mesh files saved in time.
Definition: fvMesh.C:671
static polyMesh::readUpdateState combine(const polyMesh::readUpdateState &state0, const polyMesh::readUpdateState &state1)
Combine readUpdateState. topo change trumps geom-only change etc.
A class for handling words, derived from Foam::string.
Definition: word.H:63
label size() const noexcept
The number of entries in the list.
Definition: UPtrListI.H:113
Foam::PtrList< Foam::fvMesh > meshes(regionNames.size())
static void addOption(const word &optName, const string &param="", const string &usage="", bool advanced=false)
Add an option to validOptions with usage information.
Definition: argList.C:385
const globalMeshData & globalData() const
Return parallel info.
Definition: polyMesh.C:1300
virtual void setTime(const Time &t)
Reset the time and time-index to those of the given time.
Definition: Time.C:997
void writeFields(const fvMesh &mesh, const wordHashSet &selectedFields, const bool writeFaceFields)
static word timeName(const scalar t, const int precision=precision_)
Return time name of given scalar time formatted with the given precision.
Definition: Time.C:770
static instantList select0(Time &runTime, const argList &args)
Return the set of times selected based on the argList options and also set the runTime to the first i...
Definition: timeSelector.C:234
label checkMeshQuality(const polyMesh &mesh, const dictionary &dict, autoPtr< surfaceWriter > &writer)
void printMeshStats(const polyMesh &mesh, const bool allTopology)
A list of pointers to objects of type <T>, with allocation/deallocation management of the pointers...
Definition: List.H:55
List< Key > sortedToc() const
The table of contents (the keys) in sorted order.
Definition: HashTable.C:130
messageStream Info
Information stream (stdout output on master, null elsewhere)
Pointer management similar to std::unique_ptr, with some additional methods and type checking...
Definition: HashPtrTable.H:48
readUpdateState
Enumeration defining the state of the mesh after a read update.
Definition: polyMesh.H:89
int system(const std::string &command, const bool bg=false)
Execute the specified command via the shell.
Definition: POSIX.C:1702
Foam::argList args(argc, argv)
Defines the attributes of an object for which implicit objectRegistry management is supported...
Definition: IOobject.H:171
static autoPtr< surfaceWriter > New(const word &writeType)
Return a reference to the selected surfaceWriter.
Definition: surfaceWriter.C:80
bool found(const word &optName) const
Return true if the named option is found.
Definition: argListI.H:171
static void addOptions(const bool constant=true, const bool withZero=false)
Add timeSelector options to argList::validOptions.
Definition: timeSelector.C:101
Namespace for OpenFOAM.
FlatOutput::OutputAdaptor< Container, Delimiters > flatOutput(const Container &obj, Delimiters delim)
Global flatOutput() function with specified output delimiters.
Definition: FlatOutput.H:225
label checkGeometry(const polyMesh &mesh, const bool allGeometry, autoPtr< surfaceWriter > &surfWriter, autoPtr< coordSetWriter > &setWriter)
Required Variables.