1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | cfMesh: A library for mesh generation
5 \\ / A nd | Author: Franjo Juretic (franjo.juretic@c-fields.com)
6 \\/ M anipulation | Copyright (C) Creative Fields, Ltd.
7 -------------------------------------------------------------------------------
9 This file is part of cfMesh.
11 cfMesh 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 cfMesh 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 cfMesh. If not, see <http://www.gnu.org/licenses/>.
26 \*---------------------------------------------------------------------------*/
28 #include "tetMeshGenerator.H"
30 #include "demandDrivenData.H"
32 #include "meshOctreeCreator.H"
33 #include "tetMeshExtractorOctree.H"
34 #include "meshSurfaceEngine.H"
35 #include "meshSurfaceMapper.H"
36 #include "edgeExtractor.H"
37 #include "meshSurfaceEdgeExtractorNonTopo.H"
38 #include "surfaceMorpherCells.H"
39 #include "meshOptimizer.H"
40 #include "meshSurfaceOptimizer.H"
41 #include "topologicalCleaner.H"
42 #include "boundaryLayers.H"
43 #include "renameBoundaryPatches.H"
44 #include "checkMeshDict.H"
45 #include "triSurfacePatchManipulator.H"
46 #include "refineBoundaryLayers.H"
47 #include "triSurfaceMetaData.H"
48 #include "polyMeshGenGeometryModification.H"
49 #include "surfaceMeshGeometryModification.H"
53 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
58 // * * * * * * * * * * * * Private member functions * * * * * * * * * * * * //
60 void tetMeshGenerator::createTetMesh()
62 //- create tet Mesh from octree and Delaunay tets
63 tetMeshExtractorOctree tme(*octreePtr_, meshDict_, mesh_);
68 void tetMeshGenerator::surfacePreparation()
70 //- removes unnecessary cells and morph the boundary
71 //- such that there is only one boundary face per cell
72 //- It also checks topology of cells after morphing is performed
75 surfaceMorpherCells* cmPtr = new surfaceMorpherCells(mesh_);
77 deleteDemandDrivenData(cmPtr);
79 while( topologicalCleaner(mesh_).cleanTopology() );
82 void tetMeshGenerator::mapMeshToSurface()
84 //- calculate mesh surface
85 meshSurfaceEngine* msePtr = new meshSurfaceEngine(mesh_);
87 //- map mesh surface on the geometry surface
88 meshSurfaceMapper(*msePtr, *octreePtr_).mapVerticesOntoSurface();
90 //- untangle surface faces
91 meshSurfaceOptimizer(*msePtr, *octreePtr_).untangleSurface();
93 deleteDemandDrivenData(msePtr);
96 void tetMeshGenerator::extractPatches()
98 edgeExtractor extractor(mesh_, *octreePtr_);
100 Info << "Extracting edges" << endl;
101 extractor.extractEdges();
103 extractor.updateMeshPatches();
106 void tetMeshGenerator::mapEdgesAndCorners()
108 meshSurfaceEdgeExtractorNonTopo(mesh_, *octreePtr_);
111 void tetMeshGenerator::optimiseMeshSurface()
113 meshSurfaceEngine mse(mesh_);
114 meshSurfaceOptimizer(mse, *octreePtr_).optimizeSurface();
117 void tetMeshGenerator::generateBoundaryLayers()
119 if( meshDict_.found("boundaryLayers") )
121 boundaryLayers bl(mesh_);
123 const dictionary& bndLayers = meshDict_.subDict("boundaryLayers");
125 if( bndLayers.found("nLayers") )
127 const label nLayers = readLabel(bndLayers.lookup("nLayers"));
130 bl.addLayerForAllPatches();
132 else if( bndLayers.found("patchBoundaryLayers") )
134 const dictionary& patchLayers =
135 bndLayers.subDict("patchBoundaryLayers");
136 const wordList createLayers = patchLayers.toc();
138 forAll(createLayers, patchI)
139 bl.addLayerForPatch(createLayers[patchI]);
144 void tetMeshGenerator::optimiseFinalMesh()
146 //- final optimisation
147 bool enforceConstraints(false);
148 if( meshDict_.found("enforceGeometryConstraints") )
151 readBool(meshDict_.lookup("enforceGeometryConstraints"));
154 meshOptimizer optimizer(mesh_);
155 if( enforceConstraints )
156 optimizer.enforceConstraints();
158 optimizer.optimizeSurface(*octreePtr_);
160 optimizer.optimizeMeshFV();
161 optimizer.optimizeLowQualityFaces();
162 optimizer.optimizeBoundaryLayer(false);
163 optimizer.untangleMeshFV();
165 deleteDemandDrivenData(octreePtr_);
167 mesh_.clearAddressingData();
171 polyMeshGenGeometryModification meshMod(mesh_, meshDict_);
173 //- revert the mesh into the original space
174 meshMod.revertGeometryModification();
176 //- delete modified surface mesh
177 deleteDemandDrivenData(modSurfacePtr_);
181 void tetMeshGenerator::projectSurfaceAfterBackScaling()
183 if( !meshDict_.found("anisotropicSources") )
186 deleteDemandDrivenData(octreePtr_);
187 octreePtr_ = new meshOctree(*surfacePtr_);
193 ).createOctreeWithRefinedBoundary(20, 30);
195 //- calculate mesh surface
196 meshSurfaceEngine mse(mesh_);
198 //- pre-map mesh surface
199 meshSurfaceMapper mapper(mse, *octreePtr_);
201 //- map mesh surface on the geometry surface
202 mapper.mapVerticesOntoSurface();
207 void tetMeshGenerator::refBoundaryLayers()
209 if( meshDict_.isDict("boundaryLayers") )
211 refineBoundaryLayers refLayers(mesh_);
213 refineBoundaryLayers::readSettings(meshDict_, refLayers);
215 refLayers.refineLayers();
217 labelLongList pointsInLayer;
218 refLayers.pointsInBndLayer(pointsInLayer);
220 meshOptimizer opt(mesh_);
221 opt.lockPoints(pointsInLayer);
222 opt.untangleBoundaryLayer();
226 void tetMeshGenerator::replaceBoundaries()
228 renameBoundaryPatches rbp(mesh_, meshDict_);
231 void tetMeshGenerator::renumberMesh()
233 polyMeshGenModifier(mesh_).renumberMesh();
236 void tetMeshGenerator::generateMesh()
240 if( controller_.runCurrentStep("templateGeneration") )
245 if( controller_.runCurrentStep("surfaceTopology") )
247 surfacePreparation();
250 if( controller_.runCurrentStep("surfaceProjection") )
255 if( controller_.runCurrentStep("patchAssignment") )
260 if( controller_.runCurrentStep("edgeExtraction") )
262 mapEdgesAndCorners();
264 optimiseMeshSurface();
267 if( controller_.runCurrentStep("boundaryLayerGeneration") )
269 generateBoundaryLayers();
272 if( controller_.runCurrentStep("meshOptimisation") )
276 projectSurfaceAfterBackScaling();
279 if( controller_.runCurrentStep("boundaryLayerRefinement") )
288 controller_.workflowCompleted();
290 catch(const std::string& message)
292 Info << message << endl;
298 "void tetMeshGenerator::generateMesh()"
299 ) << "Meshing process terminated!" << endl;
303 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
305 // Construct from Time
306 tetMeshGenerator::tetMeshGenerator(const Time& time)
310 modSurfacePtr_(NULL),
328 checkMeshDict cmd(meshDict_);
331 const fileName surfaceFile = meshDict_.lookup("surfaceFile");
333 surfacePtr_ = new triSurf(runTime_.path()/surfaceFile);
337 //- save meta data with the mesh (surface mesh + its topology info)
338 triSurfaceMetaData sMetaData(*surfacePtr_);
339 const dictionary& surfMetaDict = sMetaData.metaData();
341 mesh_.metaData().add("surfaceFile", surfaceFile, true);
342 mesh_.metaData().add("surfaceMeta", surfMetaDict, true);
345 if( surfacePtr_->featureEdges().size() != 0 )
347 //- create surface patches based on the feature edges
348 //- and update the meshDict based on the given data
349 triSurfacePatchManipulator manipulator(*surfacePtr_);
351 const triSurf* surfaceWithPatches =
352 manipulator.surfaceWithPatches(&meshDict_);
354 //- delete the old surface and assign the new one
355 deleteDemandDrivenData(surfacePtr_);
356 surfacePtr_ = surfaceWithPatches;
359 if( meshDict_.found("anisotropicSources") )
361 surfaceMeshGeometryModification surfMod(*surfacePtr_, meshDict_);
363 modSurfacePtr_ = surfMod.modifyGeometry();
365 octreePtr_ = new meshOctree(*modSurfacePtr_);
369 octreePtr_ = new meshOctree(*surfacePtr_);
372 meshOctreeCreator(*octreePtr_, meshDict_).createOctreeBoxes();
377 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
379 tetMeshGenerator::~tetMeshGenerator()
381 deleteDemandDrivenData(surfacePtr_);
382 deleteDemandDrivenData(octreePtr_);
383 deleteDemandDrivenData(modSurfacePtr_);
386 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
388 void tetMeshGenerator::writeMesh() const
393 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
395 } // End namespace Foam
397 // ************************************************************************* //