Newer
Older
/*---------------------------------------------------------------------------*\
========= |
\\ / A nd | Author: Franjo Juretic (franjo.juretic@c-fields.com)
\\/ M anipulation | Copyright (C) Creative Fields, Ltd.
-------------------------------------------------------------------------------
License
cfMesh is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 3 of the License, or (at your
cfMesh is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with cfMesh. If not, see <http://www.gnu.org/licenses/>.
Description
\*---------------------------------------------------------------------------*/
#include "cartesianMeshGenerator.H"
#include "triSurf.H"
franjo_j@hotmail.com
committed
#include "triSurfacePatchManipulator.H"
#include "demandDrivenData.H"
#include "Time.H"
#include "meshOctreeCreator.H"
#include "cartesianMeshExtractor.H"
#include "meshSurfaceEngine.H"
#include "meshSurfaceMapper.H"
#include "meshSurfaceEdgeExtractorNonTopo.H"
#include "meshOptimizer.H"
#include "meshSurfaceOptimizer.H"
#include "topologicalCleaner.H"
#include "boundaryLayers.H"
#include "refineBoundaryLayers.H"
#include "renameBoundaryPatches.H"
#include "checkMeshDict.H"
#include "checkCellConnectionsOverFaces.H"
#include "checkIrregularSurfaceConnections.H"
#include "checkNonMappableCellConnections.H"
#include "checkBoundaryFacesSharingTwoEdges.H"
#include "polyMeshGenGeometryModification.H"
#include "surfaceMeshGeometryModification.H"
//#define DEBUG
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * Private member functions * * * * * * * * * * * * //
//- create polyMesh from octree boxes
cartesianMeshExtractor cme(*octreePtr_, meshDict_, mesh_);
if( meshDict_.found("decomposePolyhedraIntoTetsAndPyrs") )
{
if( readBool(meshDict_.lookup("decomposePolyhedraIntoTetsAndPyrs")) )
cme.decomposeSplitHexes();
}
//- removes unnecessary cells and morph the boundary
//- It also checks topology of cells after morphing is performed
franjo_j@hotmail.com
committed
do
{
changed = false;
checkIrregularSurfaceConnections checkConnections(mesh_);
if( checkConnections.checkAndFixIrregularConnections() )
changed = true;
if( checkNonMappableCellConnections(mesh_).removeCells() )
changed = true;
if( checkCellConnectionsOverFaces(mesh_).checkCellGroups() )
changed = true;
checkBoundaryFacesSharingTwoEdges(mesh_).improveTopology();
}
meshSurfaceMapper mapper(mse, *octreePtr_);
//- map mesh surface on the geometry surface
meshSurfaceOptimizer(mse, *octreePtr_).untangleSurface();
void cartesianMeshGenerator::extractPatches()
{
edgeExtractor extractor(mesh_, *octreePtr_);
Info << "Extracting edges" << endl;
extractor.extractEdges();
extractor.updateMeshPatches();
}
meshSurfaceEdgeExtractorNonTopo(mesh_, *octreePtr_);
}
void cartesianMeshGenerator::optimiseMeshSurface()
{
meshSurfaceEngine mse(mesh_);
meshSurfaceOptimizer(mse, *octreePtr_).optimizeSurface();
void cartesianMeshGenerator::generateBoundaryLayers()
franjo.juretic@c-fields.com
committed
//- add boundary layers
bl.addLayerForAllPatches();
void cartesianMeshGenerator::refBoundaryLayers()
{
if( meshDict_.isDict("boundaryLayers") )
{
refineBoundaryLayers refLayers(mesh_);
refineBoundaryLayers::readSettings(meshDict_, refLayers);
refLayers.refineLayers();
labelLongList pointsInLayer;
refLayers.pointsInBndLayer(pointsInLayer);
meshOptimizer mOpt(mesh_);
mOpt.lockPoints(pointsInLayer);
mOpt.untangleBoundaryLayer();
}
}
franjo.juretic@c-fields.com
committed
//- untangle the surface if needed
bool enforceConstraints(false);
if( meshDict_.found("enforceGeometryConstraints") )
{
enforceConstraints =
readBool(meshDict_.lookup("enforceGeometryConstraints"));
}
if( true )
{
meshSurfaceEngine mse(mesh_);
meshSurfaceOptimizer surfOpt(mse, *octreePtr_);
if( enforceConstraints )
surfOpt.enforceConstraints();
surfOpt.optimizeSurface();
}
franjo.juretic@c-fields.com
committed
//- final optimisation
meshOptimizer optimizer(mesh_);
if( enforceConstraints )
optimizer.enforceConstraints();
optimizer.optimizeMeshFV();
optimizer.optimizeBoundaryLayer(modSurfacePtr_==NULL);
franjo.juretic@c-fields.com
committed
optimizer.untangleMeshFV();
if( modSurfacePtr_ )
{
polyMeshGenGeometryModification meshMod(mesh_, meshDict_);
//- revert the mesh into the original space
meshMod.revertGeometryModification();
//- delete modified surface mesh
deleteDemandDrivenData(modSurfacePtr_);
}
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
void cartesianMeshGenerator::projectSurfaceAfterBackScaling()
{
if( !meshDict_.found("anisotropicSources") )
return;
deleteDemandDrivenData(octreePtr_);
octreePtr_ = new meshOctree(*surfacePtr_);
meshOctreeCreator
(
*octreePtr_,
meshDict_
).createOctreeWithRefinedBoundary(20, 30);
//- calculate mesh surface
meshSurfaceEngine mse(mesh_);
//- pre-map mesh surface
meshSurfaceMapper mapper(mse, *octreePtr_);
//- map mesh surface on the geometry surface
mapper.mapVerticesOntoSurface();
optimiseFinalMesh();
}
void cartesianMeshGenerator::replaceBoundaries()
{
renameBoundaryPatches rbp(mesh_, meshDict_);
}
void cartesianMeshGenerator::renumberMesh()
{
polyMeshGenModifier(mesh_).renumberMesh();
try
{
if( controller_.runCurrentStep("templateGeneration") )
if( controller_.runCurrentStep("surfaceTopology") )
if( controller_.runCurrentStep("surfaceProjection") )
if( controller_.runCurrentStep("patchAssignment") )
{
extractPatches();
if( controller_.runCurrentStep("edgeExtraction") )
if( controller_.runCurrentStep("boundaryLayerGeneration") )
{
if( controller_.runCurrentStep("meshOptimisation") )
projectSurfaceAfterBackScaling();
if( controller_.runCurrentStep("boundaryLayerRefinement") )
renumberMesh();
replaceBoundaries();
catch(const std::string& message)
{
Info << message << endl;
}
catch(...)
{
WarningIn
(
"void cartesianMeshGenerator::generateMesh()"
) << "Meshing process terminated!" << endl;
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
cartesianMeshGenerator::cartesianMeshGenerator(const Time& time)
:
db_(time),
surfacePtr_(NULL),
modSurfacePtr_(NULL),
meshDict_
(
IOobject
(
"meshDict",
db_.system(),
db_,
IOobject::MUST_READ,
IOobject::NO_WRITE
)
),
octreePtr_(NULL),
{
if( true )
{
checkMeshDict cmd(meshDict_);
}
fileName surfaceFile = meshDict_.lookup("surfaceFile");
if( Pstream::parRun() )
if( true )
{
//- save meta data with the mesh (surface mesh + its topology info)
triSurfaceMetaData sMetaData(*surfacePtr_);
const dictionary& surfMetaDict = sMetaData.metaData();
mesh_.metaData().add("surfaceFile", surfaceFile, true);
mesh_.metaData().add("surfaceMeta", surfMetaDict, true);
franjo_j@hotmail.com
committed
if( surfacePtr_->featureEdges().size() != 0 )
{
//- create surface patches based on the feature edges
//- and update the meshDict based on the given data
triSurfacePatchManipulator manipulator(*surfacePtr_);
const triSurf* surfaceWithPatches =
manipulator.surfaceWithPatches(&meshDict_);
//- delete the old surface and assign the new one
deleteDemandDrivenData(surfacePtr_);
surfacePtr_ = surfaceWithPatches;
}
if( meshDict_.found("anisotropicSources") )
{
surfaceMeshGeometryModification surfMod(*surfacePtr_, meshDict_);
modSurfacePtr_ = surfMod.modifyGeometry();
octreePtr_ = new meshOctree(*modSurfacePtr_);
}
else
{
octreePtr_ = new meshOctree(*surfacePtr_);
}
meshOctreeCreator(*octreePtr_, meshDict_).createOctreeBoxes();
generateMesh();
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
cartesianMeshGenerator::~cartesianMeshGenerator()
{
deleteDemandDrivenData(surfacePtr_);
deleteDemandDrivenData(modSurfacePtr_);
deleteDemandDrivenData(octreePtr_);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
void cartesianMeshGenerator::writeMesh() const