Changing indexedCell to store an integer count of the number of times

a dual vertex has been limited.

Allowing the face filtering to continue after warning that mesh
quality cannot be satisfied based on a control Switch.  The filtering
terminates when the number of wrongFaces is less than or equal to the
intial number.

There is a possiblity that the filtering will never converge in this
mode (or in fact, any other).  For example, if a face is on the brink
of being "wrong" and a face motion on the other side of the cell moves
the cell centre enough to make it "wrong", then the limiting mechanism
won't be able to pick this up and stop it, unless limiting is applied
to all points of all cells that are connected to a point that is on a
wrong face.  This can be done if a vertex on a face has been limited
many (say > 4) times.
This commit is contained in:
graham
2010-01-14 13:32:51 +00:00
parent cf0c71789a
commit ecab63cc58
7 changed files with 89 additions and 69 deletions

View File

@ -1030,7 +1030,7 @@ Foam::face Foam::conformalVoronoiMesh::buildDualFace
}
Foam::scalar Foam::conformalVoronoiMesh::minFilterLimit
Foam::label Foam::conformalVoronoiMesh::maxFilterCount
(
const Triangulation::Finite_edges_iterator& eit
) const
@ -1038,7 +1038,7 @@ Foam::scalar Foam::conformalVoronoiMesh::minFilterLimit
Cell_circulator ccStart = incident_cells(*eit);
Cell_circulator cc = ccStart;
scalar minFilterLimit = GREAT;
label maxFC = 0;
do
{
@ -1057,16 +1057,16 @@ Foam::scalar Foam::conformalVoronoiMesh::minFilterLimit
<< exit(FatalError);
}
if (cc->filterLimit() < minFilterLimit)
if (cc->filterCount() > maxFC)
{
minFilterLimit = cc->filterLimit();
maxFC = cc->filterCount();
}
cc++;
} while (cc != ccStart);
return minFilterLimit;
return maxFC;
}

View File

@ -357,10 +357,10 @@ private:
const Triangulation::Finite_edges_iterator& eit
) const;
//- Finds the minimum filterLimit of the dual vertices
//- Finds the maximum filterCount of the dual vertices
// (Delaunay cells) that form the dual face produced by the
// supplied edge
scalar minFilterLimit
label maxFilterCount
(
const Triangulation::Finite_edges_iterator& eit
) const;

View File

@ -76,6 +76,18 @@ void Foam::conformalVoronoiMesh::calcDualMesh
}
}
// Make all filterCount values zero
for
(
Triangulation::Finite_cells_iterator cit = finite_cells_begin();
cit != finite_cells_end();
++cit
)
{
cit->filterCount() = 0;
}
indexDualVertices(points);
{
@ -100,14 +112,22 @@ void Foam::conformalVoronoiMesh::calcDualMesh
if (nInitialBadQualityFaces > 0)
{
Info<< "A mesh could not be produced to satisfy the specified quality "
<< "criteria. The quality and the surface conformation controls "
<< "can be altered and the internalDelaunayVertices read in to try "
<< "again, or more cell size resolution and motion iterations can "
<< "be applied in areas where problems are occurring."
Info<< nl
<< "A mesh could not be produced to satisfy the specified "
<< "quality criteria." << nl
<< "The quality and the surface conformation controls "
<< "can be altered and the internalDelaunayVertices read in "
<< "to try again, or more cell size resolution and motion "
<< "iterations can be applied in areas where problems are "
<< "occurring."
<< endl;
}
else
if
(
nInitialBadQualityFaces == 0
|| cvMeshControls().continueFilteringOnBadInitialPolyMesh()
)
{
label nBadQualityFaces = 0;
@ -141,7 +161,7 @@ void Foam::conformalVoronoiMesh::calcDualMesh
Info<< "Found " << nBadQualityFaces << " bad quality faces" << endl;
} while (nBadQualityFaces > 0);
} while (nBadQualityFaces > nInitialBadQualityFaces);
}
// Final dual face and owner neighbour construction
@ -477,7 +497,7 @@ void Foam::conformalVoronoiMesh::smoothSurface(pointField& pts)
{
label ptI = cit->cellIndex();
if (cit->filterLimit() < 1.0)
if (cit->filterCount() > 0)
{
// This vertex has been limited, skip
continue;
@ -578,9 +598,9 @@ Foam::label Foam::conformalVoronoiMesh::smoothSurfaceDualFaces
continue;
}
scalar minFL = minFilterLimit(eit);
label maxFC = maxFilterCount(eit);
if (minFL < 1.0)
if (maxFC > 0)
{
// A vertex on this face has been limited, skip
continue;
@ -755,9 +775,9 @@ Foam::label Foam::conformalVoronoiMesh::collapseFaces
continue;
}
scalar minFL = minFilterLimit(eit);
label maxFC = maxFilterCount(eit);
if (minFL < 1.0)
if (maxFC > 0)
{
// A vertex on this face has been limited, skip
continue;
@ -817,7 +837,7 @@ Foam::conformalVoronoiMesh::collapseFace
scalar collapseSizeLimitCoeff
) const
{
bool limitToQuadsOrTris = true;
bool limitToQuadsOrTris = false;
bool allowEarlyCollapseToPoint = true;
@ -1297,7 +1317,7 @@ Foam::label Foam::conformalVoronoiMesh::checkPolyMeshQuality
}
}
Info<< "Cells with fewer than 4 faces : "
Info<< "Cells with more than 1 but fewer than 4 faces : "
<< nInvalidPolyhedra << endl;
PackedBoolList ptToBeLimited(pts.size(), false);
@ -1350,7 +1370,10 @@ Foam::label Foam::conformalVoronoiMesh::checkPolyMeshQuality
// }
// Limit Delaunay cell filter values
// Apply Delaunay cell filterCounts and determine the maximum
// overall filterCount
label maxFilterCount = 0;
for
(
@ -1365,42 +1388,17 @@ Foam::label Foam::conformalVoronoiMesh::checkPolyMeshQuality
{
if (ptToBeLimited[cI] == true)
{
cit->filterLimit() *= 0.75;
cit->filterCount()++;
}
}
}
// Determine the minimum minFilterLimit
scalar minMinFilterLimit = GREAT;
for
(
Triangulation::Finite_edges_iterator eit = finite_edges_begin();
eit != finite_edges_end();
++eit
)
{
Cell_handle c = eit->first;
Vertex_handle vA = c->vertex(eit->second);
Vertex_handle vB = c->vertex(eit->third);
if
(
vA->internalOrBoundaryPoint()
|| vB->internalOrBoundaryPoint()
)
{
scalar minFL = minFilterLimit(eit);
if (minFL < minMinFilterLimit)
if (cit->filterCount() > maxFilterCount)
{
minMinFilterLimit = minFL;
maxFilterCount = cit->filterCount();
}
}
}
Info<< "minMinFilterLimit " << minMinFilterLimit << endl;
Info<< "maxFilterCount " << maxFilterCount << endl;
return wrongFaces.size();

