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 "cartesianMeshGenerator.H"
30 #include "triSurfacePatchManipulator.H"
31 #include "demandDrivenData.H"
33 #include "meshOctreeCreator.H"
34 #include "cartesianMeshExtractor.H"
35 #include "meshSurfaceEngine.H"
36 #include "meshSurfaceMapper.H"
37 #include "edgeExtractor.H"
38 #include "meshSurfaceEdgeExtractorNonTopo.H"
39 #include "meshOptimizer.H"
40 #include "meshSurfaceOptimizer.H"
41 #include "topologicalCleaner.H"
42 #include "boundaryLayers.H"
43 #include "refineBoundaryLayers.H"
44 #include "renameBoundaryPatches.H"
45 #include "checkMeshDict.H"
46 #include "checkCellConnectionsOverFaces.H"
47 #include "checkIrregularSurfaceConnections.H"
48 #include "checkNonMappableCellConnections.H"
49 #include "checkBoundaryFacesSharingTwoEdges.H"
50 #include "triSurfaceMetaData.H"
51 #include "polyMeshGenGeometryModification.H"
52 #include "surfaceMeshGeometryModification.H"
56 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
61 // * * * * * * * * * * * * Private member functions * * * * * * * * * * * * //
63 void cartesianMeshGenerator::createCartesianMesh()
65 //- create polyMesh from octree boxes
66 cartesianMeshExtractor cme(*octreePtr_, meshDict_, mesh_);
68 if( meshDict_.found("decomposePolyhedraIntoTetsAndPyrs") )
70 if( readBool(meshDict_.lookup("decomposePolyhedraIntoTetsAndPyrs")) )
71 cme.decomposeSplitHexes();
77 void cartesianMeshGenerator::surfacePreparation()
79 //- removes unnecessary cells and morph the boundary
80 //- such that there is only one boundary face per cell
81 //- It also checks topology of cells after morphing is performed
88 checkIrregularSurfaceConnections checkConnections(mesh_);
89 if( checkConnections.checkAndFixIrregularConnections() )
92 if( checkNonMappableCellConnections(mesh_).removeCells() )
95 if( checkCellConnectionsOverFaces(mesh_).checkCellGroups() )
99 checkBoundaryFacesSharingTwoEdges(mesh_).improveTopology();
102 void cartesianMeshGenerator::mapMeshToSurface()
104 //- calculate mesh surface
105 meshSurfaceEngine mse(mesh_);
107 //- pre-map mesh surface
108 meshSurfaceMapper mapper(mse, *octreePtr_);
109 mapper.preMapVertices();
111 //- map mesh surface on the geometry surface
112 mapper.mapVerticesOntoSurface();
114 //- untangle surface faces
115 meshSurfaceOptimizer(mse, *octreePtr_).untangleSurface();
118 void cartesianMeshGenerator::extractPatches()
120 edgeExtractor extractor(mesh_, *octreePtr_);
122 Info << "Extracting edges" << endl;
123 extractor.extractEdges();
125 extractor.updateMeshPatches();
128 void cartesianMeshGenerator::mapEdgesAndCorners()
130 meshSurfaceEdgeExtractorNonTopo(mesh_, *octreePtr_);
133 void cartesianMeshGenerator::optimiseMeshSurface()
135 meshSurfaceEngine mse(mesh_);
136 meshSurfaceOptimizer(mse, *octreePtr_).optimizeSurface();
139 void cartesianMeshGenerator::generateBoundaryLayers()
141 //- add boundary layers
142 boundaryLayers bl(mesh_);
143 bl.addLayerForAllPatches();
146 void cartesianMeshGenerator::refBoundaryLayers()
148 if( meshDict_.isDict("boundaryLayers") )
150 refineBoundaryLayers refLayers(mesh_);
152 refineBoundaryLayers::readSettings(meshDict_, refLayers);
154 refLayers.refineLayers();
156 labelLongList pointsInLayer;
157 refLayers.pointsInBndLayer(pointsInLayer);
159 meshOptimizer mOpt(mesh_);
160 mOpt.lockPoints(pointsInLayer);
161 mOpt.untangleBoundaryLayer();
165 void cartesianMeshGenerator::optimiseFinalMesh()
167 //- untangle the surface if needed
168 bool enforceConstraints(false);
169 if( meshDict_.found("enforceGeometryConstraints") )
172 readBool(meshDict_.lookup("enforceGeometryConstraints"));
177 meshSurfaceEngine mse(mesh_);
178 meshSurfaceOptimizer surfOpt(mse, *octreePtr_);
180 if( enforceConstraints )
181 surfOpt.enforceConstraints();
183 surfOpt.optimizeSurface();
186 deleteDemandDrivenData(octreePtr_);
188 //- final optimisation
189 meshOptimizer optimizer(mesh_);
190 if( enforceConstraints )
191 optimizer.enforceConstraints();
193 optimizer.optimizeMeshFV();
194 optimizer.optimizeLowQualityFaces();
195 optimizer.optimizeBoundaryLayer(modSurfacePtr_==NULL);
196 optimizer.untangleMeshFV();
198 mesh_.clearAddressingData();
202 polyMeshGenGeometryModification meshMod(mesh_, meshDict_);
204 //- revert the mesh into the original space
205 meshMod.revertGeometryModification();
207 //- delete modified surface mesh
208 deleteDemandDrivenData(modSurfacePtr_);
212 void cartesianMeshGenerator::projectSurfaceAfterBackScaling()
214 if( !meshDict_.found("anisotropicSources") )
217 deleteDemandDrivenData(octreePtr_);
218 octreePtr_ = new meshOctree(*surfacePtr_);
224 ).createOctreeWithRefinedBoundary(20, 30);
226 //- calculate mesh surface
227 meshSurfaceEngine mse(mesh_);
229 //- pre-map mesh surface
230 meshSurfaceMapper mapper(mse, *octreePtr_);
232 //- map mesh surface on the geometry surface
233 mapper.mapVerticesOntoSurface();
238 void cartesianMeshGenerator::replaceBoundaries()
240 renameBoundaryPatches rbp(mesh_, meshDict_);
243 void cartesianMeshGenerator::renumberMesh()
245 polyMeshGenModifier(mesh_).renumberMesh();
248 void cartesianMeshGenerator::generateMesh()
252 if( controller_.runCurrentStep("templateGeneration") )
254 createCartesianMesh();
257 if( controller_.runCurrentStep("surfaceTopology") )
259 surfacePreparation();
262 if( controller_.runCurrentStep("surfaceProjection") )
267 if( controller_.runCurrentStep("patchAssignment") )
272 if( controller_.runCurrentStep("edgeExtraction") )
274 mapEdgesAndCorners();
276 optimiseMeshSurface();
279 if( controller_.runCurrentStep("boundaryLayerGeneration") )
281 generateBoundaryLayers();
284 if( controller_.runCurrentStep("meshOptimisation") )
288 projectSurfaceAfterBackScaling();
291 if( controller_.runCurrentStep("boundaryLayerRefinement") )
300 controller_.workflowCompleted();
302 catch(const std::string& message)
304 Info << message << endl;
310 "void cartesianMeshGenerator::generateMesh()"
311 ) << "Meshing process terminated!" << endl;
315 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
317 cartesianMeshGenerator::cartesianMeshGenerator(const Time& time)
321 modSurfacePtr_(NULL),
339 checkMeshDict cmd(meshDict_);
342 fileName surfaceFile = meshDict_.lookup("surfaceFile");
343 if( Pstream::parRun() )
344 surfaceFile = ".."/surfaceFile;
346 surfacePtr_ = new triSurf(db_.path()/surfaceFile);
350 //- save meta data with the mesh (surface mesh + its topology info)
351 triSurfaceMetaData sMetaData(*surfacePtr_);
352 const dictionary& surfMetaDict = sMetaData.metaData();
354 mesh_.metaData().add("surfaceFile", surfaceFile, true);
355 mesh_.metaData().add("surfaceMeta", surfMetaDict, true);
358 if( surfacePtr_->featureEdges().size() != 0 )
360 //- create surface patches based on the feature edges
361 //- and update the meshDict based on the given data
362 triSurfacePatchManipulator manipulator(*surfacePtr_);
364 const triSurf* surfaceWithPatches =
365 manipulator.surfaceWithPatches(&meshDict_);
367 //- delete the old surface and assign the new one
368 deleteDemandDrivenData(surfacePtr_);
369 surfacePtr_ = surfaceWithPatches;
372 if( meshDict_.found("anisotropicSources") )
374 surfaceMeshGeometryModification surfMod(*surfacePtr_, meshDict_);
376 modSurfacePtr_ = surfMod.modifyGeometry();
378 octreePtr_ = new meshOctree(*modSurfacePtr_);
382 octreePtr_ = new meshOctree(*surfacePtr_);
385 meshOctreeCreator(*octreePtr_, meshDict_).createOctreeBoxes();
390 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
392 cartesianMeshGenerator::~cartesianMeshGenerator()
394 deleteDemandDrivenData(surfacePtr_);
395 deleteDemandDrivenData(modSurfacePtr_);
396 deleteDemandDrivenData(octreePtr_);
399 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
401 void cartesianMeshGenerator::writeMesh() const
406 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
408 } // End namespace Foam
410 // ************************************************************************* //