1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | foam-extend: Open Source CFD
4 \\ / O peration | Version: 3.2
5 \\ / A nd | Web: http://www.foam-extend.org
6 \\/ M anipulation | For copyright notice see file Copyright
7 -------------------------------------------------------------------------------
9 This file is part of foam-extend.
11 foam-extend is free software: you can redistribute it and/or modify it
12 under the terms of the GNU General Public License as published by the
13 Free Software Foundation, either version 3 of the License, or (at your
14 option) any later version.
16 foam-extend is distributed in the hope that it will be useful, but
17 WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with foam-extend. If not, see <http://www.gnu.org/licenses/>.
28 Automatic split hex mesher. Refines and snaps to surface.
30 \*---------------------------------------------------------------------------*/
33 #include "objectRegistry.H"
36 #include "autoRefineDriver.H"
37 #include "autoSnapDriver.H"
38 #include "autoLayerDriver.H"
39 #include "searchableSurfaces.H"
40 #include "refinementSurfaces.H"
41 #include "shellSurfaces.H"
42 #include "decompositionMethod.H"
43 #include "fvMeshDistribute.H"
44 #include "wallPolyPatch.H"
45 #include "refinementParameters.H"
46 #include "snapParameters.H"
47 #include "layerParameters.H"
52 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
54 // Check writing tolerance before doing any serious work
55 scalar getMergeDistance(const polyMesh& mesh, const scalar mergeTol)
57 const boundBox& meshBb = mesh.bounds();
58 scalar mergeDist = mergeTol * meshBb.mag();
59 scalar writeTol = std::pow
62 -scalar(IOstream::defaultPrecision())
66 << "Overall mesh bounding box : " << meshBb << nl
67 << "Relative tolerance : " << mergeTol << nl
68 << "Absolute matching distance : " << mergeDist << nl
71 if (mesh.time().writeFormat() == IOstream::ASCII && mergeTol < writeTol)
73 FatalErrorIn("getMergeDistance(const polyMesh&, const scalar)")
74 << "Your current settings specify ASCII writing with "
75 << IOstream::defaultPrecision() << " digits precision." << endl
76 << "Your merging tolerance (" << mergeTol << ") is finer than this."
78 << "Please change your writeFormat to binary"
79 << " or increase the writePrecision" << endl
80 << "or adjust the merge tolerance (-mergeTol)."
88 // Write mesh and additional information
92 const meshRefinement& meshRefiner,
96 const fvMesh& mesh = meshRefiner.mesh();
98 meshRefiner.printMeshInfo(debug, msg);
99 Info<< "Writing mesh to time " << meshRefiner.timeName() << endl;
101 meshRefiner.write(meshRefinement::MESH|meshRefinement::SCALARLEVELS, "");
102 if (debug & meshRefinement::OBJINTERSECTIONS)
106 meshRefinement::OBJINTERSECTIONS,
107 mesh.time().path()/meshRefiner.timeName()
110 Info<< "Written mesh in = "
111 << mesh.time().cpuTimeIncrement() << " s." << endl;
116 int main(int argc, char *argv[])
118 argList::validOptions.insert("overwrite", "");
119 # include "setRootCase.H"
120 # include "createTime.H"
121 runTime.functionObjects().off();
122 # include "createMesh.H"
124 Info<< "Read mesh in = "
125 << runTime.cpuTimeIncrement() << " s" << endl;
127 const bool overwrite = args.optionFound("overwrite");
130 // Check patches and faceZones are synchronised
131 mesh.boundaryMesh().checkParallelSync(true);
132 meshRefinement::checkCoupledFaceZones(mesh);
135 // Read decomposePar dictionary
136 IOdictionary decomposeDict
148 // Read meshing dictionary
149 IOdictionary meshDict
161 // all surface geometry
162 const dictionary& geometryDict = meshDict.subDict("geometry");
164 // refinement parameters
165 const dictionary& refineDict = meshDict.subDict("castellatedMeshControls");
167 // mesh motion and mesh quality parameters
168 const dictionary& motionDict = meshDict.subDict("meshQualityControls");
170 // snap-to-surface parameters
171 const dictionary& snapDict = meshDict.subDict("snapControls");
173 // layer addition parameters
174 const dictionary& layerDict = meshDict.subDict("addLayersControls");
177 const scalar mergeDist = getMergeDistance
180 readScalar(meshDict.lookup("mergeTolerance"))
188 const label debug(readLabel(meshDict.lookup("debug")));
191 meshRefinement::debug = debug;
192 autoRefineDriver::debug = debug;
193 autoSnapDriver::debug = debug;
194 autoLayerDriver::debug = debug;
201 searchableSurfaces allGeometry
206 mesh.time().constant(), // instance
207 //mesh.time().findInstance("triSurface", word::null),// instance
208 "triSurface", // local
209 mesh.time(), // registry
217 // Read refinement surfaces
218 // ~~~~~~~~~~~~~~~~~~~~~~~~
220 Info<< "Reading refinement surfaces." << endl;
221 refinementSurfaces surfaces
224 refineDict.subDict("refinementSurfaces")
226 Info<< "Read refinement surfaces in = "
227 << mesh.time().cpuTimeIncrement() << " s" << nl << endl;
230 // Read refinement shells
231 // ~~~~~~~~~~~~~~~~~~~~~~
233 Info<< "Reading refinement shells." << endl;
237 refineDict.subDict("refinementRegions")
239 Info<< "Read refinement shells in = "
240 << mesh.time().cpuTimeIncrement() << " s" << nl << endl;
243 Info<< "Setting refinement level of surface to be consistent"
244 << " with shells." << endl;
245 surfaces.setMinLevelFields(shells);
246 Info<< "Checked shell refinement in = "
247 << mesh.time().cpuTimeIncrement() << " s" << nl << endl;
254 << "Determining initial surface intersections" << nl
255 << "-----------------------------------------" << nl
258 // Main refinement engine
259 meshRefinement meshRefiner
262 mergeDist, // tolerance used in sorting coordinates
263 overwrite, // overwrite mesh files?
264 surfaces, // for surface intersection refinement
265 shells // for volume (inside/outside) refinement
267 Info<< "Calculated surface intersections in = "
268 << mesh.time().cpuTimeIncrement() << " s" << nl << endl;
271 meshRefiner.printMeshInfo(debug, "Initial mesh");
275 debug&meshRefinement::OBJINTERSECTIONS,
276 mesh.time().path()/meshRefiner.timeName()
280 // Add all the surface regions as patches
281 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
283 labelList globalToPatch;
286 << "Adding patches for surface regions" << nl
287 << "----------------------------------" << nl
290 // From global region number to mesh patch.
291 globalToPatch.setSize(surfaces.nRegions(), -1);
293 Info<< "Patch\tRegion" << nl
297 const labelList& surfaceGeometry = surfaces.surfaces();
298 forAll(surfaceGeometry, surfI)
300 label geomI = surfaceGeometry[surfI];
302 const wordList& regNames = allGeometry.regionNames()[geomI];
304 Info<< surfaces.names()[surfI] << ':' << nl << nl;
308 label patchI = meshRefiner.addMeshedPatch
311 wallPolyPatch::typeName
314 Info<< patchI << '\t' << regNames[i] << nl;
316 globalToPatch[surfaces.globalRegion(surfI, i)] = patchI;
321 Info<< "Added patches in = "
322 << mesh.time().cpuTimeIncrement() << " s" << nl << endl;
330 autoPtr<decompositionMethod> decomposerPtr
332 decompositionMethod::New
338 decompositionMethod& decomposer = decomposerPtr();
340 if (Pstream::parRun() && !decomposer.parallelAware())
342 FatalErrorIn(args.executable())
343 << "You have selected decomposition method "
344 << decomposer.typeName
345 << " which is not parallel aware." << endl
346 << "Please select one that is (hierarchical, parMetis)"
350 // Mesh distribution engine (uses tolerance to reconstruct meshes)
351 fvMeshDistribute distributor(mesh, mergeDist);
357 // Now do the real work -refinement -snapping -layers
358 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
360 Switch wantRefine(meshDict.lookup("castellatedMesh"));
361 Switch wantSnap(meshDict.lookup("snap"));
362 Switch wantLayers(meshDict.lookup("addLayers"));
368 autoRefineDriver refineDriver
376 // Refinement parameters
377 refinementParameters refineParams(refineDict);
381 const_cast<Time&>(mesh.time())++;
384 refineDriver.doRefine(refineDict, refineParams, wantSnap, motionDict);
393 Info<< "Mesh refined in = "
394 << timer.cpuTimeIncrement() << " s." << endl;
401 autoSnapDriver snapDriver
408 snapParameters snapParams(snapDict);
412 const_cast<Time&>(mesh.time())++;
415 snapDriver.doSnap(snapDict, motionDict, snapParams);
424 Info<< "Mesh snapped in = "
425 << timer.cpuTimeIncrement() << " s." << endl;
432 autoLayerDriver layerDriver(meshRefiner);
434 // Layer addition parameters
435 layerParameters layerParams(layerDict, mesh.boundaryMesh());
437 //!!! Temporary hack to get access to maxLocalCells
440 refinementParameters refineParams(refineDict);
442 preBalance = returnReduce
444 (mesh.nCells() >= refineParams.maxLocalCells()),
452 const_cast<Time&>(mesh.time())++;
472 Info<< "Layers added in = "
473 << timer.cpuTimeIncrement() << " s." << endl;
477 Info<< "Finished meshing in = "
478 << runTime.elapsedCpuTime() << " s." << endl;
480 Info<< "End\n" << endl;
486 // ************************************************************************* //