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 "cartesian2DMeshGenerator.H"
29 #include "triSurface2DCheck.H"
30 #include "polyMeshGen2DEngine.H"
32 #include "triSurfacePatchManipulator.H"
33 #include "triSurfaceCleanupDuplicateTriangles.H"
34 #include "demandDrivenData.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"
57 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
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") )
71 if( readBool(meshDict_.lookup("decomposePolyhedraIntoTetsAndPyrs")) )
72 cme.decomposeSplitHexes();
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
89 checkIrregularSurfaceConnections checkConnections(mesh_);
90 if( checkConnections.checkAndFixIrregularConnections() )
93 if( checkNonMappableCellConnections(mesh_).removeCells() )
96 if( checkCellConnectionsOverFaces(mesh_).checkCellGroups() )
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_);
145 bl.addLayerForAllPatches();
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();
170 void cartesian2DMeshGenerator::refBoundaryLayers()
172 if( meshDict_.isDict("boundaryLayers") )
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();
189 void cartesian2DMeshGenerator::replaceBoundaries()
191 renameBoundaryPatches rbp(mesh_, meshDict_);
194 void cartesian2DMeshGenerator::renumberMesh()
196 polyMeshGenModifier(mesh_).renumberMesh();
199 void cartesian2DMeshGenerator::generateMesh()
203 if( controller_.runCurrentStep("templateGeneration") )
205 createCartesianMesh();
208 if( controller_.runCurrentStep("surfaceTopology") )
210 surfacePreparation();
213 if( controller_.runCurrentStep("surfaceProjection") )
218 if( controller_.runCurrentStep("patchAssignment") )
223 if( controller_.runCurrentStep("edgeExtraction") )
225 mapEdgesAndCorners();
227 optimiseMeshSurface();
230 if( controller_.runCurrentStep("boundaryLayerGeneration") )
232 generateBoundaryLayers();
235 if( controller_.runCurrentStep("meshOptimisation") )
237 optimiseMeshSurface();
240 if( controller_.runCurrentStep("boundaryLayerRefinement") )
249 controller_.workflowCompleted();
251 catch(const std::string& message)
253 Info << message << endl;
259 "void cartesian2DMeshGenerator::generateMesh()"
260 ) << "Meshing process terminated!" << endl;
264 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
266 cartesian2DMeshGenerator::cartesian2DMeshGenerator(const Time& time)
270 modSurfacePtr_(NULL),
288 checkMeshDict cmd(meshDict_);
291 fileName surfaceFile = meshDict_.lookup("surfaceFile");
292 if( Pstream::parRun() )
293 surfaceFile = ".."/surfaceFile;
295 surfacePtr_ = new triSurf(db_.path()/surfaceFile);
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() )
309 surfCheck.createSubsets();
311 Info << "Writting surface with subsets to file "
312 << "badSurfaceWithSubsets.fms" << endl;
313 surfacePtr_->writeSurface("badSurfaceWithSubsets.fms");
317 if( surfacePtr_->featureEdges().size() != 0 )
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;
334 if( meshDict_.found("anisotropicSources") )
336 surfaceMeshGeometryModification surfMod(*surfacePtr_, meshDict_);
338 modSurfacePtr_ = surfMod.modifyGeometry();
340 octreePtr_ = new meshOctree(*modSurfacePtr_, true);
344 octreePtr_ = new meshOctree(*surfacePtr_, true);
347 meshOctreeCreator(*octreePtr_, meshDict_).createOctreeBoxes();
352 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
354 cartesian2DMeshGenerator::~cartesian2DMeshGenerator()
356 deleteDemandDrivenData(surfacePtr_);
357 deleteDemandDrivenData(modSurfacePtr_);
358 deleteDemandDrivenData(octreePtr_);
361 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
363 void cartesian2DMeshGenerator::writeMesh() const
368 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
370 } // End namespace Foam
372 // ************************************************************************* //