From cf8ad3d9364b76e413d4e534fa908b83efd43bc9 Mon Sep 17 00:00:00 2001
From: mattijs <mattijs>
Date: Tue, 15 Nov 2011 10:29:59 +0000
Subject: [PATCH] ENH: cyclicAMI: handle FaceCellWave (e.g. wall distance)

---
 src/OpenFOAM/Make/files                       |   3 -
 .../polyPatches/polyPatch/polyPatch.H         |   2 +-
 .../AMIInterpolation/AMIInterpolation.C       | 188 ++++++----
 .../AMIInterpolation/AMIInterpolation.H       |  29 +-
 .../cyclicAMIPolyPatch/cyclicAMIPolyPatch.H   |   9 +
 .../cyclicAMIPolyPatchTemplates.C             |  19 +
 src/meshTools/Make/files                      |  11 +-
 .../algorithms/MeshWave/FaceCellWave.C        | 334 +++++++++++++-----
 .../algorithms/MeshWave/FaceCellWave.H        |  11 +-
 .../algorithms/MeshWave/FaceCellWaveName.C    |   0
 .../algorithms/MeshWave/MeshWave.C            |   0
 .../algorithms/MeshWave/MeshWave.H            |   0
 .../algorithms/MeshWave/MeshWaveName.C        |   0
 .../PatchEdgeFaceWave/PatchEdgeFaceWave.C     |   0
 .../PatchEdgeFaceWave/PatchEdgeFaceWave.H     |   0
 .../PatchEdgeFaceWave/PatchEdgeFaceWaveName.C |   0
 .../PatchEdgeFaceWave/patchEdgeFaceInfo.C     |   0
 .../PatchEdgeFaceWave/patchEdgeFaceInfo.H     |   0
 .../PatchEdgeFaceWave/patchEdgeFaceInfoI.H    |   0
 .../PointEdgeWave/PointEdgeWave.C             |   0
 .../PointEdgeWave/PointEdgeWave.H             |   0
 .../PointEdgeWave/PointEdgeWaveName.C         |   0
 .../PointEdgeWave/pointEdgePoint.C            |   0
 .../PointEdgeWave/pointEdgePoint.H            |   0
 .../PointEdgeWave/pointEdgePointI.H           |   0
 25 files changed, 440 insertions(+), 166 deletions(-)
 rename src/{OpenFOAM => meshTools}/algorithms/MeshWave/FaceCellWave.C (77%)
 rename src/{OpenFOAM => meshTools}/algorithms/MeshWave/FaceCellWave.H (97%)
 rename src/{OpenFOAM => meshTools}/algorithms/MeshWave/FaceCellWaveName.C (100%)
 rename src/{OpenFOAM => meshTools}/algorithms/MeshWave/MeshWave.C (100%)
 rename src/{OpenFOAM => meshTools}/algorithms/MeshWave/MeshWave.H (100%)
 rename src/{OpenFOAM => meshTools}/algorithms/MeshWave/MeshWaveName.C (100%)
 rename src/meshTools/{ => algorithms}/PatchEdgeFaceWave/PatchEdgeFaceWave.C (100%)
 rename src/meshTools/{ => algorithms}/PatchEdgeFaceWave/PatchEdgeFaceWave.H (100%)
 rename src/meshTools/{ => algorithms}/PatchEdgeFaceWave/PatchEdgeFaceWaveName.C (100%)
 rename src/meshTools/{ => algorithms}/PatchEdgeFaceWave/patchEdgeFaceInfo.C (100%)
 rename src/meshTools/{ => algorithms}/PatchEdgeFaceWave/patchEdgeFaceInfo.H (100%)
 rename src/meshTools/{ => algorithms}/PatchEdgeFaceWave/patchEdgeFaceInfoI.H (100%)
 rename src/meshTools/{ => algorithms}/PointEdgeWave/PointEdgeWave.C (100%)
 rename src/meshTools/{ => algorithms}/PointEdgeWave/PointEdgeWave.H (100%)
 rename src/meshTools/{ => algorithms}/PointEdgeWave/PointEdgeWaveName.C (100%)
 rename src/meshTools/{ => algorithms}/PointEdgeWave/pointEdgePoint.C (100%)
 rename src/meshTools/{ => algorithms}/PointEdgeWave/pointEdgePoint.H (100%)
 rename src/meshTools/{ => algorithms}/PointEdgeWave/pointEdgePointI.H (100%)

diff --git a/src/OpenFOAM/Make/files b/src/OpenFOAM/Make/files
index 6e169d64bc5..da569b2e211 100644
--- a/src/OpenFOAM/Make/files
+++ b/src/OpenFOAM/Make/files
@@ -577,9 +577,6 @@ $(interpolations)/interpolationTable/tableReaders/tableReaders.C
 $(interpolations)/interpolationTable/tableReaders/openFoam/openFoamTableReaders.C
 $(interpolations)/interpolationTable/tableReaders/csv/csvTableReaders.C
 
-algorithms/MeshWave/MeshWaveName.C
-algorithms/MeshWave/FaceCellWaveName.C
-
 algorithms/indexedOctree/indexedOctreeName.C
 algorithms/indexedOctree/treeDataCell.C
 
