ENH: Various improvements.

+ No fatal error on triSurfaceTools::surfaceSide, commented out WarningIn.

  + Make cellSizeControlSurfaces look for a GREAT span for the nearest surface
    point.

  + Identify and limit filtering on single internal face cells in polyMesh
    quality assessment.

  + Create cellSet of remaining protruding cells after polyMesh creation.

  + Implemented wellOutside function by generalising wellInside to
    wellInOutSide.
This commit is contained in:
graham
2011-01-24 13:19:44 +00:00
parent 5cd9ccf88b
commit b328499d02
8 changed files with 322 additions and 124 deletions

View File

@ -97,6 +97,53 @@ void deleteBox
} }
void drawHitProblem
(
label fI,
const triSurface& surf,
const pointField& start,
const pointField& faceCentres,
const pointField& end,
const List<pointIndexHit>& hitInfo
)
{
Info<< nl << "# findLineAll did not hit its own face."
<< nl << "# fI " << fI
<< nl << "# start " << start[fI]
<< nl << "# f centre " << faceCentres[fI]
<< nl << "# end " << end[fI]
<< nl << "# hitInfo " << hitInfo
<< endl;
meshTools::writeOBJ(Info, start[fI]);
meshTools::writeOBJ(Info, faceCentres[fI]);
meshTools::writeOBJ(Info, end[fI]);
Info<< "l 1 2 3" << endl;
meshTools::writeOBJ(Info, surf.points()[surf[fI][0]]);
meshTools::writeOBJ(Info, surf.points()[surf[fI][1]]);
meshTools::writeOBJ(Info, surf.points()[surf[fI][2]]);
Info<< "f 4 5 6" << endl;
forAll(hitInfo, hI)
{
label hFI = hitInfo[hI].index();
meshTools::writeOBJ(Info, surf.points()[surf[hFI][0]]);
meshTools::writeOBJ(Info, surf.points()[surf[hFI][1]]);
meshTools::writeOBJ(Info, surf.points()[surf[hFI][2]]);
Info<< "f "
<< 3*hI + 7 << " "
<< 3*hI + 8 << " "
<< 3*hI + 9
<< endl;
}
}
scalarField curvature(const triSurface& surf) scalarField curvature(const triSurface& surf)
{ {
scalarField k(surf.points().size(), 0); scalarField k(surf.points().size(), 0);
@ -598,23 +645,24 @@ int main(int argc, char *argv[])
if (hitInfo.size() < 1) if (hitInfo.size() < 1)
{ {
Info<< nl << "# fI " << fI drawHitProblem(fI, surf, start, faceCentres, end, hitInfo);
<< nl << "# start " << start[fI] // Info<< nl << "# fI " << fI
<< nl << "# f centre " << faceCentres[fI] // << nl << "# start " << start[fI]
<< nl << "# end " << end[fI] // << nl << "# f centre " << faceCentres[fI]
<< endl; // << nl << "# end " << end[fI]
// << endl;
meshTools::writeOBJ(Info, start[fI]); // meshTools::writeOBJ(Info, start[fI]);
meshTools::writeOBJ(Info, faceCentres[fI]); // meshTools::writeOBJ(Info, faceCentres[fI]);
meshTools::writeOBJ(Info, end[fI]); // meshTools::writeOBJ(Info, end[fI]);
Info<< "l 1 2 3" << endl; // Info<< "l 1 2 3" << endl;
meshTools::writeOBJ(Info, surf.points()[surf[fI][0]]); // meshTools::writeOBJ(Info, surf.points()[surf[fI][0]]);
meshTools::writeOBJ(Info, surf.points()[surf[fI][1]]); // meshTools::writeOBJ(Info, surf.points()[surf[fI][1]]);
meshTools::writeOBJ(Info, surf.points()[surf[fI][2]]); // meshTools::writeOBJ(Info, surf.points()[surf[fI][2]]);
Info<< "f 4 5 6" << endl; // Info<< "f 4 5 6" << endl;
FatalErrorIn(args.executable()) FatalErrorIn(args.executable())
<< "findLineAll did not hit its own face." << "findLineAll did not hit its own face."
@ -630,40 +678,42 @@ int main(int argc, char *argv[])
} }
else if (hitInfo[0].index() != fI) else if (hitInfo[0].index() != fI)
{ {
Info<< nl << "# findLineAll did not hit its own face." drawHitProblem(fI, surf, start, faceCentres, end, hitInfo);
<< nl << "# fI " << fI
<< nl << "# start " << start[fI]
<< nl << "# f centre " << faceCentres[fI]
<< nl << "# end " << end[fI]
<< nl << "# hitInfo " << hitInfo
<< endl;
meshTools::writeOBJ(Info, start[fI]); // Info<< nl << "# findLineAll did not hit its own face."
meshTools::writeOBJ(Info, faceCentres[fI]); // << nl << "# fI " << fI
meshTools::writeOBJ(Info, end[fI]); // << nl << "# start " << start[fI]
// << nl << "# f centre " << faceCentres[fI]
// << nl << "# end " << end[fI]
// << nl << "# hitInfo " << hitInfo
// << endl;
Info<< "l 1 2 3" << endl; // meshTools::writeOBJ(Info, start[fI]);
// meshTools::writeOBJ(Info, faceCentres[fI]);
// meshTools::writeOBJ(Info, end[fI]);
meshTools::writeOBJ(Info, surf.points()[surf[fI][0]]); // Info<< "l 1 2 3" << endl;
meshTools::writeOBJ(Info, surf.points()[surf[fI][1]]);
meshTools::writeOBJ(Info, surf.points()[surf[fI][2]]);
Info<< "f 4 5 6" << endl; // meshTools::writeOBJ(Info, surf.points()[surf[fI][0]]);
// meshTools::writeOBJ(Info, surf.points()[surf[fI][1]]);
// meshTools::writeOBJ(Info, surf.points()[surf[fI][2]]);
forAll(hitInfo, hI) // Info<< "f 4 5 6" << endl;
{
label hFI = hitInfo[hI].index();
meshTools::writeOBJ(Info, surf.points()[surf[hFI][0]]); // forAll(hitInfo, hI)
meshTools::writeOBJ(Info, surf.points()[surf[hFI][1]]); // {
meshTools::writeOBJ(Info, surf.points()[surf[hFI][2]]); // label hFI = hitInfo[hI].index();
Info<< "f " // meshTools::writeOBJ(Info, surf.points()[surf[hFI][0]]);
<< 3*hI + 7 << " " // meshTools::writeOBJ(Info, surf.points()[surf[hFI][1]]);
<< 3*hI + 8 << " " // meshTools::writeOBJ(Info, surf.points()[surf[hFI][2]]);
<< 3*hI + 9
<< endl; // Info<< "f "
} // << 3*hI + 7 << " "
// << 3*hI + 8 << " "
// << 3*hI + 9
// << endl;
// }
// FatalErrorIn(args.executable()) // FatalErrorIn(args.executable())
// << "findLineAll did not hit its own face." // << "findLineAll did not hit its own face."
// << exit(FatalError); // << exit(FatalError);
@ -687,40 +737,41 @@ int main(int argc, char *argv[])
if (ownHitI < 0) if (ownHitI < 0)
{ {
Info<< nl << "# findLineAll did not hit its own face." drawHitProblem(fI, surf, start, faceCentres, end, hitInfo);
<< nl << "# fI " << fI // Info<< nl << "# findLineAll did not hit its own face."
<< nl << "# start " << start[fI] // << nl << "# fI " << fI
<< nl << "# f centre " << faceCentres[fI] // << nl << "# start " << start[fI]
<< nl << "# end " << end[fI] // << nl << "# f centre " << faceCentres[fI]
<< nl << "# hitInfo " << hitInfo // << nl << "# end " << end[fI]
<< endl; // << nl << "# hitInfo " << hitInfo
// << endl;
meshTools::writeOBJ(Info, start[fI]); // meshTools::writeOBJ(Info, start[fI]);
meshTools::writeOBJ(Info, faceCentres[fI]); // meshTools::writeOBJ(Info, faceCentres[fI]);
meshTools::writeOBJ(Info, end[fI]); // meshTools::writeOBJ(Info, end[fI]);
Info<< "l 1 2 3" << endl; // Info<< "l 1 2 3" << endl;
meshTools::writeOBJ(Info, surf.points()[surf[fI][0]]); // meshTools::writeOBJ(Info, surf.points()[surf[fI][0]]);
meshTools::writeOBJ(Info, surf.points()[surf[fI][1]]); // meshTools::writeOBJ(Info, surf.points()[surf[fI][1]]);
meshTools::writeOBJ(Info, surf.points()[surf[fI][2]]); // meshTools::writeOBJ(Info, surf.points()[surf[fI][2]]);
Info<< "f 4 5 6" << endl; // Info<< "f 4 5 6" << endl;
forAll(hitInfo, hI) // forAll(hitInfo, hI)
{ // {
label hFI = hitInfo[hI].index(); // label hFI = hitInfo[hI].index();
meshTools::writeOBJ(Info, surf.points()[surf[hFI][0]]); // meshTools::writeOBJ(Info, surf.points()[surf[hFI][0]]);
meshTools::writeOBJ(Info, surf.points()[surf[hFI][1]]); // meshTools::writeOBJ(Info, surf.points()[surf[hFI][1]]);
meshTools::writeOBJ(Info, surf.points()[surf[hFI][2]]); // meshTools::writeOBJ(Info, surf.points()[surf[hFI][2]]);
Info<< "f " // Info<< "f "
<< 3*hI + 7 << " " // << 3*hI + 7 << " "
<< 3*hI + 8 << " " // << 3*hI + 8 << " "
<< 3*hI + 9 // << 3*hI + 9
<< endl; // << endl;
} // }
// FatalErrorIn(args.executable()) // FatalErrorIn(args.executable())
// << "findLineAll did not hit its own face." // << "findLineAll did not hit its own face."

View File

@ -301,7 +301,7 @@ Foam::scalar Foam::cellSizeControlSurfaces::cellSize
cvMesh_.geometryToConformTo().findSurfaceNearest cvMesh_.geometryToConformTo().findSurfaceNearest
( (
pt, pt,
cvMesh_.geometryToConformTo().spanMagSqr(), sqr(GREAT),
surfHit, surfHit,
hitSurface hitSurface
); );
@ -316,11 +316,7 @@ Foam::scalar Foam::cellSizeControlSurfaces::cellSize
"bool isSurfacePoint" "bool isSurfacePoint"
") const" ") const"
) )
<< "Point " << pt << "was not within " << "Point " << pt << " did not find a nearest surface point"
<< cvMesh_.geometryToConformTo().spanMag()
<< " of the surface." << nl
<< "findSurfaceNearest did not find a hit across the span "
<< "of the surfaces."
<< nl << exit(FatalError) << endl; << nl << exit(FatalError) << endl;
} }
else else

View File

@ -64,6 +64,7 @@ SourceFiles
#include "HashSet.H" #include "HashSet.H"
#include "memInfo.H" #include "memInfo.H"
#include "point.H" #include "point.H"
#include "cellSet.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -797,6 +798,10 @@ public:
// target cell volume, actual cell volume and equivalent // target cell volume, actual cell volume and equivalent
// actual cell size (cbrt(actual cell volume)). // actual cell size (cbrt(actual cell volume)).
void writeCellSizes(const fvMesh& mesh) const; void writeCellSizes(const fvMesh& mesh) const;
//- Find the cellSet of the boundary cells which have points that
// protrude out of the surface beyond a tolerance.
void findRemainingProtrusionSet(const fvMesh& mesh) const;
}; };

