Handling cases where there are repeated eigenvalues for a face, i.e. a

square.  The subdeterminants in the eigenvector calculation in
tensor.C ran off the bottom of SMALL.  Handling by identifying the
longest edge as the collapseAxis.

Adding function to return the index of the longest edge for a face.
This commit is contained in:
graham
2010-01-20 18:54:56 +00:00
parent a67845421c
commit 70116c0049
2 changed files with 84 additions and 38 deletions

View File

@ -549,6 +549,9 @@ private:
label maxFC label maxFC
) const; ) const;
// Identify the index of the longest edge on the face
label longestEdge(const face& f, const pointField& pts) const;
//- Identify the face labels of the deferred collapse faces //- Identify the face labels of the deferred collapse faces
void deferredCollapseFaceSet void deferredCollapseFaceSet
( (

View File

@ -865,6 +865,8 @@ Foam::conformalVoronoiMesh::collapseFace
maxFC maxFC
); );
labelList facePts(f);
const vector fC = f.centre(pts); const vector fC = f.centre(pts);
vector fN = f.normal(pts); vector fN = f.normal(pts);
@ -898,47 +900,37 @@ Foam::conformalVoronoiMesh::collapseFace
vector collapseAxis = vector::zero; vector collapseAxis = vector::zero;
scalar aspectRatio = 1; scalar aspectRatio = 1.0;
if (detJ < 1e-5) if (detJ < 1e-5)
{ {
const edgeList& eds = f.edges(); collapseAxis = f.edges()[longestEdge(f, pts)].vec(pts);
label longestEdgeI = -1;
scalar longestEdgeLength = -SMALL;
forAll(eds, edI)
{
scalar edgeLength = eds[edI].mag(pts);
if (edgeLength > longestEdgeLength)
{
longestEdgeI = edI;
longestEdgeLength = edgeLength;
}
}
collapseAxis = eds[longestEdgeI].vec(pts);
if (mag(collapseAxis) < VSMALL)
{
Info<< "if (mag(collapseAxis) < VSMALL) " << collapseAxis << endl;
}
collapseAxis /= mag(collapseAxis); collapseAxis /= mag(collapseAxis);
// Empirical correlation for high aspect ratio faces // Empirical correlation for high aspect ratio faces
aspectRatio = sqrt(0.35/detJ); aspectRatio = sqrt(0.35/detJ);
// Info<< "# Longest edge determined collapseAxis" << endl;
} }
else else
{ {
vector eVals = eigenValues(J); vector eVals = eigenValues(J);
if (mag(eVals.y() - eVals.x()) < 100*SMALL)
{
// First two eigenvalues are the same: i.e. a square face
// Cannot necessarily determine linearly independent
// eigenvectors, or any at all, use longest edge direction.
collapseAxis = f.edges()[longestEdge(f, pts)].vec(pts);
collapseAxis /= mag(collapseAxis);
aspectRatio = 1.0;
}
else
{
// The maximum eigenvalue (z()) must be the direction of the // The maximum eigenvalue (z()) must be the direction of the
// normal, as it has the greatest value. The minimum eigenvalue // normal, as it has the greatest value. The minimum eigenvalue
// is the dominant collapse axis for high aspect ratio faces. // is the dominant collapse axis for high aspect ratio faces.
@ -952,6 +944,7 @@ Foam::conformalVoronoiMesh::collapseFace
aspectRatio = sqrt(eVals.y()/max(eVals.x(), SMALL)); aspectRatio = sqrt(eVals.y()/max(eVals.x(), SMALL));
} }
}
if (magSqr(collapseAxis) < VSMALL) if (magSqr(collapseAxis) < VSMALL)
{ {
@ -962,6 +955,30 @@ Foam::conformalVoronoiMesh::collapseFace
<< "No collapse axis found for face, not collapsing." << "No collapse axis found for face, not collapsing."
<< endl; << endl;
// Output face and collapse axis for visualisation
Info<< "# Aspect ratio = " << aspectRatio << nl
<< "# inertia = " << J << nl
<< "# determinant = " << detJ << nl
<< "# eigenvalues = " << eigenValues(J) << nl
<< "# collapseAxis = " << collapseAxis << nl
<< "# facePts = " << facePts << nl
<< endl;
forAll(f, fPtI)
{
meshTools::writeOBJ(Info, pts[f[fPtI]]);
}
Info<< "f";
forAll(f, fPtI)
{
Info << " " << fPtI + 1;
}
Info<< endl;
return fcmNone; return fcmNone;
} }
@ -980,8 +997,6 @@ Foam::conformalVoronoiMesh::collapseFace
// Sort the projected distances and the corresponding vertex // Sort the projected distances and the corresponding vertex
// indices along the collapse axis // indices along the collapse axis
labelList facePts(f);
labelList oldToNew; labelList oldToNew;
sortedOrder(d, oldToNew); sortedOrder(d, oldToNew);
@ -1214,6 +1229,34 @@ Foam::conformalVoronoiMesh::collapseFace
} }
Foam::label Foam::conformalVoronoiMesh::longestEdge
(
const face& f,
const pointField& pts
) const
{
const edgeList& eds = f.edges();
label longestEdgeI = -1;
scalar longestEdgeLength = -SMALL;
forAll(eds, edI)
{
scalar edgeLength = eds[edI].mag(pts);
if (edgeLength > longestEdgeLength)
{
longestEdgeI = edI;
longestEdgeLength = edgeLength;
}
}
return longestEdgeI;
}
void Foam::conformalVoronoiMesh::deferredCollapseFaceSet void Foam::conformalVoronoiMesh::deferredCollapseFaceSet
( (
labelList& owner, labelList& owner,