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-------------------------------------------------------------------------------
11License
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
27Application
28 checkMesh
29
30Group
31 grpMeshManipulationUtilities
32
33Description
34 Checks validity of a mesh.
35
36Usage
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
89using namespace Foam;
90
91// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
92
93int main(int argc, char *argv[])
94{
95 argList::addNote
96 (
97 "Checks validity of a mesh"
98 );
99
100 timeSelector::addOptions();
101 #include "addAllRegionOptions.H"
102
103 argList::addBoolOption
104 (
105 "noTopology",
106 "Skip checking the mesh topology"
107 );
108 argList::addBoolOption
109 (
110 "allGeometry",
111 "Include bounding box checks"
112 );
113 argList::addBoolOption
114 (
115 "allTopology",
116 "Include extra topology checks"
117 );
118 argList::addBoolOption
119 (
120 "writeAllFields",
121 "Write volFields with mesh quality parameters"
122 );
123 argList::addBoolOption
124 (
125 "writeAllSurfaceFields",
126 "Write surfaceFields with mesh quality parameters"
127 );
128 argList::addOption
129 (
130 "writeFields",
131 "wordList",
132 "Write volFields with selected mesh quality parameters"
133 );
134 argList::addBoolOption
135 (
136 "meshQuality",
137 "Read user-defined mesh quality criteria from system/meshQualityDict"
138 );
139 argList::addOption
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"
149 instantList timeDirs = timeSelector::select0(runTime, args);
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
241 if (meshQuality)
242 {
243 forAll(meshes, meshi)
244 {
245 qualDict.set
246 (
247 meshi,
248 new IOdictionary
249 (
251 (
252 "meshQualityDict",
253 meshes[meshi].time().system(),
254 meshes[meshi],
255 IOobject::MUST_READ,
256 IOobject::NO_WRITE
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
278 polyMesh::readUpdateState state = polyMesh::UNCHANGED;
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 size() const noexcept
The number of elements in table.
Definition: HashTableI.H:52
IOdictionary is derived from dictionary and IOobject to give the dictionary automatic IO functionalit...
Definition: IOdictionary.H:57
Defines the attributes of an object for which implicit objectRegistry management is supported,...
Definition: IOobject.H:170
A list of pointers to objects of type <T>, with allocation/deallocation management of the pointers....
Definition: PtrList.H:73
label size() const noexcept
The number of elements in the list.
Definition: UPtrListI.H:106
bool found(const word &optName) const
Return true if the named option is found.
Definition: argListI.H:178
List< T > getList(const label index) const
Get a List of values from the argument at index.
T getOrDefault(const word &optName, const T &deflt) const
Get a value from the named option if present, or return default.
Definition: argListI.H:307
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
Definition: autoPtr.H:66
readUpdateState
Enumeration defining the state of the mesh after a read update.
Definition: polyMesh.H:91
A class for handling words, derived from Foam::string.
Definition: word.H:68
dynamicFvMesh & mesh
engineTime & runTime
Required Variables.
Foam::PtrList< Foam::fvMesh > meshes(regionNames.size())
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
Namespace for OpenFOAM.
int system(const std::string &command, const bool bg=false)
Execute the specified command via the shell.
Definition: MSwindows.C:1158
label checkMeshQuality(const polyMesh &mesh, const dictionary &dict, autoPtr< surfaceWriter > &writer)
label checkGeometry(const polyMesh &mesh, const bool allGeometry, autoPtr< surfaceWriter > &surfWriter, autoPtr< coordSetWriter > &setWriter)
label checkTopology(const polyMesh &mesh, const bool allTopology, const bool allGeometry, autoPtr< surfaceWriter > &surfWriter, autoPtr< coordSetWriter > &setWriter)
messageStream Info
Information stream (stdout output on master, null elsewhere)
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:372
FlatOutput::OutputAdaptor< Container, Delimiters > flatOutput(const Container &obj, Delimiters delim)
Global flatOutput() function with specified output delimiters.
Definition: FlatOutput.H:215
void writeFields(const fvMesh &mesh, const wordHashSet &selectedFields, const bool writeFaceFields)
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
void printMeshStats(const polyMesh &mesh, const bool allTopology)
constexpr char nl
The newline '\n' character (0x0a)
Definition: Ostream.H:53
Foam::argList args(argc, argv)
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:333