View File

@ -1531,6 +1531,8 @@ Foam::labelHashSet Foam::conformalVoronoiMesh::checkPolyMeshQuality
wrongFaces wrongFaces
); );
{
// Check for cells with more than 1 but fewer than 4 faces
label nInvalidPolyhedra = 0; label nInvalidPolyhedra = 0;
const cellList& cells = pMesh.cells(); const cellList& cells = pMesh.cells();
@ -1552,9 +1554,54 @@ Foam::labelHashSet Foam::conformalVoronoiMesh::checkPolyMeshQuality
} }
} }
Info<< "Cells with more than 1 but fewer than 4 faces : " Info<< " cells with more than 1 but fewer than 4 faces : "
<< nInvalidPolyhedra << endl; << nInvalidPolyhedra << endl;
// Check for cells with one internal face only
labelList nInternalFaces(pMesh.nCells(), 0);
for (label fI = 0; fI < pMesh.nInternalFaces(); fI++)
{
nInternalFaces[pMesh.faceOwner()[fI]]++;
nInternalFaces[pMesh.faceNeighbour()[fI]]++;
}
const polyBoundaryMesh& patches = pMesh.boundaryMesh();
forAll(patches, patchI)
{
if (patches[patchI].coupled())
{
const labelUList& owners = patches[patchI].faceCells();
forAll(owners, i)
{
nInternalFaces[owners[i]]++;
}
}
}
label oneInternalFaceCells = 0;
forAll(nInternalFaces, cI)
{
if (nInternalFaces[cI] <= 1)
{
oneInternalFaceCells++;
forAll(cells[cI], cFI)
{
wrongFaces.insert(cells[cI][cFI]);
}
}
}
Info<< " cells with with zero or one non-boundary face : "
<< oneInternalFaceCells << endl;
}
PackedBoolList ptToBeLimited(pts.size(), false); PackedBoolList ptToBeLimited(pts.size(), false);
forAllConstIter(labelHashSet, wrongFaces, iter) forAllConstIter(labelHashSet, wrongFaces, iter)

