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 "voronoiMeshGenerator.H"
30 #include "demandDrivenData.H"
31 #include "objectRegistry.H"
33 #include "meshOctreeCreator.H"
34 #include "voronoiMeshExtractor.H"
35 #include "meshSurfaceEngine.H"
36 #include "meshSurfaceMapper.H"
37 #include "surfaceMorpherCells.H"
38 #include "meshOptimizer.H"
39 #include "meshSurfaceOptimizer.H"
40 #include "topologicalCleaner.H"
41 #include "boundaryLayers.H"
42 #include "refineBoundaryLayers.H"
43 #include "renameBoundaryPatches.H"
44 #include "checkMeshDict.H"
45 #include "triSurfacePatchManipulator.H"
46 #include "triSurfaceMetaData.H"
47 #include "surfaceMeshGeometryModification.H"
48 #include "polyMeshGenGeometryModification.H"
49 #include "edgeExtractor.H"
50 #include "meshSurfaceEdgeExtractorFUN.H"
54 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
59 // * * * * * * * * * * * * Private member functions * * * * * * * * * * * * //
61 void voronoiMeshGenerator::createVoronoiMesh()
63 //- create voronoi mesh from octree and Delaunay tets
64 voronoiMeshExtractor vme(*octreePtr_, meshDict_, mesh_);
70 //::exit(EXIT_FAILURE);
74 void voronoiMeshGenerator::surfacePreparation()
76 //- removes unnecessary cells and morphs the boundary
77 //- such that there exists only one boundary face per cell
79 surfaceMorpherCells* cmPtr = new surfaceMorpherCells(mesh_);
81 deleteDemandDrivenData(cmPtr);
85 //::exit(EXIT_FAILURE);
89 void voronoiMeshGenerator::mapMeshToSurface()
91 //- calculate mesh surface
92 meshSurfaceEngine* msePtr = new meshSurfaceEngine(mesh_);
94 //- map mesh surface on the geometry surface
95 meshSurfaceMapper mapper(*msePtr, *octreePtr_);
96 mapper.preMapVertices();
97 mapper.mapVerticesOntoSurface();
101 //::exit(EXIT_FAILURE);
104 //- untangle surface faces
105 meshSurfaceOptimizer(*msePtr, *octreePtr_).untangleSurface();
109 ::exit(EXIT_FAILURE);
112 deleteDemandDrivenData(msePtr);
115 void voronoiMeshGenerator::extractPatches()
117 edgeExtractor extractor(mesh_, *octreePtr_);
119 Info << "Extracting edges" << endl;
120 extractor.extractEdges();
122 extractor.updateMeshPatches();
125 void voronoiMeshGenerator::mapEdgesAndCorners()
127 meshSurfaceEdgeExtractorFUN(mesh_, *octreePtr_, false);
131 //::exit(EXIT_FAILURE);
135 void voronoiMeshGenerator::optimiseMeshSurface()
137 meshSurfaceEngine mse(mesh_);
138 meshSurfaceOptimizer surfOptimiser(mse, *octreePtr_);
139 surfOptimiser.optimizeSurface();
140 surfOptimiser.untangleSurface();
144 //::exit(EXIT_FAILURE);
148 void voronoiMeshGenerator::generateBoudaryLayers()
150 boundaryLayers bl(mesh_);
152 if( meshDict_.found("boundaryLayers") )
154 boundaryLayers bl(mesh_);
156 const dictionary& bndLayers = meshDict_.subDict("boundaryLayers");
158 if( bndLayers.found("nLayers") )
160 const label nLayers = readLabel(bndLayers.lookup("nLayers"));
163 bl.addLayerForAllPatches();
165 else if( bndLayers.found("patchBoundaryLayers") )
167 const dictionary& patchLayers =
168 bndLayers.subDict("patchBoundaryLayers");
169 const wordList createLayers = patchLayers.toc();
171 forAll(createLayers, patchI)
172 bl.addLayerForPatch(createLayers[patchI]);
178 //::exit(EXIT_FAILURE);
182 void voronoiMeshGenerator::refBoundaryLayers()
184 if( meshDict_.isDict("boundaryLayers") )
186 refineBoundaryLayers refLayers(mesh_);
188 refineBoundaryLayers::readSettings(meshDict_, refLayers);
190 refLayers.refineLayers();
192 labelLongList pointsInLayer;
193 refLayers.pointsInBndLayer(pointsInLayer);
195 meshOptimizer mOpt(mesh_);
196 mOpt.lockPoints(pointsInLayer);
197 mOpt.untangleBoundaryLayer();
201 void voronoiMeshGenerator::optimiseFinalMesh()
203 //- untangle the surface if needed
204 bool enforceConstraints(false);
205 if( meshDict_.found("enforceGeometryConstraints") )
208 readBool(meshDict_.lookup("enforceGeometryConstraints"));
213 meshSurfaceEngine mse(mesh_);
214 meshSurfaceOptimizer surfOpt(mse, *octreePtr_);
216 if( enforceConstraints )
217 surfOpt.enforceConstraints();
219 surfOpt.optimizeSurface();
222 deleteDemandDrivenData(octreePtr_);
224 //- final optimisation
225 meshOptimizer optimizer(mesh_);
226 if( enforceConstraints )
227 optimizer.enforceConstraints();
228 optimizer.optimizeMeshFV();
230 optimizer.optimizeLowQualityFaces();
231 optimizer.optimizeBoundaryLayer(false);
232 optimizer.untangleMeshFV();
234 mesh_.clearAddressingData();
238 polyMeshGenGeometryModification meshMod(mesh_, meshDict_);
240 //- revert the mesh into the original space
241 meshMod.revertGeometryModification();
243 //- delete modified surface mesh
244 deleteDemandDrivenData(modSurfacePtr_);
253 void voronoiMeshGenerator::projectSurfaceAfterBackScaling()
255 if( !meshDict_.found("anisotropicSources") )
258 deleteDemandDrivenData(octreePtr_);
259 octreePtr_ = new meshOctree(*surfacePtr_);
265 ).createOctreeWithRefinedBoundary(20, 30);
267 //- calculate mesh surface
268 meshSurfaceEngine mse(mesh_);
270 //- pre-map mesh surface
271 meshSurfaceMapper mapper(mse, *octreePtr_);
273 //- map mesh surface on the geometry surface
274 mapper.mapVerticesOntoSurface();
279 void voronoiMeshGenerator::replaceBoundaries()
281 renameBoundaryPatches rbp(mesh_, meshDict_);
289 void voronoiMeshGenerator::renumberMesh()
291 polyMeshGenModifier(mesh_).renumberMesh();
299 void voronoiMeshGenerator::generateMesh()
303 if( controller_.runCurrentStep("templateGeneration") )
308 if( controller_.runCurrentStep("surfaceTopology") )
310 surfacePreparation();
313 if( controller_.runCurrentStep("surfaceProjection") )
318 if( controller_.runCurrentStep("patchAssignment") )
323 if( controller_.runCurrentStep("edgeExtraction") )
325 mapEdgesAndCorners();
327 optimiseMeshSurface();
330 if( controller_.runCurrentStep("boundaryLayerGeneration") )
332 generateBoudaryLayers();
335 if( controller_.runCurrentStep("meshOptimisation") )
339 projectSurfaceAfterBackScaling();
342 if( controller_.runCurrentStep("boundaryLayerRefinement") )
351 catch(const std::string& message)
353 Info << message << endl;
359 "void voronoiMeshGenerator::generateMesh()"
360 ) << "Meshing process terminated!" << endl;
364 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
366 voronoiMeshGenerator::voronoiMeshGenerator(const Time& time)
370 modSurfacePtr_(NULL),
372 pointRegionsPtr_(NULL),
388 checkMeshDict cmd(meshDict_);
390 const fileName surfaceFile = meshDict_.lookup("surfaceFile");
392 surfacePtr_ = new triSurf(runTime_.path()/surfaceFile);
396 //- save meta data with the mesh (surface mesh + its topology info)
397 triSurfaceMetaData sMetaData(*surfacePtr_);
398 const dictionary& surfMetaDict = sMetaData.metaData();
400 mesh_.metaData().add("surfaceFile", surfaceFile, true);
401 mesh_.metaData().add("surfaceMeta", surfMetaDict, true);
404 if( surfacePtr_->featureEdges().size() != 0 )
406 //- create surface patches based on the feature edges
407 //- and update the meshDict based on the given data
408 triSurfacePatchManipulator manipulator(*surfacePtr_);
410 const triSurf* surfaceWithPatches =
411 manipulator.surfaceWithPatches(&meshDict_);
413 //- delete the old surface and assign the new one
414 deleteDemandDrivenData(surfacePtr_);
415 surfacePtr_ = surfaceWithPatches;
418 if( meshDict_.found("anisotropicSources") )
420 surfaceMeshGeometryModification surfMod(*surfacePtr_, meshDict_);
422 modSurfacePtr_ = surfMod.modifyGeometry();
424 octreePtr_ = new meshOctree(*modSurfacePtr_);
428 octreePtr_ = new meshOctree(*surfacePtr_);
431 meshOctreeCreator(*octreePtr_, meshDict_).createOctreeBoxes();
436 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
438 voronoiMeshGenerator::~voronoiMeshGenerator()
440 deleteDemandDrivenData(surfacePtr_);
441 deleteDemandDrivenData(modSurfacePtr_);
442 deleteDemandDrivenData(octreePtr_);
443 deleteDemandDrivenData(pointRegionsPtr_);
446 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
448 void voronoiMeshGenerator::writeMesh() const
453 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
455 } // End namespace Foam
457 // ************************************************************************* //