View File

@ -36,7 +36,6 @@ Description
#include <CGAL/Triangulation_3.h>
#include "indexedVertex.H"
#include "scalar.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -54,12 +53,12 @@ class indexedCell
{
// Private data
//- The index for this tetrahedral cell
//- The index for this Delaunay tetrahedral cell
int index_;
//- The applicable fraction of the face filtering mechanism
// controls
Foam::scalar filterLimit_;
//- The number of times that this Delaunay cell has been limited
// during filtering
int filterCount_;
public:
@ -79,7 +78,7 @@ public:
:
Cb(),
index_(-1),
filterLimit_(1.0)
filterCount_(0)
{}
@ -90,7 +89,7 @@ public:
:
Cb(v0, v1, v2, v3),
index_(-1),
filterLimit_(1.0)
filterCount_(0)
{}
@ -108,7 +107,7 @@ public:
:
Cb(v0, v1, v2, v3, n0, n1, n2, n3),
index_(-1),
filterLimit_(1.0)
filterCount_(0)
{}
@ -124,15 +123,15 @@ public:
}
inline Foam::scalar& filterLimit()
inline int& filterCount()
{
return filterLimit_;
return filterCount_;
}
inline Foam::scalar filterLimit() const
inline int filterCount() const
{
return filterLimit_;
return filterCount_;
}
};

View File

@ -157,6 +157,15 @@ Foam::cvControls::cvControls
filteringDict.lookup("mergeClosenessCoeff")
);
continueFilteringOnBadInitialPolyMesh_ = Switch
(
filteringDict.lookupOrDefault<Switch>
(
"continueFilteringOnBadInitialPolyMesh",
false
)
);
surfaceStepFaceAngle_ = readScalar
(
filteringDict.lookup("surfaceStepFaceAngle")

View File

@ -147,10 +147,18 @@ class cvControls
// polyMesh filtering controls
//- Upper limit on the size of faces to be filtered from,
// fraction of the local target cell size
scalar filterSizeCoeff_;
//- Upper limit on how close two dual vertices can be before
// being merged, fraction of the local target cell size
scalar mergeClosenessCoeff_;
//- If the mesh quality criteria cannot be satisfied, continue
// with filtering anyway?
Switch continueFilteringOnBadInitialPolyMesh_;
//- The maximum allowed angle between a boundary face normal
// and the local surface normal before face will be
// aggressively collapsed
@ -173,10 +181,6 @@ class cvControls
// the local target cell size
scalar maxCollapseFaceToPointSideLengthCoeff_;
//- Upper limit on the size of faces to be filtered from,
// fraction of the local target cell size
scalar filterSizeCoeff_;
// Private Member Functions
@ -244,7 +248,7 @@ public:
inline label surfaceConformationRebuildFrequency() const;
//- Return the objOutput Switch
inline bool objOutput() const;
inline Switch objOutput() const;
//- Return the number of alignmentSearchSpokes to use
inline label alignmentSearchSpokes() const;
@ -270,6 +274,9 @@ public:
//- Return the mergeClosenessCoeff
inline scalar mergeClosenessCoeff() const;
//- Return the continueFilteringOnBadInitialPolyMesh Switch
inline Switch continueFilteringOnBadInitialPolyMesh() const;
//- Return the surfaceStepFaceAngle
inline scalar surfaceStepFaceAngle() const;

View File

@ -98,7 +98,7 @@ inline Foam::label Foam::cvControls::surfaceConformationRebuildFrequency() const
}
inline bool Foam::cvControls::objOutput() const
inline Foam::Switch Foam::cvControls::objOutput() const
{
return objOutput_;
}
@ -152,6 +152,13 @@ inline Foam::scalar Foam::cvControls::mergeClosenessCoeff() const
}
inline Foam::Switch
Foam::cvControls::continueFilteringOnBadInitialPolyMesh() const
{
return continueFilteringOnBadInitialPolyMesh_;
}
inline Foam::scalar Foam::cvControls::surfaceStepFaceAngle() const
{
return surfaceStepFaceAngle_;