View File

@ -328,6 +328,8 @@ void Foam::conformalVoronoiMesh::writeMesh
// cellCs.write(); // cellCs.write();
writeCellSizes(mesh); writeCellSizes(mesh);
findRemainingProtrusionSet(mesh);
} }
@ -512,4 +514,69 @@ void Foam::conformalVoronoiMesh::writeCellSizes
} }
void Foam::conformalVoronoiMesh::findRemainingProtrusionSet
(
const fvMesh& mesh
) const
{
timeCheck("Start findRemainingProtrusionSet");
const polyBoundaryMesh& patches = mesh.boundaryMesh();
labelHashSet protrudingBoundaryPoints;
forAll(patches, patchI)
{
const labelList& patchLocalPtIs = patches[patchI].boundaryPoints();
forAll(patchLocalPtIs, ppI)
{
label meshPtI = patches[patchI].meshPoints()[patchLocalPtIs[ppI]];
const Foam::point& pt = mesh.points()[meshPtI];
if
(
geometryToConformTo_.wellOutside
(
pt,
sqr(2.0*maxSurfaceProtrusion(pt))
)
)
{
protrudingBoundaryPoints.insert(meshPtI);
}
}
}
cellSet protrudingCells
(
mesh,
"cvMesh_remainingProtrusions",
mesh.nCells()/1000
);
forAllConstIter(labelHashSet, protrudingBoundaryPoints, iter)
{
const label pointI = iter.key();
const labelList& pCells = mesh.pointCells()[pointI];
forAll(pCells, pCellI)
{
protrudingCells.insert(pCells[pCellI]);
}
}
if (!protrudingCells.empty())
{
Info<< nl << "Found " << protrudingCells.size()
<< " cells protruding from the surface, writing cellSet "
<< protrudingCells.name()
<< endl;
protrudingCells.write();
}
}
// ************************************************************************* // // ************************************************************************* //

