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-2022 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 \*---------------------------------------------------------------------------*/
71 
72 #include "argList.H"
73 #include "timeSelector.H"
74 #include "Time.H"
75 #include "fvMesh.H"
76 #include "globalMeshData.H"
77 #include "vtkCoordSetWriter.H"
78 #include "vtkSurfaceWriter.H"
79 #include "IOdictionary.H"
80 #include "regionProperties.H"
81 #include "polyMeshTools.H"
82 
83 #include "checkTools.H"
84 #include "checkTopology.H"
85 #include "checkGeometry.H"
86 #include "checkMeshQuality.H"
87 #include "writeFields.H"
88 
89 using namespace Foam;
90 
91 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
92 
93 int main(int argc, char *argv[])
94 {
96  (
97  "Checks validity of a mesh"
98  );
99 
101  #include "addAllRegionOptions.H"
102 
104  (
105  "noTopology",
106  "Skip checking the mesh topology"
107  );
109  (
110  "allGeometry",
111  "Include bounding box checks"
112  );
114  (
115  "allTopology",
116  "Include extra topology checks"
117  );
119  (
120  "writeAllFields",
121  "Write volFields with mesh quality parameters"
122  );
124  (
125  "writeAllSurfaceFields",
126  "Write surfaceFields with mesh quality parameters"
127  );
129  (
130  "writeFields",
131  "wordList",
132  "Write volFields with selected mesh quality parameters"
133  );
135  (
136  "meshQuality",
137  "Read user-defined mesh quality criteria from system/meshQualityDict"
138  );
140  (
141  "writeSets",
142  "surfaceFormat",
143  "Reconstruct and write all faceSets and cellSets in selected format"
144  );
145 
146  #include "setRootCase.H"
147  #include "createTime.H"
148  #include "getAllRegionOptions.H"
150  #include "createNamedMeshes.H"
151 
152  const bool noTopology = args.found("noTopology");
153  const bool allGeometry = args.found("allGeometry");
154  const bool allTopology = args.found("allTopology");
155  const bool meshQuality = args.found("meshQuality");
156 
157  const word surfaceFormat = args.getOrDefault<word>("writeSets", "");
158  const bool writeSets = surfaceFormat.size();
159 
160 
161  // All potential writeable fields
162  const wordHashSet allFields
163  ({
164  "nonOrthoAngle",
165  "faceWeight",
166  "skewness",
167  "cellDeterminant",
168  "aspectRatio",
169  "cellShapes",
170  "cellVolume",
171  "cellVolumeRatio",
172  "cellAspectRatio",
173  "minTetVolume",
174  "minPyrVolume",
175  "cellRegion",
176  "wallDistance",
177  "cellZone",
178  "faceZone"
179  });
180 
181  const bool writeFaceFields = args.found("writeAllSurfaceFields");
182  wordHashSet selectedFields;
183  if (args.found("writeFields"))
184  {
185  selectedFields = args.getList<word>("writeFields");
186  const wordHashSet badFields(selectedFields - allFields);
187 
188  if (!badFields.empty())
189  {
191  << "Illegal field(s) " << flatOutput(badFields.sortedToc())
192  << nl
193  << "Valid fields are " << flatOutput(allFields.sortedToc())
194  << nl << exit(FatalError);
195  }
196  }
197  else if (args.found("writeAllFields"))
198  {
199  selectedFields = allFields;
200  }
201  else if (writeFaceFields)
202  {
204  << "Option 'writeAllSurfaceFields' only valid in combination"
205  << " with 'writeFields' or 'writeAllFields'"
206  << nl << exit(FatalError);
207  }
208 
209 
210  if (noTopology)
211  {
212  Info<< "Disabling all topology checks." << nl << endl;
213  }
214  if (allTopology)
215  {
216  Info<< "Enabling all (cell, face, edge, point) topology checks."
217  << nl << endl;
218  }
219  if (allGeometry)
220  {
221  Info<< "Enabling all geometry checks." << nl << endl;
222  }
223  if (meshQuality)
224  {
225  Info<< "Enabling user-defined geometry checks." << nl << endl;
226  }
227  if (writeSets)
228  {
229  Info<< "Reconstructing and writing " << surfaceFormat
230  << " representation"
231  << " of all faceSets and cellSets." << nl << endl;
232  }
233  if (selectedFields.size())
234  {
235  Info<< "Writing mesh quality as fields " << selectedFields << nl
236  << endl;
237  }
238 
239 
240  PtrList<IOdictionary> qualDict(meshes.size());
241  if (meshQuality)
242  {
243  forAll(meshes, meshi)
244  {
245  qualDict.set
246  (
247  meshi,
248  new IOdictionary
249  (
250  IOobject
251  (
252  "meshQualityDict",
253  meshes[meshi].time().system(),
254  meshes[meshi],
257  )
258  )
259  );
260  }
261  }
262 
263 
264  autoPtr<surfaceWriter> surfWriter;
265  autoPtr<coordSetWriter> setWriter;
266  if (writeSets)
267  {
268  surfWriter = surfaceWriter::New(surfaceFormat);
269  setWriter = coordSetWriter::New(coordSetWriters::vtkWriter::typeName);
270  }
271 
272 
273  forAll(timeDirs, timeI)
274  {
275  runTime.setTime(timeDirs[timeI], timeI);
276 
277  // Get most changed of all meshes
279  for (auto& mesh : meshes)
280  {
281  state = polyMeshTools::combine(state, mesh.readUpdate());
282  }
283 
284 
285  if
286  (
287  !timeI
288  || state == polyMesh::TOPO_CHANGE
289  || state == polyMesh::TOPO_PATCH_CHANGE
290  )
291  {
292  Info<< "Time = " << runTime.timeName() << nl << endl;
293 
294  forAll(meshes, meshi)
295  {
296  const auto& mesh = meshes[meshi];
297 
298  // Reconstruct globalMeshData
299  mesh.globalData();
300 
301  printMeshStats(mesh, allTopology);
302 
303  label nFailedChecks = 0;
304 
305  if (!noTopology)
306  {
307  nFailedChecks += checkTopology
308  (
309  mesh,
310  allTopology,
311  allGeometry,
312  surfWriter,
313  setWriter
314  );
315  }
316 
317  nFailedChecks += checkGeometry
318  (
319  mesh,
320  allGeometry,
321  surfWriter,
322  setWriter
323  );
324 
325  if (meshQuality)
326  {
327  nFailedChecks +=
328  checkMeshQuality(mesh, qualDict[meshi], surfWriter);
329  }
330 
331 
332  // Note: no reduction in nFailedChecks necessary since is
333  // counter of checks, not counter of failed cells,faces
334  // etc.
335 
336  if (nFailedChecks == 0)
337  {
338  Info<< "\nMesh OK.\n" << endl;
339  }
340  else
341  {
342  Info<< "\nFailed " << nFailedChecks << " mesh checks.\n"
343  << endl;
344  }
345 
346 
347  // Write selected fields
348  Foam::writeFields(mesh, selectedFields, writeFaceFields);
349  }
350  }
351  else if (state == polyMesh::POINTS_MOVED)
352  {
353  Info<< "Time = " << runTime.timeName() << nl << endl;
354 
355  forAll(meshes, meshi)
356  {
357  const auto& mesh = meshes[meshi];
358 
359  label nFailedChecks = checkGeometry
360  (
361  mesh,
362  allGeometry,
363  surfWriter,
364  setWriter
365  );
366 
367  if (meshQuality)
368  {
369  nFailedChecks +=
370  checkMeshQuality(mesh, qualDict[meshi], surfWriter);
371  }
372 
373 
374  if (nFailedChecks)
375  {
376  Info<< "\nFailed " << nFailedChecks << " mesh checks.\n"
377  << endl;
378  }
379  else
380  {
381  Info<< "\nMesh OK.\n" << endl;
382  }
383 
384 
385  // Write selected fields
386  Foam::writeFields(mesh, selectedFields, writeFaceFields);
387  }
388  }
389  }
390 
391  Info<< "End\n" << endl;
392 
393  return 0;
394 }
395 
396 
397 // ************************************************************************* //
label checkTopology(const polyMesh &mesh, const bool allTopology, const bool allGeometry, autoPtr< surfaceWriter > &surfWriter, autoPtr< coordSetWriter > &setWriter)
static void addNote(const string &note)
Add extra notes for the usage information.
Definition: argList.C:453
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
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:365
label size() const noexcept
The number of elements in table.
Definition: HashTableI.H:45
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:413
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:668
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 elements in the list.
Definition: UPtrListI.H:99
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:376
const globalMeshData & globalData() const
Return parallel info.
Definition: polyMesh.C:1293
virtual void setTime(const Time &t)
Reset the time and time-index to those of the given time.
Definition: Time.C:977
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:760
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
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:1655
Foam::argList args(argc, argv)
Defines the attributes of an object for which implicit objectRegistry management is supported...
Definition: IOobject.H:166
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.