1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd.
7 -------------------------------------------------------------------------------
9 This file is part of OpenFOAM.
11 OpenFOAM 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 2 of the License, or (at your
14 option) any later version.
16 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 You should have received a copy of the GNU General Public License
22 along with OpenFOAM; if not, write to the Free Software Foundation,
23 Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
29 Automatic split hex mesher. Refines and snaps to surface.
31 \*---------------------------------------------------------------------------*/
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"));
366 autoRefineDriver refineDriver
374 // Refinement parameters
375 refinementParameters refineParams(refineDict);
379 const_cast<Time&>(mesh.time())++;
382 refineDriver.doRefine(refineDict, refineParams, wantSnap, motionDict);
394 autoSnapDriver snapDriver
401 snapParameters snapParams(snapDict);
405 const_cast<Time&>(mesh.time())++;
408 snapDriver.doSnap(snapDict, motionDict, snapParams);
420 autoLayerDriver layerDriver(meshRefiner);
422 // Layer addition parameters
423 layerParameters layerParams(layerDict, mesh.boundaryMesh());
427 const_cast<Time&>(mesh.time())++;
448 Info<< "Finished meshing in = "
449 << runTime.elapsedCpuTime() << " s." << endl;
451 Info<< "End\n" << endl;
457 // ************************************************************************* //