View File

@ -329,10 +329,11 @@ bool Foam::conformationSurfaces::outside
} }
Foam::Field<bool> Foam::conformationSurfaces::wellInside Foam::Field<bool> Foam::conformationSurfaces::wellInOutSide
( (
const pointField& samplePts, const pointField& samplePts,
const scalarField& testDistSqr const scalarField& testDistSqr,
bool testForInside
) const ) const
{ {
List<List<searchableSurface::volumeType> > surfaceVolumeTests List<List<searchableSurface::volumeType> > surfaceVolumeTests
@ -360,7 +361,7 @@ Foam::Field<bool> Foam::conformationSurfaces::wellInside
// reference value and if the points are inside the surface by a given // reference value and if the points are inside the surface by a given
// distanceSquared // distanceSquared
Field<bool> insidePoints(samplePts.size(), true); Field<bool> inOutSidePoint(samplePts.size(), true);
//Check if the points are inside the surface by the given distance squared //Check if the points are inside the surface by the given distance squared
@ -384,23 +385,39 @@ Foam::Field<bool> Foam::conformationSurfaces::wellInside
if (pHit.hit()) if (pHit.hit())
{ {
insidePoints[i] = false; // If the point is within range of the surface, then it can't be
// well (in|out)side
inOutSidePoint[i] = false;
continue; continue;
} }
forAll(surfaces_, s) forAll(surfaces_, s)
{ {
// If one of the pattern tests is failed, then the point cannot be
// inside, therefore, if this is a testForInside = true call, the
// result is false. If this is a testForInside = false call, then
// the result is true.
if (surfaceVolumeTests[s][i] != referenceVolumeTypes_[s]) if (surfaceVolumeTests[s][i] != referenceVolumeTypes_[s])
{ {
insidePoints[i] = false; inOutSidePoint[i] = !testForInside;
break; break;
} }
} }
} }
return insidePoints; return inOutSidePoint;
}
Foam::Field<bool> Foam::conformationSurfaces::wellInside
(
const pointField& samplePts,
const scalarField& testDistSqr
) const
{
return wellInOutSide(samplePts, testDistSqr, true);
} }
@ -420,9 +437,7 @@ Foam::Field<bool> Foam::conformationSurfaces::wellOutside
const scalarField& testDistSqr const scalarField& testDistSqr
) const ) const
{ {
notImplemented("Field<bool> Foam::conformationSurfaces::wellOutside"); return wellInOutSide(samplePts, testDistSqr, false);
return Field<bool>(samplePts.size(), true);
} }

