diff --git a/src/meshTools/AMIInterpolation/AMIInterpolation/advancingFrontAMI/advancingFrontAMI.C b/src/meshTools/AMIInterpolation/AMIInterpolation/advancingFrontAMI/advancingFrontAMI.C index 01f83db8c07c355ed3e5c1143524a57abe6eb189..bb434401bcd78bede115fd58996d03ab356c0be1 100644 --- a/src/meshTools/AMIInterpolation/AMIInterpolation/advancingFrontAMI/advancingFrontAMI.C +++ b/src/meshTools/AMIInterpolation/AMIInterpolation/advancingFrontAMI/advancingFrontAMI.C @@ -81,6 +81,57 @@ void Foam::advancingFrontAMI::checkPatches() const } +bool Foam::advancingFrontAMI::isCandidate +( + const label srcFacei, + const label tgtFacei +) const +{ + const auto& srcPatch = this->srcPatch(); + const auto& tgtPatch = this->tgtPatch(); + + if + ( + (srcMagSf_[srcFacei] < ROOTVSMALL) + || (tgtMagSf_[tgtFacei] < ROOTVSMALL) + ) + { + return false; + } + + if (maxDistance2_ > 0) + { + const point& srcFc = srcPatch.faceCentres()[srcFacei]; + const point& tgtFc = tgtPatch.faceCentres()[tgtFacei]; + const vector& srcN = srcPatch.faceNormals()[srcFacei]; + + const scalar normalDist((tgtFc-srcFc)&srcN); + //if (magSqr(srcFc-tgtFc) >= maxDistance2_) + if (sqr(normalDist) >= maxDistance2_) + { + return false; + } + } + + if (minCosAngle_ > -1) + { + const vector& srcN = srcPatch.faceNormals()[srcFacei]; + vector tgtN = tgtPatch.faceNormals()[tgtFacei]; + if (!reverseTarget_) + { + tgtN = -tgtN; + } + + if ((srcN & tgtN) <= minCosAngle_) + { + return false; + } + } + + return true; +} + + void Foam::advancingFrontAMI::createExtendedTgtPatch() { // Create processor map of extended cells. This map gets (possibly @@ -251,7 +302,7 @@ Foam::label Foam::advancingFrontAMI::findTargetFace const pointIndexHit sample = treePtr_->findNearest(srcPt, magSqr(bb.max() - bb.centre()), fnOp); - if (sample.hit()) + if (sample.hit() && isCandidate(srcFacei, sample.index())) { targetFacei = sample.index(); @@ -375,6 +426,8 @@ Foam::advancingFrontAMI::advancingFrontAMI ) : AMIInterpolation(dict, reverseTarget), + maxDistance2_(dict.getOrDefault("maxDistance2", -1)), + minCosAngle_(dict.getOrDefault("minCosAngle", -1)), srcTris_(), tgtTris_(), extendedTgtPatchPtr_(nullptr), @@ -404,6 +457,8 @@ Foam::advancingFrontAMI::advancingFrontAMI ) : AMIInterpolation(requireMatch, reverseTarget, lowWeightCorrection), + maxDistance2_(-1), + minCosAngle_(-1), srcTris_(), tgtTris_(), extendedTgtPatchPtr_(nullptr), @@ -419,6 +474,8 @@ Foam::advancingFrontAMI::advancingFrontAMI Foam::advancingFrontAMI::advancingFrontAMI(const advancingFrontAMI& ami) : AMIInterpolation(ami), + maxDistance2_(ami.maxDistance2_), + minCosAngle_(ami.minCosAngle_), srcTris_(), tgtTris_(), extendedTgtPatchPtr_(nullptr), @@ -452,6 +509,24 @@ bool Foam::advancingFrontAMI::calculate const auto& src = this->srcPatch(); const auto& tgt = this->tgtPatch(); + + if (maxDistance2_ > 0) + { + // Early trigger face centre calculation + (void)src.faceCentres(); + (void)tgt.faceCentres(); + // Early trigger face normals calculation + (void)src.faceNormals(); + (void)tgt.faceNormals(); + } + if (minCosAngle_ > -1) + { + // Early trigger face normals calculation + (void)src.faceNormals(); + (void)tgt.faceNormals(); + } + + // Initialise area magnitudes srcMagSf_.setSize(src.size(), 1.0); tgtMagSf_.setSize(tgt.size(), 1.0); @@ -479,6 +554,8 @@ bool Foam::advancingFrontAMI::calculate void Foam::advancingFrontAMI::write(Ostream& os) const { AMIInterpolation::write(os); + os.writeEntryIfDifferent("maxDistance2", -1, maxDistance2_); + os.writeEntryIfDifferent("minCosAngle", -1, minCosAngle_); os.writeEntryIfDifferent ( "triMode", diff --git a/src/meshTools/AMIInterpolation/AMIInterpolation/advancingFrontAMI/advancingFrontAMI.H b/src/meshTools/AMIInterpolation/AMIInterpolation/advancingFrontAMI/advancingFrontAMI.H index 9ba117ecd30800a26ad8fe90409e714f4171bec4..5cfec3e12d2363d6d204570d8d2bf2ef0403584c 100644 --- a/src/meshTools/AMIInterpolation/AMIInterpolation/advancingFrontAMI/advancingFrontAMI.H +++ b/src/meshTools/AMIInterpolation/AMIInterpolation/advancingFrontAMI/advancingFrontAMI.H @@ -106,6 +106,12 @@ protected: // Protected data + //- Maximum squared distance + const scalar maxDistance2_; + + //- Minimum (cos of) angle. 1 for perfectly matching. + const scalar minCosAngle_; + //- Storage for src-side triangle decomposition List> srcTris_; @@ -148,6 +154,10 @@ protected: //- Check AMI patch coupling void checkPatches() const; + //- Is source/target a valid pair (i.e. not too far/different + // orientation). Used for prefiltering before e.g. area overlap + bool isCandidate(const label srcFacei, const label tgtFacei) const; + virtual bool calculate ( const primitivePatch& srcPatch, diff --git a/src/meshTools/AMIInterpolation/AMIInterpolation/faceAreaWeightAMI/faceAreaWeightAMI.C b/src/meshTools/AMIInterpolation/AMIInterpolation/faceAreaWeightAMI/faceAreaWeightAMI.C index 53063cce63356b2c8f76fc96c006714b73ada47a..fe29d2c2c5cd7d618f92750c2f61e1a76fc43eec 100644 --- a/src/meshTools/AMIInterpolation/AMIInterpolation/faceAreaWeightAMI/faceAreaWeightAMI.C +++ b/src/meshTools/AMIInterpolation/AMIInterpolation/faceAreaWeightAMI/faceAreaWeightAMI.C @@ -379,12 +379,8 @@ void Foam::faceAreaWeightAMI::calcInterArea { addProfiling(ami, "faceAreaWeightAMI::interArea"); - // Quick reject if either face has zero area - if - ( - (srcMagSf_[srcFacei] < ROOTVSMALL) - || (tgtMagSf_[tgtFacei] < ROOTVSMALL) - ) + // Quick reject if either face has zero area/too far away/wrong orientation + if (!isCandidate(srcFacei, tgtFacei)) { return; } @@ -459,12 +455,8 @@ bool Foam::faceAreaWeightAMI::overlaps const scalar threshold ) const { - // Quick reject if either face has zero area - if - ( - (srcMagSf_[srcFacei] < ROOTVSMALL) - || (tgtMagSf_[tgtFacei] < ROOTVSMALL) - ) + // Quick reject if either face has zero area/too far away/wrong orientation + if (!isCandidate(srcFacei, tgtFacei)) { return false; } diff --git a/src/meshTools/AMIInterpolation/AMIInterpolation/faceAreaWeightAMI2D/faceAreaWeightAMI2D.C b/src/meshTools/AMIInterpolation/AMIInterpolation/faceAreaWeightAMI2D/faceAreaWeightAMI2D.C index bec5662ac9a45f5f855a4c4bc82769761bb1a97d..0e0be21dca960efadb47e5b276548425e84148a3 100644 --- a/src/meshTools/AMIInterpolation/AMIInterpolation/faceAreaWeightAMI2D/faceAreaWeightAMI2D.C +++ b/src/meshTools/AMIInterpolation/AMIInterpolation/faceAreaWeightAMI2D/faceAreaWeightAMI2D.C @@ -133,12 +133,8 @@ void Foam::faceAreaWeightAMI2D::storeInterArea { addProfiling(ami, "faceAreaWeightAMI2D::calcInterArea"); - // Quick reject if either face has zero area - if - ( - (srcMagSf_[srcFacei] < ROOTVSMALL) - || (tgtMagSf_[tgtFacei] < ROOTVSMALL) - ) + // Quick reject if either face has zero area/too far away/wrong orientation + if (!isCandidate(srcFacei, tgtFacei)) { return; }