Forward compatibility: flex
[foam-extend-3.2.git] / src / mesh / cfMesh / cartesian2DMesh / cartesian2DMeshGenerator / cartesian2DMeshGenerator.C
blob2bdc6bce5ba378c78e5807b793018200482476bb
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 "cartesian2DMeshGenerator.H"
29 #include "triSurface2DCheck.H"
30 #include "polyMeshGen2DEngine.H"
31 #include "triSurf.H"
32 #include "triSurfacePatchManipulator.H"
33 #include "triSurfaceCleanupDuplicateTriangles.H"
34 #include "demandDrivenData.H"
35 #include "foamTime.H"
36 #include "meshOctreeCreator.H"
37 #include "cartesianMeshExtractor.H"
38 #include "meshSurfaceEngine.H"
39 #include "meshSurfaceMapper2D.H"
40 #include "meshSurfaceEdgeExtractor2D.H"
41 #include "meshSurfaceOptimizer.H"
42 #include "topologicalCleaner.H"
43 #include "boundaryLayers.H"
44 #include "refineBoundaryLayers.H"
45 #include "renameBoundaryPatches.H"
46 #include "checkMeshDict.H"
47 #include "checkCellConnectionsOverFaces.H"
48 #include "checkIrregularSurfaceConnections.H"
49 #include "checkNonMappableCellConnections.H"
50 #include "checkBoundaryFacesSharingTwoEdges.H"
51 #include "triSurfaceMetaData.H"
52 #include "polyMeshGenGeometryModification.H"
53 #include "surfaceMeshGeometryModification.H"
55 //#define DEBUG
57 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
59 namespace Foam
62 // * * * * * * * * * * * * Private member functions  * * * * * * * * * * * * //
64 void cartesian2DMeshGenerator::createCartesianMesh()
66     //- create polyMesh from octree boxes
67     cartesianMeshExtractor cme(*octreePtr_, meshDict_, mesh_);
69     if( meshDict_.found("decomposePolyhedraIntoTetsAndPyrs") )
70     {
71         if( readBool(meshDict_.lookup("decomposePolyhedraIntoTetsAndPyrs")) )
72             cme.decomposeSplitHexes();
73     }
75     cme.createMesh();
78 void cartesian2DMeshGenerator::surfacePreparation()
80     //- removes unnecessary cells and morph the boundary
81     //- such that there is only one boundary face per cell
82     //- It also checks topology of cells after morphing is performed
83     bool changed;
85     do
86     {
87         changed = false;
89         checkIrregularSurfaceConnections checkConnections(mesh_);
90         if( checkConnections.checkAndFixIrregularConnections() )
91             changed = true;
93         if( checkNonMappableCellConnections(mesh_).removeCells() )
94             changed = true;
96         if( checkCellConnectionsOverFaces(mesh_).checkCellGroups() )
97             changed = true;
98     } while( changed );
100     checkBoundaryFacesSharingTwoEdges(mesh_).improveTopology();
103 void cartesian2DMeshGenerator::mapMeshToSurface()
105     //- calculate mesh surface
106     meshSurfaceEngine* msePtr = new meshSurfaceEngine(mesh_);
108     //- pre-map mesh surface
109     meshSurfaceMapper2D mapper(*msePtr, *octreePtr_);
111     mapper.adjustZCoordinates();
113     mapper.preMapVertices();
115     //- map mesh surface on the geometry surface
116     mapper.mapVerticesOntoSurface();
118     deleteDemandDrivenData(msePtr);
121 void cartesian2DMeshGenerator::extractPatches()
123     meshSurfaceEdgeExtractor2D(mesh_, *octreePtr_).distributeBoundaryFaces();
126 void cartesian2DMeshGenerator::mapEdgesAndCorners()
128     meshSurfaceEdgeExtractor2D(mesh_, *octreePtr_).remapBoundaryPoints();
131 void cartesian2DMeshGenerator::optimiseMeshSurface()
133     meshSurfaceEngine mse(mesh_);
134     meshSurfaceOptimizer optimizer(mse, *octreePtr_);
135     optimizer.optimizeSurface2D();
136     optimizer.untangleSurface2D();
139 void cartesian2DMeshGenerator::generateBoundaryLayers()
141     boundaryLayers bl(mesh_);
143     bl.activate2DMode();
145     bl.addLayerForAllPatches();
147     if( modSurfacePtr_ )
148     {
149         polyMeshGenGeometryModification meshMod(mesh_, meshDict_);
151         //- revert the mesh into the original space
152         meshMod.revertGeometryModification();
154         //- delete modified surface mesh
155         deleteDemandDrivenData(modSurfacePtr_);
157         //- delete the octree
158         deleteDemandDrivenData(octreePtr_);
160         //- contruct a new octree from the input surface
161         octreePtr_ = new meshOctree(*surfacePtr_, true);
162         meshOctreeCreator(*octreePtr_).createOctreeWithRefinedBoundary(20);
164         mapEdgesAndCorners();
166         optimiseMeshSurface();
167     }
170 void cartesian2DMeshGenerator::refBoundaryLayers()
172     if( meshDict_.isDict("boundaryLayers") )
173     {
174         refineBoundaryLayers refLayers(mesh_);
176         refineBoundaryLayers::readSettings(meshDict_, refLayers);
178         refLayers.activate2DMode();
180         refLayers.refineLayers();
182         meshSurfaceEngine mse(mesh_);
183         meshSurfaceOptimizer optimizer(mse, *octreePtr_);
185         optimizer.untangleSurface2D();
186     }
189 void cartesian2DMeshGenerator::replaceBoundaries()
191     renameBoundaryPatches rbp(mesh_, meshDict_);
194 void cartesian2DMeshGenerator::renumberMesh()
196     polyMeshGenModifier(mesh_).renumberMesh();
199 void cartesian2DMeshGenerator::generateMesh()
201     try
202     {
203         if( controller_.runCurrentStep("templateGeneration") )
204         {
205             createCartesianMesh();
206         }
208         if( controller_.runCurrentStep("surfaceTopology") )
209         {
210             surfacePreparation();
211         }
213         if( controller_.runCurrentStep("surfaceProjection") )
214         {
215             mapMeshToSurface();
216         }
218         if( controller_.runCurrentStep("patchAssignment") )
219         {
220             extractPatches();
221         }
223         if( controller_.runCurrentStep("edgeExtraction") )
224         {
225             mapEdgesAndCorners();
227             optimiseMeshSurface();
228         }
230         if( controller_.runCurrentStep("boundaryLayerGeneration") )
231         {
232             generateBoundaryLayers();
233         }
235         if( controller_.runCurrentStep("meshOptimisation") )
236         {
237             optimiseMeshSurface();
238         }
240         if( controller_.runCurrentStep("boundaryLayerRefinement") )
241         {
242             refBoundaryLayers();
243         }
245         renumberMesh();
247         replaceBoundaries();
249         controller_.workflowCompleted();
250     }
251     catch(const std::string& message)
252     {
253         Info << message << endl;
254     }
255     catch(...)
256     {
257         WarningIn
258         (
259             "void cartesian2DMeshGenerator::generateMesh()"
260         ) << "Meshing process terminated!" << endl;
261     }
264 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
266 cartesian2DMeshGenerator::cartesian2DMeshGenerator(const Time& time)
268     db_(time),
269     surfacePtr_(NULL),
270     modSurfacePtr_(NULL),
271     meshDict_
272     (
273         IOobject
274         (
275             "meshDict",
276             db_.system(),
277             db_,
278             IOobject::MUST_READ,
279             IOobject::NO_WRITE
280         )
281     ),
282     octreePtr_(NULL),
283     mesh_(time),
284     controller_(mesh_)
286     if( true )
287     {
288         checkMeshDict cmd(meshDict_);
289     }
291     fileName surfaceFile = meshDict_.lookup("surfaceFile");
292     if( Pstream::parRun() )
293         surfaceFile = ".."/surfaceFile;
295     surfacePtr_ = new triSurf(db_.path()/surfaceFile);
297     if( true )
298     {
299         //- save meta data with the mesh (surface mesh + its topology info)
300         triSurfaceMetaData sMetaData(*surfacePtr_);
301         const dictionary& surfMetaDict = sMetaData.metaData();
303         mesh_.metaData().add("surfaceFile", surfaceFile, true);
304         mesh_.metaData().add("surfaceMeta", surfMetaDict, true);
306         triSurface2DCheck surfCheck(*surfacePtr_);
307         if( !surfCheck.is2DSurface() )
308         {
309             surfCheck.createSubsets();
311             Info << "Writting surface with subsets to file "
312                  << "badSurfaceWithSubsets.fms" << endl;
313             surfacePtr_->writeSurface("badSurfaceWithSubsets.fms");
314         }
315     }
317     if( surfacePtr_->featureEdges().size() != 0 )
318     {
319         //- get rid of duplicate triangles as they cause strange problems
320         triSurfaceCleanupDuplicateTriangles(const_cast<triSurf&>(*surfacePtr_));
322         //- create surface patches based on the feature edges
323         //- and update the meshDict based on the given data
324         triSurfacePatchManipulator manipulator(*surfacePtr_);
326         const triSurf* surfaceWithPatches =
327             manipulator.surfaceWithPatches(&meshDict_);
329         //- delete the old surface and assign the new one
330         deleteDemandDrivenData(surfacePtr_);
331         surfacePtr_ = surfaceWithPatches;
332     }
334     if( meshDict_.found("anisotropicSources") )
335     {
336         surfaceMeshGeometryModification surfMod(*surfacePtr_, meshDict_);
338         modSurfacePtr_ = surfMod.modifyGeometry();
340         octreePtr_ = new meshOctree(*modSurfacePtr_, true);
341     }
342     else
343     {
344         octreePtr_ = new meshOctree(*surfacePtr_, true);
345     }
347     meshOctreeCreator(*octreePtr_, meshDict_).createOctreeBoxes();
349     generateMesh();
352 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
354 cartesian2DMeshGenerator::~cartesian2DMeshGenerator()
356     deleteDemandDrivenData(surfacePtr_);
357     deleteDemandDrivenData(modSurfacePtr_);
358     deleteDemandDrivenData(octreePtr_);
361 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
363 void cartesian2DMeshGenerator::writeMesh() const
365     mesh_.write();
368 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
370 } // End namespace Foam
372 // ************************************************************************* //