diff --git a/src/lagrangian/basic/Cloud/Cloud.C b/src/lagrangian/basic/Cloud/Cloud.C index e3e0b4f63f..7c2b383b83 100644 --- a/src/lagrangian/basic/Cloud/Cloud.C +++ b/src/lagrangian/basic/Cloud/Cloud.C @@ -31,6 +31,250 @@ License #include "mapPolyMesh.H" #include "Time.H" #include "OFstream.H" +#include "triPointRef.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +template +const Foam::scalar Foam::Cloud::minValidTrackFraction = 1e-10; + +template +const Foam::scalar Foam::Cloud::trackingRescueTolerance = 1e-3; + +template +const Foam::scalar Foam::Cloud::intersectionTolerance = 1e-6; + +template +const Foam::scalar Foam::Cloud::planarCosAngle = (1 - 1e-6); + + +// * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * // + +// Calculate using face properties only +template +Foam::label Foam::Cloud::isIntrudingFace +( + const label cellI, + const label f0I, + const label f1I +) const +{ + const vectorField& fAreas = pMesh().faceAreas(); + const pointField& fCentres = pMesh().faceCentres(); + const labelList& fOwner = pMesh().faceOwner(); + const pointField& points = pMesh().points(); + + // Get f0 centre + const point& fc0 = fCentres[f0I]; + + const face& f0 = pMesh().faces()[f0I]; + + const face& f1 = pMesh().faces()[f1I]; + + vector fn0 = fAreas[f0I]; + fn0 /= (mag(fn0) + VSMALL); + + // Flip normal if required so that it is always pointing out of + // the cell + if (fOwner[f0I] != cellI) + { + fn0 *= -1; + } + + // Is any vertex of f1 on wrong side of the plane of f0? + + forAll(f1, f1pI) + { + label ptI = f1[f1pI]; + + // Skip points that are shared between f1 and f0 + if (findIndex(f0, ptI) > -1) + { + continue; + } + + const point& pt = points[ptI]; + + // Normal distance from fc0 to pt + scalar d = ((fc0 - pt) & fn0); + + if (d < 0) + { + // Proper concave: f1 on wrong side of f0 + return 2; + } + } + + // Could be a convex cell, but check angle for planar faces. + + vector fn1 = fAreas[f1I]; + fn1 /= (mag(fn1) + VSMALL); + + // Flip normal if required so that it is always pointing out of + // the cell + if (fOwner[f1I] != cellI) + { + fn1 *= -1; + } + + if ((fn0 & fn1) > planarCosAngle) + { + // Planar face + return 1; + } + + return 0; +} + + +template +void Foam::Cloud::calcIntrudingFaces() const +{ + const labelList& fOwner = pMesh().faceOwner(); + const cellList& cells = pMesh().cells(); + + intrudesIntoOwnerPtr_.reset(new PackedBoolList(pMesh().nFaces())); + PackedBoolList& intrudesIntoOwner = intrudesIntoOwnerPtr_(); + intrudesIntoNeighbourPtr_.reset(new PackedBoolList(pMesh().nFaces())); + PackedBoolList& intrudesIntoNeighbour = intrudesIntoNeighbourPtr_(); + + PackedBoolList cellsWithProblemFaces(cells.size()); + DynamicList