Fixed URL for libccmio-2.6.1 (bug report #5 by Thomas Oliveira)
[foam-extend-3.2.git] / src / mesh / cfMesh / cartesianMesh / cartesianMeshGenerator / cartesianMeshGenerator.C
blobe92f5f1028ced63e340304401c6d7eb1ad8d5e02
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 "cartesianMeshGenerator.H"
29 #include "triSurf.H"
30 #include "triSurfacePatchManipulator.H"
31 #include "demandDrivenData.H"
32 #include "foamTime.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"
54 //#define DEBUG
56 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
58 namespace Foam
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") )
69     {
70         if( readBool(meshDict_.lookup("decomposePolyhedraIntoTetsAndPyrs")) )
71             cme.decomposeSplitHexes();
72     }
74     cme.createMesh();
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
82     bool changed;
84     do
85     {
86         changed = false;
88         checkIrregularSurfaceConnections checkConnections(mesh_);
89         if( checkConnections.checkAndFixIrregularConnections() )
90             changed = true;
92         if( checkNonMappableCellConnections(mesh_).removeCells() )
93             changed = true;
95         if( checkCellConnectionsOverFaces(mesh_).checkCellGroups() )
96             changed = true;
97     } while( changed );
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") )
149     {
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();
162     }
165 void cartesianMeshGenerator::optimiseFinalMesh()
167     //- untangle the surface if needed
168     bool enforceConstraints(false);
169     if( meshDict_.found("enforceGeometryConstraints") )
170     {
171         enforceConstraints =
172             readBool(meshDict_.lookup("enforceGeometryConstraints"));
173     }
175     if( true )
176     {
177         meshSurfaceEngine mse(mesh_);
178         meshSurfaceOptimizer surfOpt(mse, *octreePtr_);
180         if( enforceConstraints )
181             surfOpt.enforceConstraints();
183         surfOpt.optimizeSurface();
184     }
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();
200     if( modSurfacePtr_ )
201     {
202         polyMeshGenGeometryModification meshMod(mesh_, meshDict_);
204         //- revert the mesh into the original space
205         meshMod.revertGeometryModification();
207         //- delete modified surface mesh
208         deleteDemandDrivenData(modSurfacePtr_);
209     }
212 void cartesianMeshGenerator::projectSurfaceAfterBackScaling()
214     if( !meshDict_.found("anisotropicSources") )
215         return;
217     deleteDemandDrivenData(octreePtr_);
218     octreePtr_ = new meshOctree(*surfacePtr_);
220     meshOctreeCreator
221     (
222         *octreePtr_,
223         meshDict_
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();
235     optimiseFinalMesh();
238 void cartesianMeshGenerator::replaceBoundaries()
240     renameBoundaryPatches rbp(mesh_, meshDict_);
243 void cartesianMeshGenerator::renumberMesh()
245     polyMeshGenModifier(mesh_).renumberMesh();
248 void cartesianMeshGenerator::generateMesh()
250     try
251     {
252         if( controller_.runCurrentStep("templateGeneration") )
253         {
254             createCartesianMesh();
255         }
257         if( controller_.runCurrentStep("surfaceTopology") )
258         {
259             surfacePreparation();
260         }
262         if( controller_.runCurrentStep("surfaceProjection") )
263         {
264             mapMeshToSurface();
265         }
267         if( controller_.runCurrentStep("patchAssignment") )
268         {
269             extractPatches();
270         }
272         if( controller_.runCurrentStep("edgeExtraction") )
273         {
274             mapEdgesAndCorners();
276             optimiseMeshSurface();
277         }
279         if( controller_.runCurrentStep("boundaryLayerGeneration") )
280         {
281             generateBoundaryLayers();
282         }
284         if( controller_.runCurrentStep("meshOptimisation") )
285         {
286             optimiseFinalMesh();
288             projectSurfaceAfterBackScaling();
289         }
291         if( controller_.runCurrentStep("boundaryLayerRefinement") )
292         {
293             refBoundaryLayers();
294         }
296         renumberMesh();
298         replaceBoundaries();
300         controller_.workflowCompleted();
301     }
302     catch(const std::string& message)
303     {
304         Info << message << endl;
305     }
306     catch(...)
307     {
308         WarningIn
309         (
310             "void cartesianMeshGenerator::generateMesh()"
311         ) << "Meshing process terminated!" << endl;
312     }
315 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
317 cartesianMeshGenerator::cartesianMeshGenerator(const Time& time)
319     db_(time),
320     surfacePtr_(NULL),
321     modSurfacePtr_(NULL),
322     meshDict_
323     (
324         IOobject
325         (
326             "meshDict",
327             db_.system(),
328             db_,
329             IOobject::MUST_READ,
330             IOobject::NO_WRITE
331         )
332     ),
333     octreePtr_(NULL),
334     mesh_(time),
335     controller_(mesh_)
337     if( true )
338     {
339         checkMeshDict cmd(meshDict_);
340     }
342     fileName surfaceFile = meshDict_.lookup("surfaceFile");
343     if( Pstream::parRun() )
344         surfaceFile = ".."/surfaceFile;
346     surfacePtr_ = new triSurf(db_.path()/surfaceFile);
348     if( true )
349     {
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);
356     }
358     if( surfacePtr_->featureEdges().size() != 0 )
359     {
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;
370     }
372     if( meshDict_.found("anisotropicSources") )
373     {
374         surfaceMeshGeometryModification surfMod(*surfacePtr_, meshDict_);
376         modSurfacePtr_ = surfMod.modifyGeometry();
378         octreePtr_ = new meshOctree(*modSurfacePtr_);
379     }
380     else
381     {
382         octreePtr_ = new meshOctree(*surfacePtr_);
383     }
385     meshOctreeCreator(*octreePtr_, meshDict_).createOctreeBoxes();
387     generateMesh();
390 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
392 cartesianMeshGenerator::~cartesianMeshGenerator()
394     deleteDemandDrivenData(surfacePtr_);
395     deleteDemandDrivenData(modSurfacePtr_);
396     deleteDemandDrivenData(octreePtr_);
399 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
401 void cartesianMeshGenerator::writeMesh() const
403     mesh_.write();
406 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
408 } // End namespace Foam
410 // ************************************************************************* //