diff --git a/src/finiteVolume/fields/fvPatchFields/derived/turbulentDigitalFilterInlet/turbulentDigitalFilterInletFvPatchField.C b/src/finiteVolume/fields/fvPatchFields/derived/turbulentDigitalFilterInlet/turbulentDigitalFilterInletFvPatchField.C index f947bfb24f..904a693ddb 100644 --- a/src/finiteVolume/fields/fvPatchFields/derived/turbulentDigitalFilterInlet/turbulentDigitalFilterInletFvPatchField.C +++ b/src/finiteVolume/fields/fvPatchFields/derived/turbulentDigitalFilterInlet/turbulentDigitalFilterInletFvPatchField.C @@ -29,6 +29,7 @@ License #include "addToRunTimeSelectionTable.H" #include "faceAreaWeightAMI.H" #include "turbulentDFSEMInletFvPatchVectorField.H" +#include "AMIFieldOps.H" // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // @@ -82,14 +83,8 @@ void Foam::turbulentDigitalFilterInletFvPatchField::mapL } // Map two-point correlations (integral scales) - plusEqOp cop; - AMIPtr_->interpolateToSource - ( - sourceFld, - multiplyWeightedOp>(cop), - fld, - UList::null() - ); + AMIMultiplyWeightedOp cop(AMIPtr_(), true); + AMIPtr_->interpolate(sourceFld, cop, fld, UList::null()); // Map forward-stepwise method correlations if requested if (L_.fsm()) diff --git a/src/finiteVolume/fvMesh/fvPatches/constraint/cyclicACMI/cyclicACMIFvPatch.C b/src/finiteVolume/fvMesh/fvPatches/constraint/cyclicACMI/cyclicACMIFvPatch.C index 9fd6d217f9..acde31cfc5 100644 --- a/src/finiteVolume/fvMesh/fvPatches/constraint/cyclicACMI/cyclicACMIFvPatch.C +++ b/src/finiteVolume/fvMesh/fvPatches/constraint/cyclicACMI/cyclicACMIFvPatch.C @@ -100,12 +100,19 @@ void Foam::cyclicACMIFvPatch::makeWeights(scalarField& w) const // These deltas are of the cyclic part alone - they are // not affected by the amount of overlap with the nonOverlapPatch - scalarField nbrDeltas + scalarField nbrDeltas; + + const auto& AMI = owner() ? this->AMI() : nbrPatch.AMI(); + + // Multiply-weighted op - no low weight correction + auto cop = AMIMultiplyWeightedOp(AMI, owner()); + + AMI.interpolate ( - interpolate - ( - nbrPatch.nf() & nbrPatch.coupledFvPatch::delta() - ) + (nbrPatch.nf() & nbrPatch.coupledFvPatch::delta())(), + cop, + nbrDeltas, + UList() ); const scalar tol = cyclicACMIPolyPatch::tolerance(); @@ -244,31 +251,35 @@ Foam::tmp Foam::cyclicACMIFvPatch::delta() const const vectorField patchD(coupledFvPatch::delta()); - vectorField nbrPatchD(interpolate(nbrPatch.coupledFvPatch::delta())); + const auto& AMI = owner() ? this->AMI() : nbrPatch.AMI(); + + // Multiply-weighted op - no low weight correction + auto cop = AMIMultiplyWeightedOp(AMI, owner()); + + vectorField nbrPatchD; + AMI.interpolate + ( + nbrPatch.coupledFvPatch::delta()(), + cop, + nbrPatchD, + UList() + ); + + // Do the transformation if necessary + if (!parallel()) + { + transform(nbrPatchD, forwardT()[0], nbrPatchD); + } auto tpdv = tmp::New(patchD.size()); vectorField& pdv = tpdv.ref(); - // do the transformation if necessary - if (parallel()) + forAll(patchD, facei) { - forAll(patchD, facei) - { - const vector& ddi = patchD[facei]; - const vector& dni = nbrPatchD[facei]; - - pdv[facei] = ddi - dni; - } - } - else - { - forAll(patchD, facei) - { - const vector& ddi = patchD[facei]; - const vector& dni = nbrPatchD[facei]; - - pdv[facei] = ddi - transform(forwardT()[0], dni); - } + const vector& ddi = patchD[facei]; + const vector& dni = nbrPatchD[facei]; + pdv[facei] = ddi - dni; + pdv[facei] = ddi - dni; } return tpdv; diff --git a/src/finiteVolume/fvMesh/fvPatches/constraint/cyclicACMI/cyclicACMIFvPatch.H b/src/finiteVolume/fvMesh/fvPatches/constraint/cyclicACMI/cyclicACMIFvPatch.H index 9525a4db0a..f5eb7f7a50 100644 --- a/src/finiteVolume/fvMesh/fvPatches/constraint/cyclicACMI/cyclicACMIFvPatch.H +++ b/src/finiteVolume/fvMesh/fvPatches/constraint/cyclicACMI/cyclicACMIFvPatch.H @@ -251,7 +251,7 @@ public: localFld, requests, recvBuffers, - UList() + UList::null() ); } diff --git a/src/finiteVolume/fvMesh/fvPatches/constraint/cyclicAMI/cyclicAMIFvPatch.C b/src/finiteVolume/fvMesh/fvPatches/constraint/cyclicAMI/cyclicAMIFvPatch.C index 4bb5537ad3..4b2129f792 100644 --- a/src/finiteVolume/fvMesh/fvPatches/constraint/cyclicAMI/cyclicAMIFvPatch.C +++ b/src/finiteVolume/fvMesh/fvPatches/constraint/cyclicAMI/cyclicAMIFvPatch.C @@ -97,32 +97,50 @@ void Foam::cyclicAMIFvPatch::makeWeights(scalarField& w) const { const cyclicAMIFvPatch& nbrPatch = neighbFvPatch(); - const scalarField deltas(nf() & coupledFvPatch::delta()); + const auto& AMI = owner() ? this->AMI() : nbrPatch.AMI(); - tmp tnbrDeltas; + auto tnbrDeltas = tmp::New(); if (applyLowWeightCorrection()) { - tnbrDeltas = - interpolate - ( - nbrPatch.nf() & nbrPatch.coupledFvPatch::delta(), - scalarField(this->size(), 1.0) - ); + // Use 'assign' correction for geometric interpolation + auto cop = AMICorrectedMultiplyWeightedOp + ( + AMI, + owner(), + lowWeightCorrectionBase::option::ASSIGN + ); + + // Faces with invalid interpolation weights converted to one-sided + AMI.interpolate + ( + (nbrPatch.nf() & nbrPatch.coupledFvPatch::delta())(), + cop, + tnbrDeltas.ref(), + scalarList(this->size(), 1.0) + ); } else { - tnbrDeltas = - interpolate(nbrPatch.nf() & nbrPatch.coupledFvPatch::delta()); + // Multiply-weighted op - no low weight correction + auto cop = AMIMultiplyWeightedOp(AMI, owner()); + + AMI.interpolate + ( + (nbrPatch.nf() & nbrPatch.coupledFvPatch::delta())(), + cop, + tnbrDeltas.ref(), + UList::null() + ); } const scalarField& nbrDeltas = tnbrDeltas(); + const scalarField deltas(nf() & coupledFvPatch::delta()); forAll(deltas, facei) { // Note use of mag scalar di = mag(deltas[facei]); scalar dni = mag(nbrDeltas[facei]); - w[facei] = dni/(di + dni); } } @@ -162,46 +180,58 @@ Foam::tmp Foam::cyclicAMIFvPatch::delta() const { const vectorField patchD(coupledFvPatch::delta()); - tmp tnbrPatchD; + const auto& AMI = owner() ? this->AMI() : nbrPatch.AMI(); + + auto tnbrPatchD = tmp::New(); if (applyLowWeightCorrection()) { - tnbrPatchD = - interpolate - ( - nbrPatch.coupledFvPatch::delta(), - vectorField(this->size(), Zero) - ); + // Use 'assign' correction for geometric interpolation + auto cop = AMICorrectedMultiplyWeightedOp + ( + AMI, + owner(), + lowWeightCorrectionBase::option::ASSIGN + ); + + // Faces with invalid interpolation weights converted to one-sided + AMI.interpolate + ( + nbrPatch.coupledFvPatch::delta()(), + cop, + tnbrPatchD.ref(), + vectorField(this->size(), Zero) + ); } else { - tnbrPatchD = interpolate(nbrPatch.coupledFvPatch::delta()); + // Multiply-weighted op - no low weight correction + auto cop = AMIMultiplyWeightedOp(AMI, owner()); + + AMI.interpolate + ( + nbrPatch.coupledFvPatch::delta()(), + cop, + tnbrPatchD.ref(), + UList::null() + ); } - const vectorField& nbrPatchD = tnbrPatchD(); + vectorField& nbrPatchD = tnbrPatchD.ref(); + + // Do the transformation if necessary + if (!parallel()) + { + transform(nbrPatchD, forwardT()[0], nbrPatchD); + } auto tpdv = tmp::New(patchD.size()); vectorField& pdv = tpdv.ref(); - // do the transformation if necessary - if (parallel()) + forAll(patchD, facei) { - forAll(patchD, facei) - { - const vector& ddi = patchD[facei]; - const vector& dni = nbrPatchD[facei]; - - pdv[facei] = ddi - dni; - } - } - else - { - forAll(patchD, facei) - { - const vector& ddi = patchD[facei]; - const vector& dni = nbrPatchD[facei]; - - pdv[facei] = ddi - transform(forwardT()[0], dni); - } + const vector& ddi = patchD[facei]; + const vector& dni = nbrPatchD[facei]; + pdv[facei] = ddi - dni; } return tpdv; diff --git a/src/meshTools/AMIInterpolation/GAMG/interfaceFields/cyclicACMIGAMGInterfaceField/cyclicACMIGAMGInterfaceField.C b/src/meshTools/AMIInterpolation/GAMG/interfaceFields/cyclicACMIGAMGInterfaceField/cyclicACMIGAMGInterfaceField.C index 2d4491ca77..ccd7966a34 100644 --- a/src/meshTools/AMIInterpolation/GAMG/interfaceFields/cyclicACMIGAMGInterfaceField/cyclicACMIGAMGInterfaceField.C +++ b/src/meshTools/AMIInterpolation/GAMG/interfaceFields/cyclicACMIGAMGInterfaceField/cyclicACMIGAMGInterfaceField.C @@ -292,14 +292,15 @@ void Foam::cyclicACMIGAMGInterfaceField::updateInterfaceMatrix recvRequests_.clear(); solveScalarField pnf(faceCells.size(), Zero); - AMI.weightedSum + + AMIMultiplyWeightedOp cop ( - cyclicACMIInterface_.owner(), - work, - pnf, // result - solveScalarField::null() + AMI, + cyclicACMIInterface_.owner() ); + cop(pnf, work, solveScalarField::null()); + // Add result using coefficients this->addToInternalField(result, !add, faceCells, coeffs, pnf); } diff --git a/src/meshTools/AMIInterpolation/GAMG/interfaceFields/cyclicAMIGAMGInterfaceField/cyclicAMIGAMGInterfaceField.C b/src/meshTools/AMIInterpolation/GAMG/interfaceFields/cyclicAMIGAMGInterfaceField/cyclicAMIGAMGInterfaceField.C index 68d19e6c1d..f2030e10bc 100644 --- a/src/meshTools/AMIInterpolation/GAMG/interfaceFields/cyclicAMIGAMGInterfaceField/cyclicAMIGAMGInterfaceField.C +++ b/src/meshTools/AMIInterpolation/GAMG/interfaceFields/cyclicAMIGAMGInterfaceField/cyclicAMIGAMGInterfaceField.C @@ -306,13 +306,14 @@ void Foam::cyclicAMIGAMGInterfaceField::updateInterfaceMatrix recvRequests_.clear(); solveScalarField pnf(faceCells.size(), Zero); - AMI.weightedSum + + // Note: no low-weight correction + AMIMultiplyWeightedOp cop ( - cyclicAMIInterface_.owner(), - work, - pnf, // result - defaultValues + AMI, + cyclicAMIInterface_.owner() ); + cop(pnf, work, defaultValues); // Add result using coefficients this->addToInternalField(result, !add, faceCells, coeffs, pnf); @@ -329,13 +330,14 @@ void Foam::cyclicAMIGAMGInterfaceField::updateInterfaceMatrix transformCoupleField(work, cmpt); solveScalarField pnf(faceCells.size(), Zero); - AMI.weightedSum + + // Note: no low-weight correction + AMIMultiplyWeightedOp cop ( - cyclicAMIInterface_.owner(), - work, - pnf, // result - defaultValues + AMI, + cyclicAMIInterface_.owner() ); + cop(pnf, work, defaultValues); // Add result using coefficients this->addToInternalField(result, !add, faceCells, coeffs, pnf); diff --git a/src/meshTools/algorithms/MeshWave/FaceCellWave.C b/src/meshTools/algorithms/MeshWave/FaceCellWave.C index a5487c290a..33602a2053 100644 --- a/src/meshTools/algorithms/MeshWave/FaceCellWave.C +++ b/src/meshTools/algorithms/MeshWave/FaceCellWave.C @@ -38,6 +38,7 @@ License #include "typeInfo.H" #include "SubField.H" #include "globalMeshData.H" +#include "AMIFieldOps.H" // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // @@ -95,6 +96,73 @@ namespace Foam } } }; + + // Combine operator for AMIInterpolation + template + class combineField + : + public AMIFieldOpBase + { + // Private Data + + FaceCellWave& solver_; + + const cyclicAMIPolyPatch& patch_; + + + public: + + combineField + ( + FaceCellWave& solver, + const cyclicAMIPolyPatch& patch + ) + : + AMIFieldOpBase(patch.AMI(), patch.owner()), + solver_(solver), + patch_(patch) + {} + + void operator() + ( + List& result, + const UList& fld, + const UList& /* unused defaultValues */ + ) const + { + const auto& allSlots = address(); + + forAll(result, facei) + { + const labelList& slots = allSlots[facei]; + + for (const label sloti : slots) + { + if (fld[sloti].valid(solver_.data())) + { + label meshFacei = -1; + if (patch_.owner()) + { + meshFacei = patch_.start() + facei; + } + else + { + meshFacei = + patch_.neighbPatch().start() + facei; + } + result[facei].updateFace + ( + solver_.mesh(), + meshFacei, + fld[sloti], + solver_.propagationTol(), + solver_.data() + ); + } + } + } + } + }; } @@ -782,7 +850,7 @@ void Foam::FaceCellWave::handleAMICyclicPatches() } // Transfer sendInfo to cycPatch - combine cmb(*this, cycPatch); + combineField cmb(*this, cycPatch); if (cycPatch.applyLowWeightCorrection()) { diff --git a/src/meshTools/mappedPatches/mappedPolyPatch/mappedPatchBaseTemplates.C b/src/meshTools/mappedPatches/mappedPolyPatch/mappedPatchBaseTemplates.C index 7b6ce7e3ca..26cdff81a2 100644 --- a/src/meshTools/mappedPatches/mappedPolyPatch/mappedPatchBaseTemplates.C +++ b/src/meshTools/mappedPatches/mappedPolyPatch/mappedPatchBaseTemplates.C @@ -26,6 +26,9 @@ License \*---------------------------------------------------------------------------*/ +#include "AMIFieldOps.H" + + template void Foam::mappedPatchBase::distribute(List& lst) const { @@ -120,7 +123,9 @@ void Foam::mappedPatchBase::distribute const label oldWarnComm = UPstream::commWarn(myComm); const label oldWorldComm = UPstream::commWorld(myComm); - lst = interp.interpolateToSource(Field(std::move(lst)), cop); + const auto op = AMIFieldOp(interp, cop, true); + + lst = interp.interpolate(Field(std::move(lst)), op); UPstream::commWarn(oldWarnComm); UPstream::commWorld(oldWorldComm); @@ -206,7 +211,9 @@ void Foam::mappedPatchBase::reverseDistribute const label oldWarnComm = UPstream::commWarn(myComm); const label oldWorldComm = UPstream::commWorld(myComm); - lst = interp.interpolateToTarget(Field(std::move(lst)), cop); + const auto op = AMIFieldOp(interp, false); + + lst = interp.interpolate(Field(std::move(lst)), op); UPstream::commWarn(oldWarnComm); UPstream::commWorld(oldWorldComm); diff --git a/src/parallel/decompose/decompositionMethods/decompositionConstraints/decompositionConstraint/decompositionConstraint.C b/src/parallel/decompose/decompositionMethods/decompositionConstraints/decompositionConstraint/decompositionConstraint.C index e4ec1fd613..da834592eb 100644 --- a/src/parallel/decompose/decompositionMethods/decompositionConstraints/decompositionConstraint/decompositionConstraint.C +++ b/src/parallel/decompose/decompositionMethods/decompositionConstraints/decompositionConstraint/decompositionConstraint.C @@ -78,44 +78,8 @@ void Foam::decompositionConstraint::getMinBoundaryValue const labelList nbrDecomp(decomposition, nbrPp.faceCells()); labelList thisDecomp(decomposition, cycPp.faceCells()); - if (cycPp.owner()) - { - cycPp.AMI().interpolateToSource - ( - nbrDecomp, - [] - ( - label& res, - const label facei, - const label& fld, - const scalar& w - ) - { - res = min(res, fld); - }, - thisDecomp, - thisDecomp // used in case of low-weight-corr - ); - } - else - { - nbrPp.AMI().interpolateToTarget - ( - nbrDecomp, - [] - ( - label& res, - const label facei, - const label& fld, - const scalar& w - ) - { - res = min(res, fld); - }, - thisDecomp, - thisDecomp // used in case of low-weight-corr - ); - } + AMIMinOp