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 #include "OFstream.H"
93 #include "JSONformatter.H"
94 
95 using namespace Foam;
96 
97 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
98 
99 int main(int argc, char *argv[])
100 {
102  (
103  "Checks validity of a mesh"
104  );
105 
107  #include "addAllRegionOptions.H"
108 
110  (
111  "noTopology",
112  "Skip checking the mesh topology"
113  );
115  (
116  "allGeometry",
117  "Include bounding box checks"
118  );
120  (
121  "allTopology",
122  "Include extra topology checks"
123  );
125  (
126  "writeAllFields",
127  "Write volFields with mesh quality parameters"
128  );
130  (
131  "writeAllSurfaceFields",
132  "Write surfaceFields with mesh quality parameters"
133  );
135  (
136  "writeFields",
137  "wordList",
138  "Write volFields with selected mesh quality parameters"
139  );
141  (
142  "meshQuality",
143  "Read user-defined mesh quality criteria from system/meshQualityDict"
144  );
146  (
147  "writeSets",
148  "surfaceFormat",
149  "Reconstruct and write all faceSets and cellSets in selected format"
150  );
152  (
153  "write-edges",
154  "Write bad edges (possibly relevant for finite-area) in vtk format"
155  );
156 
158  (
159  "writeChecks",
160  "word",
161  "Write checks to file in dictionary or JSON format"
162  );
163 
164 
165  #include "setRootCase.H"
166  #include "createTime.H"
167  #include "getAllRegionOptions.H"
169  #include "createNamedMeshes.H"
170 
171  const bool noTopology = args.found("noTopology");
172  const bool allGeometry = args.found("allGeometry");
173  const bool allTopology = args.found("allTopology");
174  const bool meshQuality = args.found("meshQuality");
175  const bool optWriteEdges = args.found("write-edges");
176 
177  const word surfaceFormat = args.getOrDefault<word>("writeSets", "");
178  const bool writeSets = surfaceFormat.size();
179 
180 
181  // All potential writeable fields
182  const wordHashSet allFields
183  ({
184  "nonOrthoAngle",
185  "faceWeight",
186  "skewness",
187  "cellDeterminant",
188  "aspectRatio",
189  "cellShapes",
190  "cellVolume",
191  "cellVolumeRatio",
192  "cellAspectRatio",
193  "minTetVolume",
194  "minPyrVolume",
195  "cellRegion",
196  "wallDistance",
197  "cellZone",
198  "faceZone"
199  });
200 
201  #include "writeMeshChecks.H"
202 
203  if (args.found("writeChecks"))
204  {
206  writeChecksFormatTypeNames.get(args.get<word>("writeChecks"));
207  }
208 
209  const bool writeFaceFields = args.found("writeAllSurfaceFields");
210  wordHashSet selectedFields;
211  if (args.found("writeFields"))
212  {
213  selectedFields = args.getList<word>("writeFields");
214  const wordHashSet badFields(selectedFields - allFields);
215 
216  if (!badFields.empty())
217  {
219  << "Illegal field(s): "
220  << flatOutput(badFields.sortedToc()) << nl
221  << "Valid fields: "
222  << flatOutput(allFields.sortedToc()) << nl
223  << exit(FatalError);
224  }
225  }
226  else if (args.found("writeAllFields"))
227  {
228  selectedFields = allFields;
229  }
230  else if (writeFaceFields)
231  {
233  << "Option 'writeAllSurfaceFields' only valid in combination"
234  << " with 'writeFields' or 'writeAllFields'"
235  << nl << exit(FatalError);
236  }
237 
238 
239  Info<< "Check mesh..." << nl;
240  Info().incrIndent();
241 
242  if (noTopology)
243  {
244  Info<< indent
245  << "Disabling all topology checks." << nl;
246  }
247  if (allTopology)
248  {
249  Info<< indent
250  << "Enabling all (cell, face, edge, point) topology checks." << nl;
251  }
252  if (allGeometry)
253  {
254  Info<< indent
255  << "Enabling all geometry checks." << nl;
256  }
257  if (meshQuality)
258  {
259  Info<< indent
260  << "Enabling user-defined geometry checks." << nl;
261  }
262  if (writeSets)
263  {
264  Info<< indent
265  << "Reconstructing and writing " << surfaceFormat
266  << " representation of all faceSets and cellSets." << nl;
267  }
268  if (selectedFields.size())
269  {
270  Info<< indent
271  << "Writing mesh quality as fields "
272  << flatOutput(selectedFields.sortedToc()) << nl;
273  }
274  if (optWriteEdges)
275  {
276  Info<< indent
277  << "Writing any bad edges in vtk format" << nl;
278  }
279  Info().decrIndent();
280  Info<< endl;
281 
282 
283  PtrList<IOdictionary> qualDict(meshes.size());
284  if (meshQuality)
285  {
286  forAll(meshes, meshi)
287  {
288  qualDict.set
289  (
290  meshi,
291  new IOdictionary
292  (
293  IOobject
294  (
295  "meshQualityDict",
296  meshes[meshi].time().system(),
297  meshes[meshi],
300  )
301  )
302  );
303  }
304  }
305 
306 
307  autoPtr<surfaceWriter> surfWriter;
308  autoPtr<coordSetWriter> setWriter;
309  if (writeSets)
310  {
311  surfWriter = surfaceWriter::New(surfaceFormat);
312  setWriter = coordSetWriter::New(coordSetWriters::vtkWriter::typeName);
313  }
314 
315 
316  forAll(timeDirs, timei)
317  {
318  runTime.setTime(timeDirs[timei], timei);
319 
320  // Get most changed of all meshes
322  for (auto& mesh : meshes)
323  {
324  state = polyMeshTools::combine(state, mesh.readUpdate());
325  }
326 
327 
328  if
329  (
330  !timei
331  || state == polyMesh::TOPO_CHANGE
332  || state == polyMesh::TOPO_PATCH_CHANGE
333  )
334  {
335  Info<< "Time = " << runTime.timeName() << nl << endl;
336 
337  forAll(meshes, meshi)
338  {
339  const auto& mesh = meshes[meshi];
340 
341  // Reconstruct globalMeshData
342  mesh.globalData();
343 
344  printMeshStats(mesh, allTopology);
345 
346  label nFailedChecks = 0;
347 
348  if (!noTopology)
349  {
350  nFailedChecks += checkTopology
351  (
352  mesh,
353  allTopology,
354  allGeometry,
355  surfWriter,
356  setWriter,
357  optWriteEdges
358  );
359  }
360 
361  nFailedChecks += checkGeometry
362  (
363  mesh,
364  allGeometry,
365  surfWriter,
366  setWriter
367  );
368 
369  if (meshQuality)
370  {
371  nFailedChecks +=
372  checkMeshQuality(mesh, qualDict[meshi], surfWriter);
373  }
374 
375 
376  // Note: no reduction in nFailedChecks necessary since is
377  // counter of checks, not counter of failed cells,faces
378  // etc.
379 
380  if (nFailedChecks == 0)
381  {
382  Info<< "\nMesh OK.\n" << endl;
383  }
384  else
385  {
386  Info<< "\nFailed " << nFailedChecks << " mesh checks.\n"
387  << endl;
388  }
389 
390 
391  // Write selected fields
392  Foam::writeFields(mesh, selectedFields, writeFaceFields);
393 
395  }
396  }
397  else if (state == polyMesh::POINTS_MOVED)
398  {
399  Info<< "Time = " << runTime.timeName() << nl << endl;
400 
401  forAll(meshes, meshi)
402  {
403  const auto& mesh = meshes[meshi];
404 
405  label nFailedChecks = checkGeometry
406  (
407  mesh,
408  allGeometry,
409  surfWriter,
410  setWriter
411  );
412 
413  if (meshQuality)
414  {
415  nFailedChecks +=
416  checkMeshQuality(mesh, qualDict[meshi], surfWriter);
417  }
418 
419 
420  if (nFailedChecks)
421  {
422  Info<< "\nFailed " << nFailedChecks << " mesh checks.\n"
423  << endl;
424  }
425  else
426  {
427  Info<< "\nMesh OK.\n" << endl;
428  }
429 
430 
431  // Write selected fields
432  Foam::writeFields(mesh, selectedFields, writeFaceFields);
433 
435  }
436  }
437  }
438 
439  Info<< "End\n" << endl;
440 
441  return 0;
442 }
443 
444 
445 // ************************************************************************* //
const Enum< writeChecksFormatType > writeChecksFormatTypeNames
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:493
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:608
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:50
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:531
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:421
label size() const noexcept
The number of elements in table.
Definition: HashTable.H:358
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:715
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:106
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 (demand-driven)
Definition: polyMesh.C:1311
virtual void setTime(const Time &t)
Reset the time and time-index to those of the given time.
Definition: Time.C:902
void writeFields(const fvMesh &mesh, const wordHashSet &selectedFields, const bool writeFaceFields)
static word timeName(const scalar t, const int precision=precision_)
Return a time name for the given scalar time value formatted with the given precision.
Definition: Time.C:714
writeChecksFormatType writeChecksFormat(writeChecksFormatType::none)
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:260
T get(const label index) const
Get a value from the argument at index.
Definition: argListI.H:271
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:163
Required Classes.
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:91
auto writeMeshChecks
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:180
static autoPtr< surfaceWriter > New(const word &writeType)
Select construct a surfaceWriter.
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.