diff --git a/src/OpenFOAM/meshes/polyMesh/polyPatches/polyPatch/polyPatch.H b/src/OpenFOAM/meshes/polyMesh/polyPatches/polyPatch/polyPatch.H
index 5601c1e993c..0fa859bddba 100644
--- a/src/OpenFOAM/meshes/polyMesh/polyPatches/polyPatch/polyPatch.H
+++ b/src/OpenFOAM/meshes/polyMesh/polyPatches/polyPatch/polyPatch.H
@@ -300,7 +300,7 @@ public:
 
         //- Slice list to patch
         template<class T>
-        const typename List<T>::subList patchSlice(const List<T>& l) const
+        const typename List<T>::subList patchSlice(const UList<T>& l) const
         {
             return typename List<T>::subList(l, this->size(), start_);
         }
diff --git a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolation.C b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolation.C
index a0965ff941f..cae738707d8 100644
--- a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolation.C
+++ b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolation.C
@@ -30,6 +30,37 @@ License
 #include "mergePoints.H"
 #include "mapDistribute.H"
 
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+namespace Foam
+{
+    //- Combine operator for interpolateToSource/Target
+    template<class Type, class BinaryOp>
+    class combineBinaryOp
+    {
+        const BinaryOp& bop_;
+
+        public:
+
+            combineBinaryOp(const BinaryOp& bop)
+            :
+                bop_(bop)
+            {}
+
+            void operator()
+            (
+                Type& x,
+                const label faceI,
+                const Type& y,
+                const scalar weight
+            ) const
+            {
+                x = bop_(x, weight*y);
+            }
+    };
+}
+
+
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
 template<class SourcePatch, class TargetPatch>
@@ -1773,12 +1804,69 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::update
 
 
 template<class SourcePatch, class TargetPatch>
-template<class Type, class BinaryOp>
-Foam::tmp<Foam::Field<Type> >
-Foam::AMIInterpolation<SourcePatch, TargetPatch>::interpolateToSource
+template<class Type, class CombineOp>
+void Foam::AMIInterpolation<SourcePatch, TargetPatch>::interpolateToTarget
 (
-    const Field<Type>& fld,
-    const BinaryOp& bop
+    const UList<Type>& fld,
+    const CombineOp& bop,
+    List<Type>& result
+) const
+{
+    if (fld.size() != srcAddress_.size())
+    {
+        FatalErrorIn
+        (
+            "AMIInterpolation::interpolateToTarget(const Field<Type>&) const"
+        )   << "Supplied field size is not equal to source patch size" << nl
+            << "    source patch   = " << srcAddress_.size() << nl
+            << "    target patch   = " << tgtAddress_.size() << nl
+            << "    supplied field = " << fld.size()
+            << abort(FatalError);
+    }
+
+    result.setSize(tgtAddress_.size());
+
+    if (singlePatchProc_ == -1)
+    {
+        const mapDistribute& map = srcMapPtr_();
+
+        List<Type> work(fld);
+        map.distribute(work);
+
+        forAll(result, faceI)
+        {
+            const labelList& faces = tgtAddress_[faceI];
+            const scalarList& weights = tgtWeights_[faceI];
+
+            forAll(faces, i)
+            {
+                bop(result[faceI], faceI, work[faces[i]], weights[i]);
+            }
+        }
+    }
+    else
+    {
+        forAll(result, faceI)
+        {
+            const labelList& faces = tgtAddress_[faceI];
+            const scalarList& weights = tgtWeights_[faceI];
+
+            forAll(faces, i)
+            {
+                bop(result[faceI], faceI, fld[faces[i]], weights[i]);
+            }
+        }
+    }
+}
+
+
+template<class SourcePatch, class TargetPatch>
+template<class Type, class CombineOp>
+void Foam::AMIInterpolation<SourcePatch, TargetPatch>::interpolateToSource
+(
+    const UList<Type>& fld,
+    const CombineOp& bop,
+    List<Type>& result
 ) const
 {
     if (fld.size() != tgtAddress_.size())
@@ -1793,22 +1881,13 @@ Foam::AMIInterpolation<SourcePatch, TargetPatch>::interpolateToSource
             << abort(FatalError);
     }
 
-    tmp<Field<Type> > tresult
-    (
-        new Field<Type>
-        (
-            srcAddress_.size(),
-            pTraits<Type>::zero
-        )
-    );
-
-    Field<Type>& result = tresult();
+    result.setSize(srcAddress_.size());
 
     if (singlePatchProc_ == -1)
     {
         const mapDistribute& map = tgtMapPtr_();
 
-        Field<Type> work(fld);
+        List<Type> work(fld);
         map.distribute(work);
 
         forAll(result, faceI)
@@ -1818,7 +1897,7 @@ Foam::AMIInterpolation<SourcePatch, TargetPatch>::interpolateToSource
 
             forAll(faces, i)
             {
-                result[faceI] = bop(result[faceI], work[faces[i]]*weights[i]);
+                bop(result[faceI], faceI, work[faces[i]], weights[i]);
             }
         }
     }
