Commit 0544aae3 authored by Franjo's avatar Franjo
Browse files

It is now possible to terminate the meshin process in case of bad snapping

by using enforceConstraints entry in meshDict.
parent 7347c8e5
......@@ -214,25 +214,35 @@ void cartesian2DMeshGenerator::renumberMesh()
void cartesian2DMeshGenerator::generateMesh()
{
createCartesianMesh();
try
{
createCartesianMesh();
surfacePreparation();
surfacePreparation();
mapMeshToSurface();
mapMeshToSurface();
mapEdgesAndCorners();
mapEdgesAndCorners();
optimiseMeshSurface();
optimiseMeshSurface();
generateBoundaryLayers();
generateBoundaryLayers();
optimiseMeshSurface();
optimiseMeshSurface();
refBoundaryLayers();
refBoundaryLayers();
renumberMesh();
renumberMesh();
replaceBoundaries();
replaceBoundaries();
}
catch(...)
{
WarningIn
(
"void cartesian2DMeshGenerator::generateMesh()"
) << "Meshing process terminated!" << endl;
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
......
......@@ -224,12 +224,30 @@ void cartesianMeshGenerator::refBoundaryLayers()
void cartesianMeshGenerator::optimiseFinalMesh()
{
//- untangle the surface if needed
meshSurfaceEngine mse(mesh_);
meshSurfaceOptimizer(mse, *octreePtr_).optimizeSurface();
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();
}
deleteDemandDrivenData(octreePtr_);
//- final optimisation
meshOptimizer optimizer(mesh_);
if( enforceConstraints )
optimizer.enforceConstraints();
optimizer.optimizeMeshFV();
optimizer.optimizeLowQualityFaces();
optimizer.untangleMeshFV();
......@@ -262,25 +280,35 @@ void cartesianMeshGenerator::renumberMesh()
void cartesianMeshGenerator::generateMesh()
{
createCartesianMesh();
try
{
createCartesianMesh();
surfacePreparation();
surfacePreparation();
mapMeshToSurface();
mapMeshToSurface();
mapEdgesAndCorners();
mapEdgesAndCorners();
optimiseMeshSurface();
optimiseMeshSurface();
generateBoundaryLayers();
generateBoundaryLayers();
optimiseFinalMesh();
optimiseFinalMesh();
refBoundaryLayers();
refBoundaryLayers();
renumberMesh();
renumberMesh();
replaceBoundaries();
replaceBoundaries();
}
catch(...)
{
WarningIn
(
"void cartesianMeshGenerator::generateMesh()"
) << "Meshing process terminated!" << endl;
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
......
......@@ -179,8 +179,17 @@ void hexMeshGenerator::refBoundaryLayers()
void hexMeshGenerator::optimiseFinalMesh()
{
//- final optimisation
//- check if strict enforcing of constraints is active
bool enforceConstraints(false);
if( meshDict_.found("enforceGeometryConstraints") )
{
enforceConstraints =
readBool(meshDict_.lookup("enforceGeometryConstraints"));
}
meshOptimizer optimizer(mesh_);
if( enforceConstraints )
optimizer.enforceConstraints();
optimizer.optimizeSurface(*octreePtr_);
......@@ -216,21 +225,31 @@ void hexMeshGenerator::renumberMesh()
void hexMeshGenerator::generateMesh()
{
generateDualMesh();
try
{
generateDualMesh();
surfacePreparation();
surfacePreparation();
mapMeshToSurface();
mapMeshToSurface();
optimiseMeshSurface();
optimiseMeshSurface();
generateBoundaryLayers();
generateBoundaryLayers();
optimiseFinalMesh();
optimiseFinalMesh();
renumberMesh();
renumberMesh();
replaceBoundaries();
replaceBoundaries();
}
catch(...)
{
WarningIn
(
"void hexMeshGenerator::generateMesh()"
) << "Meshing process terminated!" << endl;
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
......
......@@ -169,7 +169,16 @@ void tetMeshGenerator::generateBoudaryLayers()
void tetMeshGenerator::optimiseFinalMesh()
{
//- final optimisation
bool enforceConstraints(false);
if( meshDict_.found("enforceGeometryConstraints") )
{
enforceConstraints =
readBool(meshDict_.lookup("enforceGeometryConstraints"));
}
meshOptimizer optimizer(mesh_);
if( enforceConstraints )
optimizer.enforceConstraints();
optimizer.optimizeSurface(*octreePtr_);
......@@ -223,25 +232,35 @@ void tetMeshGenerator::renumberMesh()
void tetMeshGenerator::generateMesh()
{
createTetMesh();
try
{
createTetMesh();
surfacePreparation();
surfacePreparation();
mapMeshToSurface();
mapMeshToSurface();
mapEdgesAndCorners();
mapEdgesAndCorners();
optimiseMeshSurface();
optimiseMeshSurface();
generateBoudaryLayers();
generateBoudaryLayers();
optimiseFinalMesh();
optimiseFinalMesh();
refBoundaryLayers();
refBoundaryLayers();
renumberMesh();
renumberMesh();
replaceBoundaries();
replaceBoundaries();
}
catch(...)
{
WarningIn
(
"void tetMeshGenerator::generateMesh()"
) << "Meshing process terminated!" << endl;
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
......
......@@ -139,7 +139,9 @@ meshOptimizer::meshOptimizer(polyMeshGen& mesh)
:
mesh_(mesh),
vertexLocation_(mesh.points().size(), INSIDE),
msePtr_(NULL)
msePtr_(NULL),
enforceConstraints_(false),
badPointsSubsetName_()
{
const meshSurfaceEngine& mse = meshSurface();
const labelList& bPoints = mse.boundaryPoints();
......@@ -177,6 +179,15 @@ meshOptimizer::~meshOptimizer()
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
void meshOptimizer::enforceConstraints(const word subsetName)
{
enforceConstraints_ = true;
badPointsSubsetName_ = subsetName;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //
......@@ -63,77 +63,83 @@ class meshOptimizer
// Private data
//- reference to the mesh
polyMeshGen& mesh_;
//- location of vertex (internal, boundary, edge, corner)
List<direction> vertexLocation_;
//- mesh surface
mutable meshSurfaceEngine* msePtr_;
//- enforce constraints
bool enforceConstraints_;
//- name of the subset contaning tangled points
word badPointsSubsetName_;
// Private member functions
//- return mesh surface
const meshSurfaceEngine& meshSurface() const;
void clearSurface();
//- find problematic faces
label findBadFaces(labelHashSet&, const boolList&) const;
label findLowQualityFaces(labelHashSet&, const boolList&) const;
// Nested classes
class laplaceSmoother
{
// Private data
//- reference to the mesh
polyMeshGen& mesh_;
//- location of vertex (internal, boundary, edge, corner)
const List<direction>& vertexLocation_;
// Private member functions
//- smooth the node using the laplacian smoother
//- new position is the average of the neighbouring vertices
void laplacian(const labelLongList&, const label);
void laplacianSurface(const labelLongList&, const label);
void laplacianParallel
(
const labelLongList& procPoints,
const bool smoothOnlySurfaceNodes = false
);
//- smooth the node using the laplacian smoother
//- new position is the average of the centres of faces attached
//- to the vertex
void laplacianPC(const labelLongList&, const label);
void laplacianPCParallel(const labelLongList& procPoints);
//- smooth the node using the laplacian smoother
//- new position is the average of the centres of faces attached
//- to the vertex
void laplacianWPC(const labelLongList&, const label);
void laplacianWPCParallel(const labelLongList& procPoints);
//- update geometry after smoothing
void updateMeshGeometry(const labelLongList& smoothPoints);
//- Disallow default bitwise copy construct
laplaceSmoother(const laplaceSmoother&);
//- Disallow default bitwise assignment
void operator=(const laplaceSmoother&);
public:
// Constructor
//- Construct from mesh and vertex locations
laplaceSmoother(polyMeshGen&, const List<direction>&);
// Destructor
~laplaceSmoother();
// Member Functions
//- new position is the average of the neighbouring vertices
void optimizeLaplacian(const label nIterations = 1);
......@@ -142,7 +148,7 @@ class meshOptimizer
const labelHashSet& badFaces,
const label nIterations = 1
);
//- new position of surface point is the average of
//- the neighbouring surface vertices
void optimizeSurfaceLaplacian
......@@ -150,7 +156,7 @@ class meshOptimizer
const labelHashSet& badFaces,
const label nIterations = 1
);
//- new positions are the average of the centres of the cells
//- adjacent to the vertex
void optimizeLaplacianPC(const label nIterations = 1);
......@@ -159,7 +165,7 @@ class meshOptimizer
const labelHashSet& badFaces,
const label nIterations = 1
);
//- new positions are the average of the centres of the cells
//- adjacent to the vertex weighted by cell volumes
void optimizeLaplacianWPC(const label nIterations = 1);
......@@ -169,13 +175,13 @@ class meshOptimizer
const label nIterations = 1
);
};
//- Disallow default bitwise copy construct
meshOptimizer(const meshOptimizer&);
//- Disallow default bitwise assignment
void operator=(const meshOptimizer&);
// enumerators
enum vertexType_
{
......@@ -199,6 +205,12 @@ public:
~meshOptimizer();
// Member Functions
//- Flag stopping the meshing process if it is not possible
//- to untangle the surface without sacrificing geometry constraints
//- Points which must be moved away from the required position are
//- stored into a point subset
void enforceConstraints(const word subsetName="badPoints");
//- smooth surface vertices
void optimizeSurface(const meshOctree&);
......
......@@ -44,14 +44,17 @@ namespace Foam
void meshOptimizer::optimizeSurface(const meshOctree& octree)
{
Info << "Optimizing positions of surface nodes" << endl;
meshSurfaceEngine& mse = const_cast<meshSurfaceEngine&>(meshSurface());
meshSurfaceOptimizer surfaceOptimizer(mse, octree);
if( enforceConstraints_ )
surfaceOptimizer.enforceConstraints(badPointsSubsetName_);
surfaceOptimizer.optimizeSurface();
meshSurfaceMapper(mse, octree).mapVerticesOntoSurfacePatches();
clearSurface();
Info << "Finished optimizing positions of surface nodes" << endl;
......
......@@ -154,7 +154,36 @@ void meshOptimizer::untangleMeshFV()
//- perform optimisation
if( nBadFaces == 0 )
{
break;
}
else if( enforceConstraints_ )
{
const label subsetId =
mesh_.addPointSubset(badPointsSubsetName_);
forAllConstIter(labelHashSet, badFaces, it)
{
const face& f = faces[it.key()];
forAll(f, pI)
mesh_.addPointToSubset(subsetId, f[pI]);
}
WarningIn
(
"void meshOptimizer::untangleMeshFV()"
) << "Writing mesh with " << badPointsSubsetName_
<< " subset. These points cannot be untangled"
<< " without sacrificing geometry constraints. Exitting.."
<< endl;
returnReduce(1, sumOp<label>());
throw std::logic_error
(
"void meshOptimizer::untangleMeshFV()"
"Cannot untangle mesh!!"
);
}
partTetMesh tetMesh(mesh_, badFaces, 0);
tetMeshOptimisation tmo(tetMesh);
......
......@@ -126,7 +126,9 @@ meshSurfaceOptimizer::meshSurfaceOptimizer
vertexType_(surface.boundaryPoints().size()),
partitionerPtr_(new meshSurfacePartitioner(surface)),
deletePartitioner_(true),
triMeshPtr_(NULL)
triMeshPtr_(NULL),
enforceConstraints_(false),
badPointsSubsetName_()
{
classifySurfaceVertices();
}
......@@ -142,7 +144,9 @@ meshSurfaceOptimizer::meshSurfaceOptimizer
vertexType_(surfaceEngine_.boundaryPoints().size()),
partitionerPtr_(&partitioner),
deletePartitioner_(false),
triMeshPtr_(NULL)
triMeshPtr_(NULL),
enforceConstraints_(false),
badPointsSubsetName_()
{
classifySurfaceVertices();
}
......@@ -159,6 +163,12 @@ meshSurfaceOptimizer::~meshSurfaceOptimizer()
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
void meshSurfaceOptimizer::enforceConstraints(const word subsetName)
{
enforceConstraints_ = true;
badPointsSubsetName_ = subsetName;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
......
......@@ -79,6 +79,12 @@ class meshSurfaceOptimizer
//- mesh of surface triangles needed for some smoothers
mutable partTriMesh* triMeshPtr_;
//- enforce constraints
bool enforceConstraints_;
//- name of the subset contaning tangled points
word badPointsSubsetName_;
// Private member functions
//- classify surface vertices as PARTITION, EDGE, CORNER
void classifySurfaceVertices();
......@@ -253,6 +259,12 @@ public:
~meshSurfaceOptimizer();
// Member Functions
//- Flag stopping the meshing process if it is not possible
//- to untangle the surface without sacrificing geometry constraints
//- Points which must be moved away from the required position are
//- stored into a point subset
void enforceConstraints(const word subsetName="badPoints");
//- runs a surface smoother on the selected boundary points
bool untangleSurface
(
......
......@@ -40,6 +40,7 @@ Description
#include "FIFOStack.H"
#include <map>
#include <stdexcept>
# ifdef USE_OMP
#include <omp.h>
......@@ -373,7 +374,40 @@ bool meshSurfaceOptimizer::untangleSurface
nInvertedTria =
findInvertedVertices(smoothVertex, nAdditionalLayers);
if( nInvertedTria == 0 ) break;
if( nInvertedTria == 0 )
{
break;
}
else if( enforceConstraints_ && !remapVertex )
{
polyMeshGen& mesh =
const_cast<polyMeshGen&>(surfaceEngine_.mesh());
const label subsetId =
mesh.addPointSubset(badPointsSubsetName_);
forAll(smoothVertex, bpI)
if( smoothVertex[bpI] )
mesh.addPointToSubset(subsetId, bPoints[bpI]);
WarningIn
(
"bool meshSurfaceOptimizer::untangleSurface"
"(const labelLongList&, const label)"
) << "Writing mesh with " << badPointsSubsetName_
<< " subset. These points cannot be untangled"
<< " without sacrificing geometry constraints. Exitting.."
<< endl;
returnReduce(1, sumOp<label>());
throw std::logic_error
(
"bool meshSurfaceOptimizer::untangleSurface"
"(const labelLongList&, const label)"
"Cannot untangle mesh!!"