mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
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:
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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();
|
||||
|
||||
|
||||
@ -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_;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -157,6 +157,15 @@ Foam::cvControls::cvControls
|
||||
filteringDict.lookup("mergeClosenessCoeff")
|
||||
);
|
||||
|
||||
continueFilteringOnBadInitialPolyMesh_ = Switch
|
||||
(
|
||||
filteringDict.lookupOrDefault<Switch>
|
||||
(
|
||||
"continueFilteringOnBadInitialPolyMesh",
|
||||
false
|
||||
)
|
||||
);
|
||||
|
||||
surfaceStepFaceAngle_ = readScalar
|
||||
(
|
||||
filteringDict.lookup("surfaceStepFaceAngle")
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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_;
|
||||
|
||||
Reference in New Issue
Block a user