Merge branch 'master' of ssh://git.code.sf.net/p/foam-extend/foam-extend-3.2
[foam-extend-3.2.git] / src / mesh / cfMesh / voronoiMesh / voronoiMeshGenerator / voronoiMeshGenerator.C
blob40849cfb5418756a555e52462f97b769d4c3ad68
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | cfMesh: A library for mesh generation
4    \\    /   O peration     |
5     \\  /    A nd           | Author: Franjo Juretic (franjo.juretic@c-fields.com)
6      \\/     M anipulation  | Copyright (C) Creative Fields, Ltd.
7 -------------------------------------------------------------------------------
8 License
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
19     for more details.
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/>.
24 Description
26 \*---------------------------------------------------------------------------*/
28 #include "voronoiMeshGenerator.H"
29 #include "triSurf.H"
30 #include "demandDrivenData.H"
31 #include "objectRegistry.H"
32 #include "foamTime.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"
52 //#define DEBUG
54 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
56 namespace Foam
59 // * * * * * * * * * * * * Private member functions  * * * * * * * * * * * * //
61 void voronoiMeshGenerator::createVoronoiMesh()
63     //- create voronoi mesh from octree and Delaunay tets
64     voronoiMeshExtractor vme(*octreePtr_, meshDict_, mesh_);
66     vme.createMesh();
68     # ifdef DEBUG
69     mesh_.write();
70     //::exit(EXIT_FAILURE);
71     # endif
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_);
80     cmPtr->morphMesh();
81     deleteDemandDrivenData(cmPtr);
83     # ifdef DEBUG
84     mesh_.write();
85     //::exit(EXIT_FAILURE);
86     # endif
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();
99     # ifdef DEBUG
100     mesh_.write();
101     //::exit(EXIT_FAILURE);
102     # endif
104     //- untangle surface faces
105     meshSurfaceOptimizer(*msePtr, *octreePtr_).untangleSurface();
107     # ifdef DEBUG
108     mesh_.write();
109     ::exit(EXIT_FAILURE);
110     # endif
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);
129     # ifdef DEBUG
130     mesh_.write();
131     //::exit(EXIT_FAILURE);
132     # endif
135 void voronoiMeshGenerator::optimiseMeshSurface()
137     meshSurfaceEngine mse(mesh_);
138     meshSurfaceOptimizer surfOptimiser(mse, *octreePtr_);
139     surfOptimiser.optimizeSurface();
140     surfOptimiser.untangleSurface();
142     # ifdef DEBUG
143     mesh_.write();
144     //::exit(EXIT_FAILURE);
145     # endif
148 void voronoiMeshGenerator::generateBoudaryLayers()
150     boundaryLayers bl(mesh_);
152     if( meshDict_.found("boundaryLayers") )
153     {
154         boundaryLayers bl(mesh_);
156         const dictionary& bndLayers = meshDict_.subDict("boundaryLayers");
158         if( bndLayers.found("nLayers") )
159         {
160             const label nLayers = readLabel(bndLayers.lookup("nLayers"));
162             if( nLayers > 0 )
163                 bl.addLayerForAllPatches();
164         }
165         else if( bndLayers.found("patchBoundaryLayers") )
166         {
167             const dictionary& patchLayers =
168                 bndLayers.subDict("patchBoundaryLayers");
169             const wordList createLayers = patchLayers.toc();
171             forAll(createLayers, patchI)
172                 bl.addLayerForPatch(createLayers[patchI]);
173         }
174     }
176     # ifdef DEBUG
177     mesh_.write();
178     //::exit(EXIT_FAILURE);
179     # endif
182 void voronoiMeshGenerator::refBoundaryLayers()
184     if( meshDict_.isDict("boundaryLayers") )
185     {
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();
198     }
201 void voronoiMeshGenerator::optimiseFinalMesh()
203     //- untangle the surface if needed
204     bool enforceConstraints(false);
205     if( meshDict_.found("enforceGeometryConstraints") )
206     {
207         enforceConstraints =
208             readBool(meshDict_.lookup("enforceGeometryConstraints"));
209     }
211     if( true )
212     {
213         meshSurfaceEngine mse(mesh_);
214         meshSurfaceOptimizer surfOpt(mse, *octreePtr_);
216         if( enforceConstraints )
217             surfOpt.enforceConstraints();
219         surfOpt.optimizeSurface();
220     }
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();
236     if( modSurfacePtr_ )
237     {
238         polyMeshGenGeometryModification meshMod(mesh_, meshDict_);
240         //- revert the mesh into the original space
241         meshMod.revertGeometryModification();
243         //- delete modified surface mesh
244         deleteDemandDrivenData(modSurfacePtr_);
245     }
247     # ifdef DEBUG
248     mesh_.write();
249     //::exit(0);
250     # endif
253 void voronoiMeshGenerator::projectSurfaceAfterBackScaling()
255     if( !meshDict_.found("anisotropicSources") )
256         return;
258     deleteDemandDrivenData(octreePtr_);
259     octreePtr_ = new meshOctree(*surfacePtr_);
261     meshOctreeCreator
262     (
263         *octreePtr_,
264         meshDict_
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();
276     optimiseFinalMesh();
279 void voronoiMeshGenerator::replaceBoundaries()
281     renameBoundaryPatches rbp(mesh_, meshDict_);
283     # ifdef DEBUG
284     mesh_.write();
285     //::exit(0);
286     # endif
289 void voronoiMeshGenerator::renumberMesh()
291     polyMeshGenModifier(mesh_).renumberMesh();
293     # ifdef DEBUG
294     mesh_.write();
295     //::exit(0);
296     # endif
299 void voronoiMeshGenerator::generateMesh()
301     try
302     {
303         if( controller_.runCurrentStep("templateGeneration") )
304         {
305             createVoronoiMesh();
306         }
308         if( controller_.runCurrentStep("surfaceTopology") )
309         {
310             surfacePreparation();
311         }
313         if( controller_.runCurrentStep("surfaceProjection") )
314         {
315             mapMeshToSurface();
316         }
318         if( controller_.runCurrentStep("patchAssignment") )
319         {
320             extractPatches();
321         }
323         if( controller_.runCurrentStep("edgeExtraction") )
324         {
325             mapEdgesAndCorners();
327             optimiseMeshSurface();
328         }
330         if( controller_.runCurrentStep("boundaryLayerGeneration") )
331         {
332             generateBoudaryLayers();
333         }
335         if( controller_.runCurrentStep("meshOptimisation") )
336         {
337             optimiseFinalMesh();
339             projectSurfaceAfterBackScaling();
340         }
342         if( controller_.runCurrentStep("boundaryLayerRefinement") )
343         {
344             refBoundaryLayers();
345         }
347         renumberMesh();
349         replaceBoundaries();
350     }
351     catch(const std::string& message)
352     {
353         Info << message << endl;
354     }
355     catch(...)
356     {
357         WarningIn
358         (
359             "void voronoiMeshGenerator::generateMesh()"
360         ) << "Meshing process terminated!" << endl;
361     }
364 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
366 voronoiMeshGenerator::voronoiMeshGenerator(const Time& time)
368     runTime_(time),
369     surfacePtr_(NULL),
370     modSurfacePtr_(NULL),
371     octreePtr_(NULL),
372     pointRegionsPtr_(NULL),
373     meshDict_
374     (
375         IOobject
376         (
377             "meshDict",
378             runTime_.system(),
379             runTime_,
380             IOobject::MUST_READ,
381             IOobject::NO_WRITE
382         )
383     ),
384     mesh_(time),
385     controller_(mesh_)
387     if( true )
388         checkMeshDict cmd(meshDict_);
390     const fileName surfaceFile = meshDict_.lookup("surfaceFile");
392     surfacePtr_ = new triSurf(runTime_.path()/surfaceFile);
394     if( true )
395     {
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);
402     }
404     if( surfacePtr_->featureEdges().size() != 0 )
405     {
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;
416     }
418     if( meshDict_.found("anisotropicSources") )
419     {
420         surfaceMeshGeometryModification surfMod(*surfacePtr_, meshDict_);
422         modSurfacePtr_ = surfMod.modifyGeometry();
424         octreePtr_ = new meshOctree(*modSurfacePtr_);
425     }
426     else
427     {
428         octreePtr_ = new meshOctree(*surfacePtr_);
429     }
431     meshOctreeCreator(*octreePtr_, meshDict_).createOctreeBoxes();
433     generateMesh();
436 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
438 voronoiMeshGenerator::~voronoiMeshGenerator()
440     deleteDemandDrivenData(surfacePtr_);
441     deleteDemandDrivenData(modSurfacePtr_);
442     deleteDemandDrivenData(octreePtr_);
443     deleteDemandDrivenData(pointRegionsPtr_);
446 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
448 void voronoiMeshGenerator::writeMesh() const
450     mesh_.write();
453 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
455 } // End namespace Foam
457 // ************************************************************************* //