Forward compatibility: flex
[foam-extend-3.2.git] / src / mesh / cfMesh / tetMesh / tetMeshGenerator / tetMeshGenerator.C
blob7453454044bb98777c92f528a09fa8df3b149698
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 "tetMeshGenerator.H"
29 #include "triSurf.H"
30 #include "demandDrivenData.H"
31 #include "foamTime.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"
51 //#define DEBUG
53 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
55 namespace Foam
58 // * * * * * * * * * * * * Private member functions  * * * * * * * * * * * * //
60 void tetMeshGenerator::createTetMesh()
62     //- create tet Mesh from octree and Delaunay tets
63     tetMeshExtractorOctree tme(*octreePtr_, meshDict_, mesh_);
65     tme.createMesh();
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
73     do
74     {
75         surfaceMorpherCells* cmPtr = new surfaceMorpherCells(mesh_);
76         cmPtr->morphMesh();
77         deleteDemandDrivenData(cmPtr);
78     }
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") )
120     {
121         boundaryLayers bl(mesh_);
123         const dictionary& bndLayers = meshDict_.subDict("boundaryLayers");
125         if( bndLayers.found("nLayers") )
126         {
127             const label nLayers = readLabel(bndLayers.lookup("nLayers"));
129             if( nLayers > 0 )
130                 bl.addLayerForAllPatches();
131         }
132         else if( bndLayers.found("patchBoundaryLayers") )
133         {
134             const dictionary& patchLayers =
135                 bndLayers.subDict("patchBoundaryLayers");
136             const wordList createLayers = patchLayers.toc();
138             forAll(createLayers, patchI)
139                 bl.addLayerForPatch(createLayers[patchI]);
140         }
141     }
144 void tetMeshGenerator::optimiseFinalMesh()
146     //- final optimisation
147     bool enforceConstraints(false);
148     if( meshDict_.found("enforceGeometryConstraints") )
149     {
150         enforceConstraints =
151             readBool(meshDict_.lookup("enforceGeometryConstraints"));
152     }
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();
169     if( modSurfacePtr_ )
170     {
171         polyMeshGenGeometryModification meshMod(mesh_, meshDict_);
173         //- revert the mesh into the original space
174         meshMod.revertGeometryModification();
176         //- delete modified surface mesh
177         deleteDemandDrivenData(modSurfacePtr_);
178     }
181 void tetMeshGenerator::projectSurfaceAfterBackScaling()
183     if( !meshDict_.found("anisotropicSources") )
184         return;
186     deleteDemandDrivenData(octreePtr_);
187     octreePtr_ = new meshOctree(*surfacePtr_);
189     meshOctreeCreator
190     (
191         *octreePtr_,
192         meshDict_
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();
204     optimiseFinalMesh();
207 void tetMeshGenerator::refBoundaryLayers()
209     if( meshDict_.isDict("boundaryLayers") )
210     {
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();
223     }
226 void tetMeshGenerator::replaceBoundaries()
228     renameBoundaryPatches rbp(mesh_, meshDict_);
231 void tetMeshGenerator::renumberMesh()
233     polyMeshGenModifier(mesh_).renumberMesh();
236 void tetMeshGenerator::generateMesh()
238     try
239     {
240         if( controller_.runCurrentStep("templateGeneration") )
241         {
242             createTetMesh();
243         }
245         if( controller_.runCurrentStep("surfaceTopology") )
246         {
247             surfacePreparation();
248         }
250         if( controller_.runCurrentStep("surfaceProjection") )
251         {
252             mapMeshToSurface();
253         }
255         if( controller_.runCurrentStep("patchAssignment") )
256         {
257             extractPatches();
258         }
260         if( controller_.runCurrentStep("edgeExtraction") )
261         {
262             mapEdgesAndCorners();
264             optimiseMeshSurface();
265         }
267         if( controller_.runCurrentStep("boundaryLayerGeneration") )
268         {
269             generateBoundaryLayers();
270         }
272         if( controller_.runCurrentStep("meshOptimisation") )
273         {
274             optimiseFinalMesh();
276             projectSurfaceAfterBackScaling();
277         }
279         if( controller_.runCurrentStep("boundaryLayerRefinement") )
280         {
281             refBoundaryLayers();
282         }
284         renumberMesh();
286         replaceBoundaries();
288         controller_.workflowCompleted();
289     }
290     catch(const std::string& message)
291     {
292         Info << message << endl;
293     }
294     catch(...)
295     {
296         WarningIn
297         (
298             "void tetMeshGenerator::generateMesh()"
299         ) << "Meshing process terminated!" << endl;
300     }
303 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
305 // Construct from Time
306 tetMeshGenerator::tetMeshGenerator(const Time& time)
308     runTime_(time),
309     surfacePtr_(NULL),
310     modSurfacePtr_(NULL),
311     meshDict_
312     (
313         IOobject
314         (
315             "meshDict",
316             runTime_.system(),
317             runTime_,
318             IOobject::MUST_READ,
319             IOobject::NO_WRITE
320         )
321     ),
322     octreePtr_(NULL),
323     mesh_(time),
324     controller_(mesh_)
326     if( true )
327     {
328         checkMeshDict cmd(meshDict_);
329     }
331     const fileName surfaceFile = meshDict_.lookup("surfaceFile");
333     surfacePtr_ = new triSurf(runTime_.path()/surfaceFile);
335     if( true )
336     {
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);
343     }
345     if( surfacePtr_->featureEdges().size() != 0 )
346     {
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;
357     }
359     if( meshDict_.found("anisotropicSources") )
360     {
361         surfaceMeshGeometryModification surfMod(*surfacePtr_, meshDict_);
363         modSurfacePtr_ = surfMod.modifyGeometry();
365         octreePtr_ = new meshOctree(*modSurfacePtr_);
366     }
367     else
368     {
369         octreePtr_ = new meshOctree(*surfacePtr_);
370     }
372     meshOctreeCreator(*octreePtr_, meshDict_).createOctreeBoxes();
374     generateMesh();
377 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
379 tetMeshGenerator::~tetMeshGenerator()
381     deleteDemandDrivenData(surfacePtr_);
382     deleteDemandDrivenData(octreePtr_);
383     deleteDemandDrivenData(modSurfacePtr_);
386 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
388 void tetMeshGenerator::writeMesh() const
390     mesh_.write();
393 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
395 } // End namespace Foam
397 // ************************************************************************* //