diff --git a/src/finiteVolume/fields/fvPatchFields/derived/turbulentDigitalFilterInlet/turbulentDigitalFilterInletFvPatchField.C b/src/finiteVolume/fields/fvPatchFields/derived/turbulentDigitalFilterInlet/turbulentDigitalFilterInletFvPatchField.C index f947bfb24f5d22cebb1eb3f954887c7cfe23be28..904a693ddbeccdad6e8ae875e1c5592c809b2553 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<Type>::mapL } // Map two-point correlations (integral scales) - plusEqOp<Type> cop; - AMIPtr_->interpolateToSource - ( - sourceFld, - multiplyWeightedOp<Type, plusEqOp<Type>>(cop), - fld, - UList<Type>::null() - ); + AMIMultiplyWeightedOp<Type> cop(AMIPtr_(), true); + AMIPtr_->interpolate(sourceFld, cop, fld, UList<Type>::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 9fd6d217f90eb3e1a949c20e00fbd5fde554cfe4..acde31cfc5115ce3e8f3f4556472f43ba08421ed 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<scalar>(AMI, owner()); + + AMI.interpolate ( - interpolate - ( - nbrPatch.nf() & nbrPatch.coupledFvPatch::delta() - ) + (nbrPatch.nf() & nbrPatch.coupledFvPatch::delta())(), + cop, + nbrDeltas, + UList<scalar>() ); const scalar tol = cyclicACMIPolyPatch::tolerance(); @@ -244,31 +251,35 @@ Foam::tmp<Foam::vectorField> Foam::cyclicACMIFvPatch::delta() const const vectorField patchD(coupledFvPatch::delta()); - vectorField nbrPatchD(interpolate(nbrPatch.coupledFvPatch::delta())); + const auto& AMI = owner() ? this->AMI() : nbrPatch.AMI(); - auto tpdv = tmp<vectorField>::New(patchD.size()); - vectorField& pdv = tpdv.ref(); + // Multiply-weighted op - no low weight correction + auto cop = AMIMultiplyWeightedOp<vector>(AMI, owner()); - // do the transformation if necessary - if (parallel()) - { - forAll(patchD, facei) - { - const vector& ddi = patchD[facei]; - const vector& dni = nbrPatchD[facei]; + vectorField nbrPatchD; + AMI.interpolate + ( + nbrPatch.coupledFvPatch::delta()(), + cop, + nbrPatchD, + UList<vector>() + ); - pdv[facei] = ddi - dni; - } - } - else + // Do the transformation if necessary + if (!parallel()) { - forAll(patchD, facei) - { - const vector& ddi = patchD[facei]; - const vector& dni = nbrPatchD[facei]; + transform(nbrPatchD, forwardT()[0], nbrPatchD); + } - pdv[facei] = ddi - transform(forwardT()[0], dni); - } + auto tpdv = tmp<vectorField>::New(patchD.size()); + vectorField& pdv = tpdv.ref(); + + forAll(patchD, facei) + { + 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 9525a4db0a05a7acc6f34a4355f393b29d695bef..f5eb7f7a502bcf2a55ec79138bdae897437b6bf4 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<Type>() + UList<Type>::null() ); } diff --git a/src/finiteVolume/fvMesh/fvPatches/constraint/cyclicAMI/cyclicAMIFvPatch.C b/src/finiteVolume/fvMesh/fvPatches/constraint/cyclicAMI/cyclicAMIFvPatch.C index 4bb5537ad3ed6a023534771dc132b2a5dbd040c9..4b2129f7926adc7b6019538016895ce8f5590740 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<scalarField> tnbrDeltas; + auto tnbrDeltas = tmp<scalarField>::New(); if (applyLowWeightCorrection()) { - tnbrDeltas = - interpolate - ( - nbrPatch.nf() & nbrPatch.coupledFvPatch::delta(), - scalarField(this->size(), 1.0) - ); + // Use 'assign' correction for geometric interpolation + auto cop = AMICorrectedMultiplyWeightedOp<scalar> + ( + 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<scalar>(AMI, owner()); + + AMI.interpolate + ( + (nbrPatch.nf() & nbrPatch.coupledFvPatch::delta())(), + cop, + tnbrDeltas.ref(), + UList<scalar>::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::vectorField> Foam::cyclicAMIFvPatch::delta() const { const vectorField patchD(coupledFvPatch::delta()); - tmp<vectorField> tnbrPatchD; + const auto& AMI = owner() ? this->AMI() : nbrPatch.AMI(); + + auto tnbrPatchD = tmp<vectorField>::New(); if (applyLowWeightCorrection()) { - tnbrPatchD = - interpolate - ( - nbrPatch.coupledFvPatch::delta(), - vectorField(this->size(), Zero) - ); + // Use 'assign' correction for geometric interpolation + auto cop = AMICorrectedMultiplyWeightedOp<vector> + ( + 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<vector>(AMI, owner()); + + AMI.interpolate + ( + nbrPatch.coupledFvPatch::delta()(), + cop, + tnbrPatchD.ref(), + UList<vector>::null() + ); } - const vectorField& nbrPatchD = tnbrPatchD(); + vectorField& nbrPatchD = tnbrPatchD.ref(); + + // Do the transformation if necessary + if (!parallel()) + { + transform(nbrPatchD, forwardT()[0], nbrPatchD); + } auto tpdv = tmp<vectorField>::New(patchD.size()); vectorField& pdv = tpdv.ref(); - // do the transformation if necessary - if (parallel()) - { - forAll(patchD, facei) - { - const vector& ddi = patchD[facei]; - const vector& dni = nbrPatchD[facei]; - - pdv[facei] = ddi - dni; - } - } - else + forAll(patchD, facei) { - 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 2d4491ca778b993c80e679823c80c144c4e4b6e7..ccd7966a3443518c3642ddf097467be8c265a99c 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<solveScalar> 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 68d19e6c1d7c4a2c43be959dd0fe2b1c8c139cd4..f2030e10bca0ad03346b90dea7c2a82bba21b301 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<solveScalar> 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<solveScalar> 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 a5487c290ab224b8ed3dd18095fc758a395ba3c6..33602a20538637e0ab27fa5fe8283a4cd48dbdb2 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 Type, class TrackingData> + class combineField + : + public AMIFieldOpBase + { + // Private Data + + FaceCellWave<Type, TrackingData>& solver_; + + const cyclicAMIPolyPatch& patch_; + + + public: + + combineField + ( + FaceCellWave<Type, TrackingData>& solver, + const cyclicAMIPolyPatch& patch + ) + : + AMIFieldOpBase(patch.AMI(), patch.owner()), + solver_(solver), + patch_(patch) + {} + + void operator() + ( + List<Type>& result, + const UList<Type>& fld, + const UList<Type>& /* 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<Type, TrackingData>::handleAMICyclicPatches() } // Transfer sendInfo to cycPatch - combine<Type, TrackingData> cmb(*this, cycPatch); + combineField<Type, TrackingData> cmb(*this, cycPatch); if (cycPatch.applyLowWeightCorrection()) { diff --git a/src/meshTools/mappedPatches/mappedPolyPatch/mappedPatchBaseTemplates.C b/src/meshTools/mappedPatches/mappedPolyPatch/mappedPatchBaseTemplates.C index 7b6ce7e3cae6d0e77583969a5408075e734a12f3..26cdff81a2f5943f2aa26f5b462f23f230611c11 100644 --- a/src/meshTools/mappedPatches/mappedPolyPatch/mappedPatchBaseTemplates.C +++ b/src/meshTools/mappedPatches/mappedPolyPatch/mappedPatchBaseTemplates.C @@ -26,6 +26,9 @@ License \*---------------------------------------------------------------------------*/ +#include "AMIFieldOps.H" + + template<class Type> void Foam::mappedPatchBase::distribute(List<Type>& 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<Type>(std::move(lst)), cop); + const auto op = AMIFieldOp<Type, CombineOp>(interp, cop, true); + + lst = interp.interpolate(Field<Type>(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<Type>(std::move(lst)), cop); + const auto op = AMIFieldOp<Type, CombineOp>(interp, false); + + lst = interp.interpolate(Field<Type>(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 e4ec1fd61377358f934e137f7ca02f444ee2a880..da834592ebd135a90ad3565c5d1aca4ba47ffdc3 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<label> cop(cycPp.AMI(), cycPp.owner()); + cop(thisDecomp, nbrDecomp, thisDecomp); forAll(thisDecomp, i) { diff --git a/src/sampling/meshToMesh/meshToMeshTemplates.C b/src/sampling/meshToMesh/meshToMeshTemplates.C index a1df9365556f55401fc965a30bee52778e41cb77..2111de675f4a74b6c4d5d4d1edc533ecd9d7916f 100644 --- a/src/sampling/meshToMesh/meshToMeshTemplates.C +++ b/src/sampling/meshToMesh/meshToMeshTemplates.C @@ -492,13 +492,9 @@ void Foam::meshToMesh::mapAndOpSrcToTgt { tgtField = Type(Zero); - AMI.interpolateToTarget - ( - srcField, - multiplyWeightedOp<Type, CombineOp>(cop), - tgtField, - UList<Type>::null() - ); + const AMIMultiplyWeightedOp<Type, CombineOp> amicop(AMI, false); + + AMI.interpolate(srcField, amicop, tgtField, UList<Type>::null()); } @@ -725,13 +721,9 @@ void Foam::meshToMesh::mapAndOpTgtToSrc { srcField = Type(Zero); - AMI.interpolateToSource - ( - tgtField, - multiplyWeightedOp<Type, CombineOp>(cop), - srcField, - UList<Type>::null() - ); + const AMIMultiplyWeightedOp<Type, CombineOp> amicop(AMI, true); + + AMI.interpolate(tgtField, amicop, srcField, UList<Type>::null()); }