From 1307c4eb2e8061d51b52efa57f89a2106c1edd92 Mon Sep 17 00:00:00 2001
From: Andrew Heather <>
Date: Fri, 3 May 2024 17:26:00 +0100
Subject: [PATCH] ENH: Propagated AMI API code changes across dependant code

---
 .../turbulentDigitalFilterInletFvPatchField.C |  11 +-
 .../constraint/cyclicACMI/cyclicACMIFvPatch.C |  61 ++++++----
 .../constraint/cyclicACMI/cyclicACMIFvPatch.H |   2 +-
 .../constraint/cyclicAMI/cyclicAMIFvPatch.C   | 108 +++++++++++-------
 .../cyclicACMIGAMGInterfaceField.C            |  11 +-
 .../cyclicAMIGAMGInterfaceField.C             |  22 ++--
 .../algorithms/MeshWave/FaceCellWave.C        |  70 +++++++++++-
 .../mappedPatchBaseTemplates.C                |  11 +-
 .../decompositionConstraint.C                 |  40 +------
 src/sampling/meshToMesh/meshToMeshTemplates.C |  20 +---
 10 files changed, 213 insertions(+), 143 deletions(-)

diff --git a/src/finiteVolume/fields/fvPatchFields/derived/turbulentDigitalFilterInlet/turbulentDigitalFilterInletFvPatchField.C b/src/finiteVolume/fields/fvPatchFields/derived/turbulentDigitalFilterInlet/turbulentDigitalFilterInletFvPatchField.C
index f947bfb24f5..904a693ddbe 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 9fd6d217f90..acde31cfc51 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 9525a4db0a0..f5eb7f7a502 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 4bb5537ad3e..4b2129f7926 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 2d4491ca778..ccd7966a344 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 68d19e6c1d7..f2030e10bca 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 a5487c290ab..33602a20538 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 7b6ce7e3cae..26cdff81a2f 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 e4ec1fd6137..da834592ebd 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 a1df9365556..2111de675f4 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());
 }
 
 
-- 
GitLab