@@ -1831,10 +1910,32 @@ Foam::AMIInterpolation<SourcePatch, TargetPatch>::interpolateToSource
 
             forAll(faces, i)
             {
-                result[faceI] = bop(result[faceI], fld[faces[i]]*weights[i]);
+                bop(result[faceI], faceI, fld[faces[i]], weights[i]);
             }
         }
     }
+}
+
+
+template<class SourcePatch, class TargetPatch>
+template<class Type, class BinaryOp>
+Foam::tmp<Foam::Field<Type> >
+Foam::AMIInterpolation<SourcePatch, TargetPatch>::interpolateToSource
+(
+    const Field<Type>& fld,
+    const BinaryOp& bop
+) const
+{
+    tmp<Field<Type> > tresult
+    (
+        new Field<Type>
+        (
+            srcAddress_.size(),
+            pTraits<Type>::zero
+        )
+    );
+
+    interpolateToSource(fld, combineBinaryOp<Type, BinaryOp>(bop), tresult());
 
     return tresult;
 }
@@ -1849,11 +1950,10 @@ Foam::AMIInterpolation<SourcePatch, TargetPatch>::interpolateToSource
     const BinaryOp& bop
 ) const
 {
-    return interpolateToSource(tFld(), bop);
+    return interpolateToSource(tFld, bop);
 }
 
 
-
 template<class SourcePatch, class TargetPatch>
 template<class Type, class BinaryOp>
 Foam::tmp<Foam::Field<Type> >
@@ -1863,18 +1963,6 @@ Foam::AMIInterpolation<SourcePatch, TargetPatch>::interpolateToTarget
     const BinaryOp& bop
 ) const
 {
-    if (fld.size() != srcAddress_.size())
-    {
-        FatalErrorIn
-        (
-            "AMIInterpolation::interpolateToTarget(const Field<Type>&) const"
-        )   << "Supplied field size is not equal to source patch size" << nl
-            << "    source patch   = " << srcAddress_.size() << nl
-            << "    target patch   = " << tgtAddress_.size() << nl
-            << "    supplied field = " << fld.size()
-            << abort(FatalError);
-    }
-
     tmp<Field<Type> > tresult
     (
         new Field<Type>
@@ -1884,39 +1972,7 @@ Foam::AMIInterpolation<SourcePatch, TargetPatch>::interpolateToTarget
         )
     );
 
-    Field<Type>& result = tresult();
-
-    if (singlePatchProc_ == -1)
-    {
-        const mapDistribute& map = srcMapPtr_();
-
-        Field<Type> work(fld);
-        map.distribute(work);
-
-        forAll(result, faceI)
-        {
-            const labelList& faces = tgtAddress_[faceI];
-            const scalarList& weights = tgtWeights_[faceI];
-
-            forAll(faces, i)
-            {
-                result[faceI] = bop(result[faceI], work[faces[i]]*weights[i]);
-            }
-        }
-    }
-    else
-    {
-        forAll(result, faceI)
-        {
-            const labelList& faces = tgtAddress_[faceI];
-            const scalarList& weights = tgtWeights_[faceI];
-
-            forAll(faces, i)
-            {
-                result[faceI] = bop(result[faceI], fld[faces[i]]*weights[i]);
-            }
-        }
-    }
+    interpolateToTarget(fld, combineBinaryOp<Type, BinaryOp>(bop), tresult());
 
     return tresult;
 }
@@ -1931,7 +1987,7 @@ Foam::AMIInterpolation<SourcePatch, TargetPatch>::interpolateToTarget
     const BinaryOp& bop
 ) const
 {
-    return interpolateToTarget(tFld(), bop);
+    return interpolateToTarget(tFld, bop);
 }
 
 
diff --git a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolation.H b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolation.H
index e43180db6fc..c9aa12da905 100644
--- a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolation.H
+++ b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolation.H
@@ -404,7 +404,30 @@ public:
 
         // Evaluation
 
-            //- Interpolate from target to source with supplied op
+            // Low-level
+
+                //- Interpolate from target to source with supplied op
+                //  to combine existing value with remote value and weight
+                template<class Type, class CombineOp>
+                void interpolateToSource
+                (
+                    const UList<Type>& fld,
+                    const CombineOp& bop,
+                    List<Type>& result
+                ) const;
+
+                //- Interpolate from source to target with supplied op
+                //  to combine existing value with remote value and weight
+                template<class Type, class CombineOp>
+                void interpolateToTarget
+                (
+                    const UList<Type>& fld,
+                    const CombineOp& bop,
+                    List<Type>& result
+                ) const;
+
+
+            //- Interpolate from target to source with supplied binary op
             template<class Type, class BinaryOp>
             tmp<Field<Type> > interpolateToSource
             (
@@ -412,7 +435,8 @@ public:
                 const BinaryOp& bop
             ) const;
 
-            //- Interpolate from target tmp field to source with supplied op
+            //- Interpolate from target tmp field to source with supplied
+            //  binary op
             template<class Type, class BinaryOp>
             tmp<Field<Type> > interpolateToSource
             (
@@ -464,7 +488,6 @@ public:
                 const tmp<Field<Type> >& tFld
             ) const;
 