View File

@ -176,6 +176,16 @@ public:
//- Check if point is outside surfaces to conform to //- Check if point is outside surfaces to conform to
bool outside(const point& samplePt) const; bool outside(const point& samplePt) const;
//- Check if point is closer to the surfaces to conform to than
// testDistSqr, in which case return false, otherwise assess in or
// outside and erturn a result depending on the testForInside flag
Field<bool> wellInOutSide
(
const pointField& samplePts,
const scalarField& testDistSqr,
bool testForInside
) const;
//- Check if point is inside surfaces to conform to by at least //- Check if point is inside surfaces to conform to by at least
// testDistSqr // testDistSqr
Field<bool> wellInside Field<bool> wellInside

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2004-2010 OpenCFD Ltd. \\ / A nd | Copyright (C) 2004-2011 OpenCFD Ltd.
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -2209,38 +2209,45 @@ Foam::triSurfaceTools::sideType Foam::triSurfaceTools::surfaceSide
{ {
vector sampleNearestVec = (sample - nearestPoint); vector sampleNearestVec = (sample - nearestPoint);
scalar magSampleNearestVec = mag(sampleNearestVec);
// Nearest to face interior. Use faceNormal to determine side // Nearest to face interior. Use faceNormal to determine side
scalar c = sampleNearestVec & surf.faceNormals()[nearestFaceI]; scalar c = sampleNearestVec & surf.faceNormals()[nearestFaceI];
// If the sample is essentially on the face, do not check for // If the sample is essentially on the face, do not check for
// it being perpendicular. // it being perpendicular.
if (magSampleNearestVec > 10*SMALL) // if (debug)
{ // {
c /= magSampleNearestVec*mag(surf.faceNormals()[nearestFaceI]); // scalar magSampleNearestVec = mag(sampleNearestVec);
if (mag(c) < 0.99) // if (magSampleNearestVec > SMALL)
{ // {
FatalErrorIn("triSurfaceTools::surfaceSide") // c /=
<< "nearestPoint identified as being on triangle face " // magSampleNearestVec
<< "but vector from nearestPoint to sample is not " // *mag(surf.faceNormals()[nearestFaceI]);
<< "perpendicular to the normal." << nl
<< "sample: " << sample << nl // if (mag(c) < 0.99)
<< "nearestPoint: " << nearestPoint << nl // {
<< "sample - nearestPoint: " << sample - nearestPoint << nl // WarningIn("triSurfaceTools::surfaceSide")
<< "normal: " << surf.faceNormals()[nearestFaceI] << nl // << "nearestPoint identified as being on triangle "
<< "mag(sample - nearestPoint): " // << "face but vector from nearestPoint to sample is "
<< mag(sample - nearestPoint) << nl // << "not perpendicular to the normal." << nl
<< "normalised dot product: " << c << nl // << "sample: " << sample << nl
<< "triangle vertices: " << nl // << "nearestPoint: " << nearestPoint << nl
<< " " << points[f[0]] << nl // << "sample - nearestPoint: "
<< " " << points[f[1]] << nl // << sample - nearestPoint << nl
<< " " << points[f[2]] << nl // << "normal: "
<< abort(FatalError); // << surf.faceNormals()[nearestFaceI] << nl
} // << "mag(sample - nearestPoint): "
} // << mag(sample - nearestPoint) << nl
// << "normalised dot product: " << c << nl
// << "triangle vertices: " << nl
// << " " << points[f[0]] << nl
// << " " << points[f[1]] << nl
// << " " << points[f[2]] << nl
// << endl;;
// }
// }
// }
if (c > 0) if (c > 0)
{ {