-
         // Checks
 
             //- Write face connectivity as OBJ file
diff --git a/src/meshTools/AMIInterpolation/patches/cyclic/cyclicAMIPolyPatch/cyclicAMIPolyPatch.H b/src/meshTools/AMIInterpolation/patches/cyclic/cyclicAMIPolyPatch/cyclicAMIPolyPatch.H
index 9ced39571a2..dcd26799c0e 100644
--- a/src/meshTools/AMIInterpolation/patches/cyclic/cyclicAMIPolyPatch/cyclicAMIPolyPatch.H
+++ b/src/meshTools/AMIInterpolation/patches/cyclic/cyclicAMIPolyPatch/cyclicAMIPolyPatch.H
@@ -318,6 +318,15 @@ public:
                     const tmp<Field<Type> >& tFld
                 ) const;
 
+                //- Low-level interpolate List
+                template<class Type, class BinaryOp>
+                void interpolate
+                (
+                    const UList<Type>& fld,
+                    const BinaryOp& bop,
+                    List<Type>& result
+                ) const;
+
 
         //- Calculate the patch geometry
         virtual void calcGeometry
diff --git a/src/meshTools/AMIInterpolation/patches/cyclic/cyclicAMIPolyPatch/cyclicAMIPolyPatchTemplates.C b/src/meshTools/AMIInterpolation/patches/cyclic/cyclicAMIPolyPatch/cyclicAMIPolyPatchTemplates.C
index ccafd75fd40..4bf59fba416 100644
--- a/src/meshTools/AMIInterpolation/patches/cyclic/cyclicAMIPolyPatch/cyclicAMIPolyPatchTemplates.C
+++ b/src/meshTools/AMIInterpolation/patches/cyclic/cyclicAMIPolyPatch/cyclicAMIPolyPatchTemplates.C
@@ -59,4 +59,23 @@ Foam::tmp<Foam::Field<Type> > Foam::cyclicAMIPolyPatch::interpolate
 }
 
 
+template<class Type, class BinaryOp>
+void Foam::cyclicAMIPolyPatch::interpolate
+(
+    const UList<Type>& fld,
+    const BinaryOp& bop,
+    List<Type>& result
+) const
+{
+    if (owner())
+    {
+        AMIPtr_->interpolateToSource(fld, bop, result);
+    }
+    else
+    {
+        neighbPatch().AMIPtr_->interpolateToTarget(fld, bop, result);
+    }
+}
+
+
 // ************************************************************************* //
diff --git a/src/meshTools/Make/files b/src/meshTools/Make/files
index 4ba28fce083..e1c98549023 100644
--- a/src/meshTools/Make/files
+++ b/src/meshTools/Make/files
@@ -30,14 +30,21 @@ meshSearch/meshSearch.C
 
 meshTools/meshTools.C
 
-pWave = PointEdgeWave
+algorithms = algorithms
+
+pWave = $(algorithms)/PointEdgeWave
 $(pWave)/PointEdgeWaveName.C
 $(pWave)/pointEdgePoint.C
 
-patchWave = PatchEdgeFaceWave
+patchWave = $(algorithms)/PatchEdgeFaceWave
 $(patchWave)/PatchEdgeFaceWaveName.C
 $(patchWave)/patchEdgeFaceInfo.C
 
+meshWave = $(algorithms)/MeshWave
+$(meshWave)/MeshWaveName.C
+$(meshWave)/FaceCellWaveName.C
+
+
 regionSplit/regionSplit.C
 
 indexedOctree/treeDataEdge.C
diff --git a/src/OpenFOAM/algorithms/MeshWave/FaceCellWave.C b/src/meshTools/algorithms/MeshWave/FaceCellWave.C
similarity index 77%
rename from src/OpenFOAM/algorithms/MeshWave/FaceCellWave.C
rename to src/meshTools/algorithms/MeshWave/FaceCellWave.C
index 5b111373293..c0e1e72ee8a 100644
--- a/src/OpenFOAM/algorithms/MeshWave/FaceCellWave.C
+++ b/src/meshTools/algorithms/MeshWave/FaceCellWave.C
@@ -27,11 +27,14 @@ License
 #include "polyMesh.H"
 #include "processorPolyPatch.H"
 #include "cyclicPolyPatch.H"
+#include "cyclicAMIPolyPatch.H"
 #include "OPstream.H"
 #include "IPstream.H"
 #include "PstreamReduceOps.H"
 #include "debug.H"
 #include "typeInfo.H"
+#include "SubField.H"
+#include "globalMeshData.H"
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
@@ -44,6 +47,53 @@ Foam::scalar Foam::FaceCellWave<Type, TrackingData>::propagationTol_ = 0.01;
 template <class Type, class TrackingData>
 Foam::label Foam::FaceCellWave<Type, TrackingData>::dummyTrackData_ = 12345;
 
+namespace Foam
+{
+    //- Combine operator for AMIInterpolation
+    template<class Type, class TrackingData>
+    class combine
+    {
+        FaceCellWave<Type, TrackingData>& solver_;
+
+        const polyPatch& patch_;
+
+        public:
+
+            combine
+            (
+                FaceCellWave<Type, TrackingData>& solver,
+                const polyPatch& patch
+            )
+            :
+                solver_(solver),
+                patch_(patch)
+            {}
+
+
+            void operator()
+            (
+                Type& x,
+                const label faceI,
+                const Type& y,
+                const scalar weight
+            ) const
+            {
+                if (y.valid(solver_.data()))
+                {
+                    x.updateFace
+                    (
+                        solver_.mesh(),
+                        patch_.start() + faceI,
+                        y,
+                        solver_.propagationTol(),
+                        solver_.data()
+                    );
+                }
+            }
+    };
+}
+
+
 
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
@@ -244,11 +294,12 @@ void Foam::FaceCellWave<Type, TrackingData>::checkCyclic
 
 // Check if has cyclic patches
 template <class Type, class TrackingData>
-bool Foam::FaceCellWave<Type, TrackingData>::hasCyclicPatch() const
+template <class PatchType>
+bool Foam::FaceCellWave<Type, TrackingData>::hasPatch() const
 {
     forAll(mesh_.boundaryMesh(), patchI)
     {
-        if (isA<cyclicPolyPatch>(mesh_.boundaryMesh()[patchI]))
+        if (isA<PatchType>(mesh_.boundaryMesh()[patchI]))
         {
             return true;
         }
@@ -446,119 +497,117 @@ void Foam::FaceCellWave<Type, TrackingData>::offset
 template <class Type, class TrackingData>
 void Foam::FaceCellWave<Type, TrackingData>::handleProcPatches()
 {
+    const globalMeshData& pData = mesh_.globalData();
+
+    // Which patches are processor patches
+    const labelList& procPatches = pData.processorPatches();
+
     // Send all
 
     PstreamBuffers pBufs(Pstream::nonBlocking);
 
-    forAll(mesh_.boundaryMesh(), patchI)
+    forAll(procPatches, i)
     {
-        const polyPatch& patch = mesh_.boundaryMesh()[patchI];
+        label patchI = procPatches[i];
 
-        if (isA<processorPolyPatch>(patch))
-        {
-            // Allocate buffers
-            label nSendFaces;
-            labelList sendFaces(patch.size());
-            List<Type> sendFacesInfo(patch.size());
+        const processorPolyPatch& procPatch =
+            refCast<const processorPolyPatch>(mesh_.boundaryMesh()[patchI]);
 
-            // Determine which faces changed on current patch
-            nSendFaces = getChangedPatchFaces
-            (
-                patch,
-                0,
-                patch.size(),
-                sendFaces,
-                sendFacesInfo
-            );
+        // Allocate buffers
+        label nSendFaces;
+        labelList sendFaces(procPatch.size());
+        List<Type> sendFacesInfo(procPatch.size());
 
-            // Adapt wallInfo for leaving domain
-            leaveDomain
-            (
-                patch,
-                nSendFaces,
-                sendFaces,
-                sendFacesInfo
-            );
-
-            const processorPolyPatch& procPatch =
-                refCast<const processorPolyPatch>(patch);
-
-            if (debug)
-            {
-                Pout<< " Processor patch " << patchI << ' ' << patch.name()
-                    << " communicating with " << procPatch.neighbProcNo()
-                    << "  Sending:" << nSendFaces
-                    << endl;
-            }
+        // Determine which faces changed on current patch
+        nSendFaces = getChangedPatchFaces
+        (
+            procPatch,
+            0,
+            procPatch.size(),
+            sendFaces,
+            sendFacesInfo
+        );
 
-            UOPstream toNeighbour(procPatch.neighbProcNo(), pBufs);
-            //writeFaces(nSendFaces, sendFaces, sendFacesInfo, toNeighbour);
-            toNeighbour
-                << SubList<label>(sendFaces, nSendFaces)
-                << SubList<Type>(sendFacesInfo, nSendFaces);
+        // Adapt wallInfo for leaving domain
+        leaveDomain
+        (
+            procPatch,
+            nSendFaces,
+            sendFaces,
+            sendFacesInfo
+        );
 
+        if (debug)
+        {
+            Pout<< " Processor patch " << patchI << ' ' << procPatch.name()
+                << " communicating with " << procPatch.neighbProcNo()
+                << "  Sending:" << nSendFaces
+                << endl;
         }
+
+        UOPstream toNeighbour(procPatch.neighbProcNo(), pBufs);
+        //writeFaces(nSendFaces, sendFaces, sendFacesInfo, toNeighbour);
+        toNeighbour
+            << SubList<label>(sendFaces, nSendFaces)
+            << SubList<Type>(sendFacesInfo, nSendFaces);
     }
 
     pBufs.finishedSends();
 
     // Receive all
 
-    forAll(mesh_.boundaryMesh(), patchI)
+    forAll(procPatches, i)
     {
-        const polyPatch& patch = mesh_.boundaryMesh()[patchI];
+        label patchI = procPatches[i];
 
-        if (isA<processorPolyPatch>(patch))
-        {
-            const processorPolyPatch& procPatch =
-                refCast<const processorPolyPatch>(patch);
-
-            // Allocate buffers
-            labelList receiveFaces;
-            List<Type> receiveFacesInfo;
+        const processorPolyPatch& procPatch =
+            refCast<const processorPolyPatch>(mesh_.boundaryMesh()[patchI]);
 
-            {
-                UIPstream fromNeighbour(procPatch.neighbProcNo(), pBufs);
-                fromNeighbour >> receiveFaces >> receiveFacesInfo;
-            }
+        // Allocate buffers
+        labelList receiveFaces;
+        List<Type> receiveFacesInfo;
 
-            if (debug)
-            {
-                Pout<< " Processor patch " << patchI << ' ' << patch.name()
-                    << " communicating with " << procPatch.neighbProcNo()
-                    << "  Receiving:" << receiveFaces.size()
-                    << endl;
-            }
-
-            // Apply transform to received data for non-parallel planes
-            if (!procPatch.parallel())
-            {
-                transform
-                (
-                    procPatch.forwardT(),
-                    receiveFaces.size(),
-                    receiveFacesInfo
-                );
-            }
+        {
+            UIPstream fromNeighbour(procPatch.neighbProcNo(), pBufs);
+            fromNeighbour >> receiveFaces >> receiveFacesInfo;
+        }
 
-            // Adapt wallInfo for entering domain
-            enterDomain
-            (
-                patch,
-                receiveFaces.size(),
-                receiveFaces,
-                receiveFacesInfo
-            );
+        if (debug)
+        {
+            Pout<< " Processor patch " << patchI << ' ' << procPatch.name()
+                << " communicating with " << procPatch.neighbProcNo()
+                << "  Receiving:" << receiveFaces.size()
+                << endl;
+        }
 
-            // Merge received info
-            mergeFaceInfo
+        // Apply transform to received data for non-parallel planes
+        if (!procPatch.parallel())
+        {
+            transform
             (
-                patch,
+                procPatch.forwardT(),
                 receiveFaces.size(),
-                receiveFaces,
                 receiveFacesInfo
             );
         }
+
+        // Adapt wallInfo for entering domain
+        enterDomain
+        (
+            procPatch,
+            receiveFaces.size(),
+            receiveFaces,
+            receiveFacesInfo
+        );
+
+        // Merge received info
+        mergeFaceInfo
+        (
+            procPatch,
+            receiveFaces.size(),
+            receiveFaces,
+            receiveFacesInfo
+        );
     }
 }
 
@@ -648,6 +697,93 @@ void Foam::FaceCellWave<Type, TrackingData>::handleCyclicPatches()
 }
 
 
+// Transfer information across cyclic halves.
+template <class Type, class TrackingData>
+void Foam::FaceCellWave<Type, TrackingData>::handleAMICyclicPatches()
+{
+    forAll(mesh_.boundaryMesh(), patchI)
+    {
+        const polyPatch& patch = mesh_.boundaryMesh()[patchI];
+
+        if (isA<cyclicAMIPolyPatch>(patch))
+        {
+            const cyclicAMIPolyPatch& cycPatch =
+                refCast<const cyclicAMIPolyPatch>(patch);
+
+            List<Type> receiveInfo;
+
+            {
+                const cyclicAMIPolyPatch& nbrPatch =
+                    refCast<const cyclicAMIPolyPatch>(patch).neighbPatch();
+
+                // Get nbrPatch data (so not just changed faces)
+                typename List<Type>::subList sendInfo
+                (
+                    nbrPatch.patchSlice
+                    (
+                        allFaceInfo_
+                    )
+                );
+
+                // Adapt sendInfo for leaving domain
+                const vectorField::subField fc = nbrPatch.faceCentres();
+                forAll(sendInfo, i)
+                {
+                    sendInfo[i].leaveDomain(mesh_, nbrPatch, i, fc[i], td_);
+                }
+
+
+                // Transfer sendInfo to cycPatch
+                combine<Type, TrackingData> cmb(*this, cycPatch);
+
+                cycPatch.interpolate(sendInfo, cmb, receiveInfo);
+            }
+
+            // Apply transform to received data for non-parallel planes
+            if (!cycPatch.parallel())
+            {
+                transform
+                (
+                    cycPatch.forwardT(),
+                    receiveInfo.size(),
+                    receiveInfo
+                );
+            }
+
+            // Adapt receiveInfo for entering domain
+            const vectorField::subField fc = cycPatch.faceCentres();
+            forAll(receiveInfo, i)
+            {
+                receiveInfo[i].enterDomain(mesh_, cycPatch, i, fc[i], td_);
+            }
+
+            // Merge into global storage
+            forAll(receiveInfo, i)
+            {
+                label meshFaceI = cycPatch.start()+i;
+
+                Type& currentWallInfo = allFaceInfo_[meshFaceI];
+
+                if
+                (
+                    receiveInfo[i].valid(td_)
+                && !currentWallInfo.equal(receiveInfo[i], td_)
+                )
+                {
+                    updateFace
+                    (
+                        meshFaceI,
+                        receiveInfo[i],
+                        propagationTol_,
+                        currentWallInfo
+                    );
+                }
+            }
+        }
+    }
+}
+
+
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
 // Set up only. Use setFaceInfo and iterate() to do actual calculation.
@@ -670,7 +806,11 @@ Foam::FaceCellWave<Type, TrackingData>::FaceCellWave
     changedCell_(mesh_.nCells(), false),
     changedCells_(mesh_.nCells()),
     nChangedCells_(0),
-    hasCyclicPatches_(hasCyclicPatch()),
+    hasCyclicPatches_(hasPatch<cyclicPolyPatch>()),
+    hasCyclicAMIPatches_
+    (
+        returnReduce(hasPatch<cyclicAMIPolyPatch>(), orOp<bool>())
+    ),
     nEvals_(0),
     nUnvisitedCells_(mesh_.nCells()),
     nUnvisitedFaces_(mesh_.nFaces())
@@ -701,7 +841,11 @@ Foam::FaceCellWave<Type, TrackingData>::FaceCellWave
     changedCell_(mesh_.nCells(), false),
     changedCells_(mesh_.nCells()),
     nChangedCells_(0),
-    hasCyclicPatches_(hasCyclicPatch()),
+    hasCyclicPatches_(hasPatch<cyclicPolyPatch>()),
+    hasCyclicAMIPatches_
+    (
+        returnReduce(hasPatch<cyclicAMIPolyPatch>(), orOp<bool>())
+    ),
     nEvals_(0),
     nUnvisitedCells_(mesh_.nCells()),
     nUnvisitedFaces_(mesh_.nFaces())
@@ -888,6 +1032,12 @@ Foam::label Foam::FaceCellWave<Type, TrackingData>::cellToFace()
         // Transfer changed faces across cyclic halves
         handleCyclicPatches();
     }
+
+    if (hasCyclicAMIPatches_)
+    {
+        handleAMICyclicPatches();
+    }
+
     if (Pstream::parRun())
     {
         // Transfer changed faces from neighbouring processors.
@@ -917,6 +1067,12 @@ Foam::label Foam::FaceCellWave<Type, TrackingData>::iterate(const label maxIter)
         // Transfer changed faces across cyclic halves
         handleCyclicPatches();
     }
+
+    if (hasCyclicAMIPatches_)
+    {
+        handleAMICyclicPatches();
+    }
+
     if (Pstream::parRun())
     {
         // Transfer changed faces from neighbouring processors.
diff --git a/src/OpenFOAM/algorithms/MeshWave/FaceCellWave.H b/src/meshTools/algorithms/MeshWave/FaceCellWave.H
similarity index 97%
rename from src/OpenFOAM/algorithms/MeshWave/FaceCellWave.H
rename to src/meshTools/algorithms/MeshWave/FaceCellWave.H
index a17dc1652ce..6b58fad24bd 100644
--- a/src/OpenFOAM/algorithms/MeshWave/FaceCellWave.H
+++ b/src/meshTools/algorithms/MeshWave/FaceCellWave.H
@@ -105,7 +105,10 @@ class FaceCellWave
         label nChangedCells_;
 
         //- Contains cyclics
-        bool hasCyclicPatches_;
+        const bool hasCyclicPatches_;
+
+        //- Contains cyclicAMI
+        const bool hasCyclicAMIPatches_;
 
         //- Number of evaluations
         label nEvals_;
@@ -163,7 +166,8 @@ class FaceCellWave
             void checkCyclic(const polyPatch& pPatch) const;
 
             //- Has cyclic patch?
-            bool hasCyclicPatch() const;
+            template <class PatchType>
+            bool hasPatch() const;
 
             //- Merge received patch data into global data
             void mergeFaceInfo
@@ -225,6 +229,9 @@ class FaceCellWave
             //- Merge data from across cyclics
             void handleCyclicPatches();
 
+            //- Merge data from across AMI cyclics
+            void handleAMICyclicPatches();
+
 
       // Private static data
 
diff --git a/src/OpenFOAM/algorithms/MeshWave/FaceCellWaveName.C b/src/meshTools/algorithms/MeshWave/FaceCellWaveName.C
similarity index 100%
rename from src/OpenFOAM/algorithms/MeshWave/FaceCellWaveName.C
rename to src/meshTools/algorithms/MeshWave/FaceCellWaveName.C
diff --git a/src/OpenFOAM/algorithms/MeshWave/MeshWave.C b/src/meshTools/algorithms/MeshWave/MeshWave.C
similarity index 100%
rename from src/OpenFOAM/algorithms/MeshWave/MeshWave.C
rename to src/meshTools/algorithms/MeshWave/MeshWave.C
diff --git a/src/OpenFOAM/algorithms/MeshWave/MeshWave.H b/src/meshTools/algorithms/MeshWave/MeshWave.H
similarity index 100%
rename from src/OpenFOAM/algorithms/MeshWave/MeshWave.H
rename to src/meshTools/algorithms/MeshWave/MeshWave.H
diff --git a/src/OpenFOAM/algorithms/MeshWave/MeshWaveName.C b/src/meshTools/algorithms/MeshWave/MeshWaveName.C
similarity index 100%
rename from src/OpenFOAM/algorithms/MeshWave/MeshWaveName.C
rename to src/meshTools/algorithms/MeshWave/MeshWaveName.C
diff --git a/src/meshTools/PatchEdgeFaceWave/PatchEdgeFaceWave.C b/src/meshTools/algorithms/PatchEdgeFaceWave/PatchEdgeFaceWave.C
similarity index 100%
rename from src/meshTools/PatchEdgeFaceWave/PatchEdgeFaceWave.C
rename to src/meshTools/algorithms/PatchEdgeFaceWave/PatchEdgeFaceWave.C
diff --git a/src/meshTools/PatchEdgeFaceWave/PatchEdgeFaceWave.H b/src/meshTools/algorithms/PatchEdgeFaceWave/PatchEdgeFaceWave.H
similarity index 100%
rename from src/meshTools/PatchEdgeFaceWave/PatchEdgeFaceWave.H
rename to src/meshTools/algorithms/PatchEdgeFaceWave/PatchEdgeFaceWave.H
diff --git a/src/meshTools/PatchEdgeFaceWave/PatchEdgeFaceWaveName.C b/src/meshTools/algorithms/PatchEdgeFaceWave/PatchEdgeFaceWaveName.C
similarity index 100%
rename from src/meshTools/PatchEdgeFaceWave/PatchEdgeFaceWaveName.C
rename to src/meshTools/algorithms/PatchEdgeFaceWave/PatchEdgeFaceWaveName.C
diff --git a/src/meshTools/PatchEdgeFaceWave/patchEdgeFaceInfo.C b/src/meshTools/algorithms/PatchEdgeFaceWave/patchEdgeFaceInfo.C
similarity index 100%
rename from src/meshTools/PatchEdgeFaceWave/patchEdgeFaceInfo.C
rename to src/meshTools/algorithms/PatchEdgeFaceWave/patchEdgeFaceInfo.C
diff --git a/src/meshTools/PatchEdgeFaceWave/patchEdgeFaceInfo.H b/src/meshTools/algorithms/PatchEdgeFaceWave/patchEdgeFaceInfo.H
similarity index 100%
rename from src/meshTools/PatchEdgeFaceWave/patchEdgeFaceInfo.H
rename to src/meshTools/algorithms/PatchEdgeFaceWave/patchEdgeFaceInfo.H
diff --git a/src/meshTools/PatchEdgeFaceWave/patchEdgeFaceInfoI.H b/src/meshTools/algorithms/PatchEdgeFaceWave/patchEdgeFaceInfoI.H
similarity index 100%
rename from src/meshTools/PatchEdgeFaceWave/patchEdgeFaceInfoI.H
rename to src/meshTools/algorithms/PatchEdgeFaceWave/patchEdgeFaceInfoI.H
diff --git a/src/meshTools/PointEdgeWave/PointEdgeWave.C b/src/meshTools/algorithms/PointEdgeWave/PointEdgeWave.C
similarity index 100%
rename from src/meshTools/PointEdgeWave/PointEdgeWave.C
rename to src/meshTools/algorithms/PointEdgeWave/PointEdgeWave.C
diff --git a/src/meshTools/PointEdgeWave/PointEdgeWave.H b/src/meshTools/algorithms/PointEdgeWave/PointEdgeWave.H
similarity index 100%
rename from src/meshTools/PointEdgeWave/PointEdgeWave.H
rename to src/meshTools/algorithms/PointEdgeWave/PointEdgeWave.H
diff --git a/src/meshTools/PointEdgeWave/PointEdgeWaveName.C b/src/meshTools/algorithms/PointEdgeWave/PointEdgeWaveName.C
similarity index 100%
rename from src/meshTools/PointEdgeWave/PointEdgeWaveName.C
rename to src/meshTools/algorithms/PointEdgeWave/PointEdgeWaveName.C
diff --git a/src/meshTools/PointEdgeWave/pointEdgePoint.C b/src/meshTools/algorithms/PointEdgeWave/pointEdgePoint.C
similarity index 100%
rename from src/meshTools/PointEdgeWave/pointEdgePoint.C
rename to src/meshTools/algorithms/PointEdgeWave/pointEdgePoint.C
diff --git a/src/meshTools/PointEdgeWave/pointEdgePoint.H b/src/meshTools/algorithms/PointEdgeWave/pointEdgePoint.H
similarity index 100%
rename from src/meshTools/PointEdgeWave/pointEdgePoint.H
rename to src/meshTools/algorithms/PointEdgeWave/pointEdgePoint.H
diff --git a/src/meshTools/PointEdgeWave/pointEdgePointI.H b/src/meshTools/algorithms/PointEdgeWave/pointEdgePointI.H
similarity index 100%
rename from src/meshTools/PointEdgeWave/pointEdgePointI.H
rename to src/meshTools/algorithms/PointEdgeWave/pointEdgePointI.H
-- 
GitLab