diff --git a/etc/codeTemplates/dynamicCode/codeStreamTemplate.C b/etc/codeTemplates/dynamicCode/codeStreamTemplate.C
index 3288b7cefb0f43ac11581339152e68070c22728e..5d69d9963294eebbced2b28a454b477698e3e3d1 100644
--- a/etc/codeTemplates/dynamicCode/codeStreamTemplate.C
+++ b/etc/codeTemplates/dynamicCode/codeStreamTemplate.C
@@ -29,6 +29,7 @@ Description
 #include "dictionary.H"
 #include "Ostream.H"
 #include "Pstream.H"
+#include "unitConversion.H"
 
 //{{{ begin codeInclude
 ${codeInclude}
diff --git a/etc/codeTemplates/dynamicCode/fixedValueFvPatchFieldTemplate.C b/etc/codeTemplates/dynamicCode/fixedValueFvPatchFieldTemplate.C
index a8b6a6da67beb930f1f330757cdedb10dcdf9d6a..c7f442f03a64c9a4fa4bd919b91a061c2de547ec 100644
--- a/etc/codeTemplates/dynamicCode/fixedValueFvPatchFieldTemplate.C
+++ b/etc/codeTemplates/dynamicCode/fixedValueFvPatchFieldTemplate.C
@@ -28,6 +28,7 @@ License
 #include "fvPatchFieldMapper.H"
 #include "volFields.H"
 #include "surfaceFields.H"
+#include "unitConversion.H"
 //{{{ begin codeInclude
 ${codeInclude}
 //}}} end codeInclude
diff --git a/etc/codeTemplates/dynamicCode/functionObjectTemplate.C b/etc/codeTemplates/dynamicCode/functionObjectTemplate.C
index 61cba180c3cccfb08645c5410cfd30b43bbfa43f..a747b528b6f8dcc3c4247bd917bf9fba1ed3ecc8 100644
--- a/etc/codeTemplates/dynamicCode/functionObjectTemplate.C
+++ b/etc/codeTemplates/dynamicCode/functionObjectTemplate.C
@@ -26,6 +26,7 @@ License
 #include "functionObjectTemplate.H"
 #include "Time.H"
 #include "fvCFD.H"
+#include "unitConversion.H"
 
 //{{{ begin codeInclude
 ${codeInclude}
diff --git a/src/OpenFOAM/Make/files b/src/OpenFOAM/Make/files
index 6e169d64bc54fef0fde90118cdb6ab2b2405bd4f..da569b2e2113f39cd7b1c4401847cc2938f3e715 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/pointMesh/pointPatches/derived/coupled/coupledFacePointPatch.H b/src/OpenFOAM/meshes/pointMesh/pointPatches/derived/coupled/coupledFacePointPatch.H
index 368782d0a3757f5ff596598c465c35b2044f81a7..91db5fc8737eb65a1cb84228b9b55a6981bd4e07 100644
--- a/src/OpenFOAM/meshes/pointMesh/pointPatches/derived/coupled/coupledFacePointPatch.H
+++ b/src/OpenFOAM/meshes/pointMesh/pointPatches/derived/coupled/coupledFacePointPatch.H
@@ -96,18 +96,6 @@ public:
 
     //- Destructor
     virtual ~coupledFacePointPatch();
-
-
-    // Member Functions
-
-        // Access
-
-            //- Return true because this patch is coupled
-            virtual bool coupled() const
-            {
-                return true;
-            }
-
 };
 
 
diff --git a/src/OpenFOAM/meshes/polyMesh/polyPatches/polyPatch/polyPatch.H b/src/OpenFOAM/meshes/polyMesh/polyPatches/polyPatch/polyPatch.H
index ceb622058526255b8885b0472d5f879ef4f535c7..0fa859bddbaf6da4dd63784e917103a02f40462d 100644
--- a/src/OpenFOAM/meshes/polyMesh/polyPatches/polyPatch/polyPatch.H
+++ b/src/OpenFOAM/meshes/polyMesh/polyPatches/polyPatch/polyPatch.H
@@ -285,7 +285,8 @@ public:
         //- Return boundaryMesh reference
         const polyBoundaryMesh& boundaryMesh() const;
 
-        //- Return true if this patch field is coupled
+        //- Return true if this patch is geometrically coupled (i.e. faces and
+        //  points correspondence)
         virtual bool coupled() const
         {
             return false;
@@ -299,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/finiteVolume/fields/fvPatchFields/constraint/cyclicAMI/cyclicAMIFvPatchField.C b/src/finiteVolume/fields/fvPatchFields/constraint/cyclicAMI/cyclicAMIFvPatchField.C
index 8e358063fa4e96ae5affc153a892f753c6115776..31729346e24a67589461886dcadb83fe558b6acc 100644
--- a/src/finiteVolume/fields/fvPatchFields/constraint/cyclicAMI/cyclicAMIFvPatchField.C
+++ b/src/finiteVolume/fields/fvPatchFields/constraint/cyclicAMI/cyclicAMIFvPatchField.C
@@ -106,7 +106,7 @@ Foam::cyclicAMIFvPatchField<Type>::cyclicAMIFvPatchField
             << exit(FatalIOError);
     }
 
-    if (cyclicAMIPatch_.coupled())
+    if (this->coupled())
     {
         this->evaluate(Pstream::blocking);
     }
@@ -140,6 +140,27 @@ Foam::cyclicAMIFvPatchField<Type>::cyclicAMIFvPatchField
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
+template<class Type>
+bool Foam::cyclicAMIFvPatchField<Type>::coupled() const
+{
+    if
+    (
+        Pstream::parRun()
+     || (
+            this->cyclicAMIPatch_.size()
+         && this->cyclicAMIPatch_.cyclicAMIPatch().neighbPatch().size()
+        )
+    )
+    {
+        return true;
+    }
+    else
+    {
+        return false;
+    }
+}
+
+
 template<class Type>
 Foam::tmp<Foam::Field<Type> >
 Foam::cyclicAMIFvPatchField<Type>::patchNeighbourField() const
diff --git a/src/finiteVolume/fields/fvPatchFields/constraint/cyclicAMI/cyclicAMIFvPatchField.H b/src/finiteVolume/fields/fvPatchFields/constraint/cyclicAMI/cyclicAMIFvPatchField.H
index 9a4e5f6b4c8f85721c608366b9a59e90e71b403b..2e05111cb688a48568ffb599da04f18e0c3bc660 100644
--- a/src/finiteVolume/fields/fvPatchFields/constraint/cyclicAMI/cyclicAMIFvPatchField.H
+++ b/src/finiteVolume/fields/fvPatchFields/constraint/cyclicAMI/cyclicAMIFvPatchField.H
@@ -147,8 +147,12 @@ public:
 
         // Evaluation functions
 
+            //- Return true if coupled. Note that the underlying patch
+            //  is not coupled() - the points don't align.
+            virtual bool coupled() const;
+
             //- Return neighbour coupled internal cell data
-            tmp<Field<Type> > patchNeighbourField() const;
+            virtual tmp<Field<Type> > patchNeighbourField() const;
 
             //- Return reference to neighbour patchField
             const cyclicAMIFvPatchField<Type>& neighbourPatchField() const;
diff --git a/src/finiteVolume/fields/fvPatchFields/constraint/processor/processorFvPatchField.H b/src/finiteVolume/fields/fvPatchFields/constraint/processor/processorFvPatchField.H
index 7e3152e1312e1302dd7efd4c8241bec707b06423..0130909d04d4a88bbe8c46dd8af564bc8a0a5491 100644
--- a/src/finiteVolume/fields/fvPatchFields/constraint/processor/processorFvPatchField.H
+++ b/src/finiteVolume/fields/fvPatchFields/constraint/processor/processorFvPatchField.H
@@ -154,7 +154,7 @@ public:
             }
 
             //- Return neighbour field given internal field
-            tmp<Field<Type> > patchNeighbourField() const;
+            virtual tmp<Field<Type> > patchNeighbourField() const;
 
 
         // Evaluation functions
diff --git a/src/finiteVolume/fields/fvsPatchFields/constraint/cyclicAMI/cyclicAMIFvsPatchField.C b/src/finiteVolume/fields/fvsPatchFields/constraint/cyclicAMI/cyclicAMIFvsPatchField.C
index a347bc43475629a4980cbc1ec1bc4d5f95261341..0ffe6b9c95e24e4039001305a3c2525f487ede21 100644
--- a/src/finiteVolume/fields/fvsPatchFields/constraint/cyclicAMI/cyclicAMIFvsPatchField.C
+++ b/src/finiteVolume/fields/fvsPatchFields/constraint/cyclicAMI/cyclicAMIFvsPatchField.C
@@ -123,4 +123,27 @@ Foam::cyclicAMIFvsPatchField<Type>::cyclicAMIFvsPatchField
 {}
 
 
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+template<class Type>
+bool Foam::cyclicAMIFvsPatchField<Type>::coupled() const
+{
+    if
+    (
+        Pstream::parRun()
+     || (
+            this->cyclicAMIPatch_.size()
+         && this->cyclicAMIPatch_.cyclicAMIPatch().neighbPatch().size()
+        )
+    )
+    {
+        return true;
+    }
+    else
+    {
+        return false;
+    }
+}
+
+
 // ************************************************************************* //
diff --git a/src/finiteVolume/fields/fvsPatchFields/constraint/cyclicAMI/cyclicAMIFvsPatchField.H b/src/finiteVolume/fields/fvsPatchFields/constraint/cyclicAMI/cyclicAMIFvsPatchField.H
index fe849831347d30ba67183a7602536d15bb0942d7..d55ff5cd5d1f1665acb05cf22e88d2f515f3a773 100644
--- a/src/finiteVolume/fields/fvsPatchFields/constraint/cyclicAMI/cyclicAMIFvsPatchField.H
+++ b/src/finiteVolume/fields/fvsPatchFields/constraint/cyclicAMI/cyclicAMIFvsPatchField.H
@@ -123,6 +123,14 @@ public:
                 new cyclicAMIFvsPatchField<Type>(*this, iF)
             );
         }
+
+    // Member functions
+
+        // Access
+
+            //- Return true if running parallel
+            virtual bool coupled() const;
+
 };
 
 
diff --git a/src/finiteVolume/finiteVolume/gradSchemes/leastSquaresGrad/leastSquaresVectors.C b/src/finiteVolume/finiteVolume/gradSchemes/leastSquaresGrad/leastSquaresVectors.C
index 6002a07e1c1a2f95a39bed80ec4921a3da8a5052..27f5b72fcfd483336cc71e2c4549a92f3da24b38 100644
--- a/src/finiteVolume/finiteVolume/gradSchemes/leastSquaresGrad/leastSquaresVectors.C
+++ b/src/finiteVolume/finiteVolume/gradSchemes/leastSquaresGrad/leastSquaresVectors.C
@@ -132,7 +132,7 @@ void Foam::leastSquaresVectors::makeLeastSquaresVectors() const
         // Build the d-vectors
         vectorField pd = p.delta();
 
-        if (p.coupled())
+        if (pw.coupled())
         {
             forAll(pd, patchFacei)
             {
@@ -185,7 +185,7 @@ void Foam::leastSquaresVectors::makeLeastSquaresVectors() const
         // Build the d-vectors
         vectorField pd = p.delta();
 
-        if (p.coupled())
+        if (pw.coupled())
         {
             forAll(pd, patchFacei)
             {
@@ -256,7 +256,7 @@ void Foam::leastSquaresVectors::makeLeastSquaresVectors() const
                             label patchFacei =
                                 facei - mesh.boundaryMesh()[patchi].start();
 
-                            if (mesh.boundary()[patchi].coupled())
+                            if (w.boundaryField()[patchi].coupled())
                             {
                                 scalar wf = max
                                 (
diff --git a/src/finiteVolume/fvMesh/extendedStencil/cellToFace/extendedCellToFaceStencil.C b/src/finiteVolume/fvMesh/extendedStencil/cellToFace/extendedCellToFaceStencil.C
index 85c6f3f61f3ed78ccc56dc78c6abbd2f05391a56..021241fa270d2dc7b14695891d771f4a14a7b6cb 100644
--- a/src/finiteVolume/fvMesh/extendedStencil/cellToFace/extendedCellToFaceStencil.C
+++ b/src/finiteVolume/fvMesh/extendedStencil/cellToFace/extendedCellToFaceStencil.C
@@ -103,7 +103,7 @@ Foam::extendedCellToFaceStencil::extendedCellToFaceStencil(const polyMesh& mesh)
 
     forAll(patches, patchI)
     {
-        if (isA<coupledPolyPatch>(patches[patchI]))
+        if (patches[patchI].coupled())
         {
             const coupledPolyPatch& cpp =
                 refCast<const coupledPolyPatch>(patches[patchI]);
diff --git a/src/finiteVolume/fvMesh/extendedStencil/faceToCell/extendedFaceToCellStencil.C b/src/finiteVolume/fvMesh/extendedStencil/faceToCell/extendedFaceToCellStencil.C
index 0943d86685ea0621e35f3b5bb3b15feb73ecc864..4f364dc288749cced43bf09e85c2399745df822b 100644
--- a/src/finiteVolume/fvMesh/extendedStencil/faceToCell/extendedFaceToCellStencil.C
+++ b/src/finiteVolume/fvMesh/extendedStencil/faceToCell/extendedFaceToCellStencil.C
@@ -38,7 +38,7 @@ Foam::extendedFaceToCellStencil::extendedFaceToCellStencil(const polyMesh& mesh)
 
     forAll(patches, patchI)
     {
-        if (isA<coupledPolyPatch>(patches[patchI]))
+        if (patches[patchI].coupled())
         {
             const coupledPolyPatch& cpp =
                 refCast<const coupledPolyPatch>(patches[patchI]);
diff --git a/src/finiteVolume/interpolation/surfaceInterpolation/schemes/clippedLinear/clippedLinear.H b/src/finiteVolume/interpolation/surfaceInterpolation/schemes/clippedLinear/clippedLinear.H
index 312a453c44d6879eb3c58c97f598b85111f5885a..b69b2a05dc356e70dee8dd791b2d8a8dcb791800 100644
--- a/src/finiteVolume/interpolation/surfaceInterpolation/schemes/clippedLinear/clippedLinear.H
+++ b/src/finiteVolume/interpolation/surfaceInterpolation/schemes/clippedLinear/clippedLinear.H
@@ -157,7 +157,7 @@ public:
 
             forAll(mesh.boundary(), patchi)
             {
-                if (mesh.boundary()[patchi].coupled())
+                if (clippedLinearWeights.boundaryField()[patchi].coupled())
                 {
                     clippedLinearWeights.boundaryField()[patchi] =
                         max
diff --git a/src/finiteVolume/interpolation/surfaceInterpolation/schemes/reverseLinear/reverseLinear.H b/src/finiteVolume/interpolation/surfaceInterpolation/schemes/reverseLinear/reverseLinear.H
index 5dd8ee104a02ff7ab5e637e7fe65865a9affeab6..3f3cae05fedc836c7db478aba8e0e0b92f27f78f 100644
--- a/src/finiteVolume/interpolation/surfaceInterpolation/schemes/reverseLinear/reverseLinear.H
+++ b/src/finiteVolume/interpolation/surfaceInterpolation/schemes/reverseLinear/reverseLinear.H
@@ -129,7 +129,7 @@ public:
 
             forAll(mesh.boundary(), patchI)
             {
-                if (mesh.boundary()[patchI].coupled())
+                if (reverseLinearWeights.boundaryField()[patchI].coupled())
                 {
                     reverseLinearWeights.boundaryField()[patchI] =
                         1.0 - cdWeights.boundaryField()[patchI];
diff --git a/src/lagrangian/intermediate/submodels/CloudFunctionObjects/FacePostProcessing/FacePostProcessing.C b/src/lagrangian/intermediate/submodels/CloudFunctionObjects/FacePostProcessing/FacePostProcessing.C
index 0f2a765ea8994401a4da2eb4756ff6c3e03c73cd..36fb2aa035930d7c85b51d1cc6c2762c86a89bcf 100644
--- a/src/lagrangian/intermediate/submodels/CloudFunctionObjects/FacePostProcessing/FacePostProcessing.C
+++ b/src/lagrangian/intermediate/submodels/CloudFunctionObjects/FacePostProcessing/FacePostProcessing.C
@@ -316,7 +316,7 @@ Foam::FacePostProcessing<CloudType>::FacePostProcessing
 
                     if
                     (
-                        !pp.coupled()
+                        !magSf.boundaryField()[patchI].coupled()
                      || refCast<const coupledPolyPatch>(pp).owner()
                     )
                     {
diff --git a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolation.C b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolation.C
index a0965ff941f8b03fd8bae131981af9c5d2d900b8..cae738707d8518b558af8ea5c34eda2d99e695ec 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 e43180db6fc67efdcbb79cae87773c1b58ecc844..c9aa12da90501156648e172551afb6158c66874a 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/cyclicAMIPointPatch/cyclicAMIPointPatch.H b/src/meshTools/AMIInterpolation/patches/cyclic/cyclicAMIPointPatch/cyclicAMIPointPatch.H
index 3ade3aeaefa3e4d026c775ef776b4a80fef11536..78c69e0ad022777a755e31807aba9b2b74684a7c 100644
--- a/src/meshTools/AMIInterpolation/patches/cyclic/cyclicAMIPointPatch/cyclicAMIPointPatch.H
+++ b/src/meshTools/AMIInterpolation/patches/cyclic/cyclicAMIPointPatch/cyclicAMIPointPatch.H
@@ -107,6 +107,17 @@ public:
 
     //- Destructor
     virtual ~cyclicAMIPointPatch();
+
+
+    // Member Functions
+
+        //- Is patch 'coupled'. Note that on AMI the geometry is not
+        //  coupled but the fields are!
+        virtual bool coupled() const
+        {
+            return false;
+        }
+
 };
 
 
diff --git a/src/meshTools/AMIInterpolation/patches/cyclic/cyclicAMIPolyPatch/cyclicAMIPolyPatch.C b/src/meshTools/AMIInterpolation/patches/cyclic/cyclicAMIPolyPatch/cyclicAMIPolyPatch.C
index b6769849f7d0a96160f54dc77e3502f9310c845d..d281afc21f84de3cd248e4ac6506af26238ce6b6 100644
--- a/src/meshTools/AMIInterpolation/patches/cyclic/cyclicAMIPolyPatch/cyclicAMIPolyPatch.C
+++ b/src/meshTools/AMIInterpolation/patches/cyclic/cyclicAMIPolyPatch/cyclicAMIPolyPatch.C
@@ -548,23 +548,6 @@ Foam::cyclicAMIPolyPatch::~cyclicAMIPolyPatch()
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
-bool Foam::cyclicAMIPolyPatch::coupled() const
-{
-    if
-    (
-        Pstream::parRun()
-     || (size() && neighbPatch().size())
-    )
-    {
-        return true;
-    }
-    else
-    {
-        return false;
-    }
-}
-
-
 Foam::label Foam::cyclicAMIPolyPatch::neighbPatchID() const
 {
     if (nbrPatchID_ == -1)
diff --git a/src/meshTools/AMIInterpolation/patches/cyclic/cyclicAMIPolyPatch/cyclicAMIPolyPatch.H b/src/meshTools/AMIInterpolation/patches/cyclic/cyclicAMIPolyPatch/cyclicAMIPolyPatch.H
index ced7968171c7f6ddc3c81d7cac8126d08b84857f..dcd26799c0e644a4df8258fd66ebb87f14654a3b 100644
--- a/src/meshTools/AMIInterpolation/patches/cyclic/cyclicAMIPolyPatch/cyclicAMIPolyPatch.H
+++ b/src/meshTools/AMIInterpolation/patches/cyclic/cyclicAMIPolyPatch/cyclicAMIPolyPatch.H
@@ -254,10 +254,12 @@ public:
 
         // Access
 
-            //- Return true only if is coupled. Note that for non-parallel
-            //  operation of a decomposed case this can return the wrong
-            //  result
-            virtual bool coupled() const;
+            //- Is patch 'coupled'. Note that on AMI the geometry is not
+            //  coupled but the fields are!
+            virtual bool coupled() const
+            {
+                return false;
+            }
 
             //- Neighbour patch name
             inline const word& neighbPatchName() const;
@@ -316,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 ccafd75fd40c63d09180ed58c6698b39a92b1002..4bf59fba4167439982d70343ac1902bbae01d37e 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 4ba28fce083d113984e577fe7afa0762c28732c8..e1c98549023fe2071f96c5093921a3019cf91215 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 5b1113732930017ff9329f85558016701da67de4..c0e1e72ee8a64961994609141023d7784eecfbfa 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 a17dc1652ce206a8e451cb48fd9265c0a77d78ae..6b58fad24bdffaaccdb9f6c29fdda522eea82e65 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
diff --git a/src/sampling/sampledSurface/isoSurface/isoSurface.C b/src/sampling/sampledSurface/isoSurface/isoSurface.C
index 81497e47a015d2895b3acb71874a256149c85e63..f96983d27ac657fa9c2224748091ea25672ccd2c 100644
--- a/src/sampling/sampledSurface/isoSurface/isoSurface.C
+++ b/src/sampling/sampledSurface/isoSurface/isoSurface.C
@@ -1769,7 +1769,7 @@ Foam::isoSurface::isoSurface
         const polyPatch& pp = patches[patchI];
 
         // Adapt separated coupled (proc and cyclic) patches
-        if (isA<coupledPolyPatch>(pp))
+        if (pp.coupled())
         {
             fvPatchVectorField& pfld = const_cast<fvPatchVectorField&>
             (
diff --git a/tutorials/incompressible/pimpleFoam/TJunction/system/fvSolution b/tutorials/incompressible/pimpleFoam/TJunction/system/fvSolution
index 876e1532a994748ded26ced00ae554ad8ae0aaf3..8e0f165060b34f36c7652578f2d4fec19ffd5707 100644
--- a/tutorials/incompressible/pimpleFoam/TJunction/system/fvSolution
+++ b/tutorials/incompressible/pimpleFoam/TJunction/system/fvSolution
@@ -59,7 +59,7 @@ solvers
 
 PIMPLE
 {
-    nOuterCorrectors 2;
+    nOuterCorrectors 1;
     nCorrectors     2;
     nNonOrthogonalCorrectors 0;
     pRefCell        0;
diff --git a/tutorials/incompressible/pimpleFoam/TJunctionFan/system/fvSolution b/tutorials/incompressible/pimpleFoam/TJunctionFan/system/fvSolution
index 876e1532a994748ded26ced00ae554ad8ae0aaf3..8e0f165060b34f36c7652578f2d4fec19ffd5707 100644
--- a/tutorials/incompressible/pimpleFoam/TJunctionFan/system/fvSolution
+++ b/tutorials/incompressible/pimpleFoam/TJunctionFan/system/fvSolution
@@ -59,7 +59,7 @@ solvers
 
 PIMPLE
 {
-    nOuterCorrectors 2;
+    nOuterCorrectors 1;
     nCorrectors     2;
     nNonOrthogonalCorrectors 0;
     pRefCell        0;
diff --git a/tutorials/incompressible/simpleFoam/pipeCyclic/0.org/U b/tutorials/incompressible/simpleFoam/pipeCyclic/0.org/U
new file mode 100644
index 0000000000000000000000000000000000000000..8ad134885121cf80b2851b5984ae8bad0b799308
--- /dev/null
+++ b/tutorials/incompressible/simpleFoam/pipeCyclic/0.org/U
@@ -0,0 +1,58 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  dev                                   |
+|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       volVectorField;
+    object      U;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+dimensions      [0 1 -1 0 0 0 0];
+
+internalField   uniform (1 0 0);
+
+boundaryField
+{
+    inlet
+    {
+        type            codedFixedValue;
+        redirectType    swirl;
+
+        code
+        #{
+            const vector axis(1, 0, 0);
+
+            vectorField v = 2.0*this->patch().Cf() ^ axis;
+            v.replace(vector::X, 1.0);
+            operator==(v);
+        #};
+        value           $internalField;
+    }
+
+    outlet
+    {
+        type            inletOutlet;
+        inletValue      $internalField;
+        value           $internalField;
+    }
+
+    walls
+    {
+        type            fixedValue;
+        value           uniform (0 0 0);
+    }
+
+    "side.*"
+    {
+        type            cyclicAMI;
+    }
+}
+
+// ************************************************************************* //
diff --git a/tutorials/incompressible/simpleFoam/pipeCyclic/0.org/epsilon b/tutorials/incompressible/simpleFoam/pipeCyclic/0.org/epsilon
new file mode 100644
index 0000000000000000000000000000000000000000..9f571637a75ba5b8a65b1efebb68f54c820cec89
--- /dev/null
+++ b/tutorials/incompressible/simpleFoam/pipeCyclic/0.org/epsilon
@@ -0,0 +1,50 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  dev                                   |
+|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       volScalarField;
+    location    "0";
+    object      epsilon;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+dimensions      [ 0 2 -3 0 0 0 0 ];
+
+internalField   uniform 1;
+
+boundaryField
+{
+    inlet
+    {
+        type            turbulentMixingLengthDissipationRateInlet;
+        mixingLength    0.5;       // 0.5m - half channel height
+        value           $internalField;
+    }
+
+    outlet
+    {
+        type            inletOutlet;
+        inletValue      $internalField;
+    }
+
+    walls
+    {
+        type            epsilonWallFunction;
+        value           uniform 0;
+    }
+
+    "side.*"
+    {
+        type            cyclicAMI;
+    }
+}
+
+
+// ************************************************************************* //
diff --git a/tutorials/incompressible/simpleFoam/pipeCyclic/0.org/k b/tutorials/incompressible/simpleFoam/pipeCyclic/0.org/k
new file mode 100644
index 0000000000000000000000000000000000000000..7266279462bb5164bb69285c27a27f16d58ad1e6
--- /dev/null
+++ b/tutorials/incompressible/simpleFoam/pipeCyclic/0.org/k
@@ -0,0 +1,50 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  dev                                   |
+|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       volScalarField;
+    location    "0";
+    object      k;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+dimensions      [ 0 2 -2 0 0 0 0 ];
+
+internalField   uniform 1;
+
+boundaryField
+{
+    inlet
+    {
+        type            turbulentIntensityKineticEnergyInlet;
+        intensity       0.05;       // 5% turbulent intensity
+        value           $internalField;
+    }
+
+    outlet
+    {
+        type            inletOutlet;
+        inletValue      $internalField;
+    }
+
+    walls
+    {
+        type            kqRWallFunction;
+        value           uniform 0;
+    }
+
+    "side.*"
+    {
+        type            cyclicAMI;
+    }
+}
+
+
+// ************************************************************************* //
diff --git a/tutorials/incompressible/simpleFoam/pipeCyclic/0.org/nuTilda b/tutorials/incompressible/simpleFoam/pipeCyclic/0.org/nuTilda
new file mode 100644
index 0000000000000000000000000000000000000000..f25d2050950ccb4e73c7a38016afb5e72cfc283b
--- /dev/null
+++ b/tutorials/incompressible/simpleFoam/pipeCyclic/0.org/nuTilda
@@ -0,0 +1,44 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  dev                                   |
+|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       volScalarField;
+    object      nuTilda;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+dimensions      [0 2 -1 0 0 0 0];
+
+internalField   uniform 0;
+
+boundaryField
+{
+    inlet
+    {
+        type            zeroGradient;
+    }
+
+    outlet
+    {
+        type            zeroGradient;
+    }
+
+    walls
+    {
+        type            zeroGradient;
+    }
+
+    "side.*"
+    {
+        type            cyclicAMI;
+    }
+}
+
+// ************************************************************************* //
diff --git a/tutorials/incompressible/simpleFoam/pipeCyclic/0.org/nut b/tutorials/incompressible/simpleFoam/pipeCyclic/0.org/nut
new file mode 100644
index 0000000000000000000000000000000000000000..62cb2f0e62dd4ea2092954f3146cb49eb4e87949
--- /dev/null
+++ b/tutorials/incompressible/simpleFoam/pipeCyclic/0.org/nut
@@ -0,0 +1,49 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  dev                                   |
+|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       volScalarField;
+    location    "0";
+    object      nut;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+dimensions      [ 0 2 -1 0 0 0 0 ];
+
+internalField   uniform 0;
+
+boundaryField
+{
+    inlet
+    {
+        type            calculated;
+        value           $internalField;
+    }
+
+    outlet
+    {
+        type            calculated;
+        value           $internalField;
+    }
+
+    walls
+    {
+        type            nutkWallFunction;
+        value           $internalField;
+    }
+
+    "side.*"
+    {
+        type            cyclicAMI;
+    }
+}
+
+
+// ************************************************************************* //
diff --git a/tutorials/incompressible/simpleFoam/pipeCyclic/0.org/p b/tutorials/incompressible/simpleFoam/pipeCyclic/0.org/p
new file mode 100644
index 0000000000000000000000000000000000000000..ede4c306b8e72bd6d26de8e8b39b8535c6e22f61
--- /dev/null
+++ b/tutorials/incompressible/simpleFoam/pipeCyclic/0.org/p
@@ -0,0 +1,45 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  dev                                   |
+|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       volScalarField;
+    object      p;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+dimensions      [0 2 -2 0 0 0 0];
+
+internalField   uniform 0;
+
+boundaryField
+{
+    inlet
+    {
+        type            zeroGradient;
+    }
+
+    outlet
+    {
+        type            fixedValue;
+        value           uniform 0;
+    }
+
+    walls
+    {
+        type            zeroGradient;
+    }
+
+    "side.*"
+    {
+        type            cyclicAMI;
+    }
+}
+
+// ************************************************************************* //
diff --git a/tutorials/incompressible/simpleFoam/pipeCyclic/Allclean b/tutorials/incompressible/simpleFoam/pipeCyclic/Allclean
new file mode 100755
index 0000000000000000000000000000000000000000..d16400a94f636d461b62f6f909c2d64d7e29c335
--- /dev/null
+++ b/tutorials/incompressible/simpleFoam/pipeCyclic/Allclean
@@ -0,0 +1,11 @@
+#!/bin/sh
+cd ${0%/*} || exit 1    # run from this directory
+
+# Source tutorial clean functions
+. $WM_PROJECT_DIR/bin/tools/CleanFunctions
+
+rm -rf 0 > /dev/null 2>&1
+
+cleanCase
+
+# ----------------------------------------------------------------- end-of-file
diff --git a/tutorials/incompressible/simpleFoam/pipeCyclic/Allrun b/tutorials/incompressible/simpleFoam/pipeCyclic/Allrun
new file mode 100755
index 0000000000000000000000000000000000000000..e27a9470fba099b0e44c3316a248ac866b3513f4
--- /dev/null
+++ b/tutorials/incompressible/simpleFoam/pipeCyclic/Allrun
@@ -0,0 +1,39 @@
+#!/bin/sh
+cd ${0%/*} || exit 1    # run from this directory
+
+# Source tutorial run functions
+. $WM_PROJECT_DIR/bin/tools/RunFunctions
+
+# Get application directory
+application=`getApplication`
+
+# This case uses the #codeStream which is disabled by default. Enable for
+# just this case.
+MAIN_CONTROL_DICT=`foamEtcFile controlDict`
+if [ -f "$MAIN_CONTROL_DICT" ]
+then
+    echo "Modifying ${MAIN_CONTROL_DICT} to enable allowSystemOperations"
+
+    # Clean up on termination and on Ctrl-C
+    trap 'mv ${MAIN_CONTROL_DICT}.$$ ${MAIN_CONTROL_DICT} 2>/dev/null; exit 0' \
+        EXIT TERM INT
+    cp ${MAIN_CONTROL_DICT} ${MAIN_CONTROL_DICT}.$$
+
+    echo "Enabling allowSystemOperations in ${MAIN_CONTROL_DICT}."
+
+    sed \
+    -e s/"\(allowSystemOperations[ \t]*\)\([0-9]\);"/"\1 1;"/g \
+    ${MAIN_CONTROL_DICT}.$$ > ${MAIN_CONTROL_DICT}
+fi
+
+
+runApplication blockMesh
+runApplication topoSet
+runApplication refineHexMesh c0 -overwrite
+cp -r 0.org 0
+
+#runApplication $application
+runApplication decomposePar -cellDist
+runParallel $application 5
+
+# ----------------------------------------------------------------- end-of-file
diff --git a/tutorials/incompressible/simpleFoam/pipeCyclic/constant/RASProperties b/tutorials/incompressible/simpleFoam/pipeCyclic/constant/RASProperties
new file mode 100644
index 0000000000000000000000000000000000000000..63ed5a5ef8f1400e71fb3b34c1903c4a6afb3946
--- /dev/null
+++ b/tutorials/incompressible/simpleFoam/pipeCyclic/constant/RASProperties
@@ -0,0 +1,25 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  dev                                   |
+|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       dictionary;
+    location    "constant";
+    object      RASProperties;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+RASModel        realizableKE;
+
+turbulence      on;
+
+printCoeffs     on;
+
+
+// ************************************************************************* //
diff --git a/tutorials/incompressible/simpleFoam/pipeCyclic/constant/polyMesh/blockMeshDict b/tutorials/incompressible/simpleFoam/pipeCyclic/constant/polyMesh/blockMeshDict
new file mode 100644
index 0000000000000000000000000000000000000000..e8fa4bbb33e07385a8a45c5839a54a8a7390bc30
--- /dev/null
+++ b/tutorials/incompressible/simpleFoam/pipeCyclic/constant/polyMesh/blockMeshDict
@@ -0,0 +1,118 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  dev                                   |
+|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       dictionary;
+    object      blockMeshDict;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+convertToMeters 1;
+
+//- half angle of wedge in degrees
+halfAngle 45.0;
+
+//- Radius of pipe [m]
+radius 0.5;
+
+
+radHalfAngle    #calc "degToRad($halfAngle)";
+y               #calc "$radius*sin($radHalfAngle)";
+minY            #calc "-1.0*$y";
+z               #calc "$radius*cos($radHalfAngle)";
+minZ            #calc "-1.0*$z";
+
+vertices
+(
+    (0.0    0.0 0)      //0
+    (10     0.0 0)
+    (10     0.0 0)      //2
+    (0.0    0.0 0)
+
+    (0.0    $minY $z)   //4
+    (10     $minY $z)
+    (10     $y $z)      //6
+    (0.0    $y $z)
+
+);
+
+blocks
+(
+    // inlet block
+    hex (0 1 2 3  4 5 6 7) (50 5 5) simpleGrading (1 1 1)
+);
+
+edges
+(
+    arc 4 7 (0 0 $radius)
+    arc 5 6 (10 0 $radius)
+);
+
+boundary
+(
+    inlet
+    {
+        type patch;
+        faces
+        (
+            (0 4 7 3)
+        );
+    }
+
+    outlet
+    {
+        type patch;
+        faces
+        (
+            (1 2 6 5)
+        );
+    }
+
+    side1
+    {
+        type cyclicAMI;
+        neighbourPatch side2;
+        faces
+        (
+            (0 1 5 4)
+        );
+
+        transform rotational;
+        rotationAxis (1 0 0);
+        rotationCentre (0 0 0);
+    }
+
+    side2
+    {
+        type cyclicAMI;
+        neighbourPatch side1;
+        faces
+        (
+            (7 6 2 3)
+        );
+
+        transform rotational;
+        rotationAxis (1 0 0);
+        rotationCentre (0 0 0);
+    }
+
+    walls
+    {
+        type wall;
+        faces
+        (
+            (4 5 6 7)
+            (3 2 1 0)
+        );
+    }
+);
+
+
+// ************************************************************************* //
diff --git a/tutorials/incompressible/simpleFoam/pipeCyclic/constant/polyMesh/boundary b/tutorials/incompressible/simpleFoam/pipeCyclic/constant/polyMesh/boundary
new file mode 100644
index 0000000000000000000000000000000000000000..9b8e73ecfd9cd5aa8d8300034ab96dc76e98ad78
--- /dev/null
+++ b/tutorials/incompressible/simpleFoam/pipeCyclic/constant/polyMesh/boundary
@@ -0,0 +1,62 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  dev                                   |
+|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       polyBoundaryMesh;
+    location    "constant/polyMesh";
+    object      boundary;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+5
+(
+    inlet
+    {
+        type            patch;
+        nFaces          28;
+        startFace       4422;
+    }
+    outlet
+    {
+        type            patch;
+        nFaces          28;
+        startFace       4450;
+    }
+    side1
+    {
+        type            cyclicAMI;
+        nFaces          400;
+        startFace       4478;
+        matchTolerance  0.0001;
+        neighbourPatch  side2;
+        transform       rotational;
+        rotationAxis    (1 0 0);
+        rotationCentre  (0 0 0);
+    }
+    side2
+    {
+        type            cyclicAMI;
+        nFaces          250;
+        startFace       4878;
+        matchTolerance  0.0001;
+        neighbourPatch  side1;
+        transform       rotational;
+        rotationAxis    (1 0 0);
+        rotationCentre  (0 0 0);
+    }
+    walls
+    {
+        type            wall;
+        nFaces          250;
+        startFace       5128;
+    }
+)
+
+// ************************************************************************* //
diff --git a/tutorials/incompressible/simpleFoam/pipeCyclic/constant/transportProperties b/tutorials/incompressible/simpleFoam/pipeCyclic/constant/transportProperties
new file mode 100644
index 0000000000000000000000000000000000000000..ab12b49567ee043def264706acc4edcbd7a6d17d
--- /dev/null
+++ b/tutorials/incompressible/simpleFoam/pipeCyclic/constant/transportProperties
@@ -0,0 +1,23 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  dev                                   |
+|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       dictionary;
+    location    "constant";
+    object      transportProperties;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+transportModel  Newtonian;
+
+nu              nu [ 0 2 -1 0 0 0 0 ] 1e-06;
+
+
+// ************************************************************************* //
diff --git a/tutorials/incompressible/simpleFoam/pipeCyclic/constant/turbulenceProperties b/tutorials/incompressible/simpleFoam/pipeCyclic/constant/turbulenceProperties
new file mode 100644
index 0000000000000000000000000000000000000000..e7fa28c74a5fead3fbcdd79b5587ef684e8bacb4
--- /dev/null
+++ b/tutorials/incompressible/simpleFoam/pipeCyclic/constant/turbulenceProperties
@@ -0,0 +1,20 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  dev                                   |
+|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       dictionary;
+    location    "constant";
+    object      turbulenceProperties;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+simulationType RASModel;
+
+// ************************************************************************* //
diff --git a/tutorials/incompressible/simpleFoam/pipeCyclic/system/controlDict b/tutorials/incompressible/simpleFoam/pipeCyclic/system/controlDict
new file mode 100644
index 0000000000000000000000000000000000000000..e43cefc79a5ade11897d10834c5a34c226908953
--- /dev/null
+++ b/tutorials/incompressible/simpleFoam/pipeCyclic/system/controlDict
@@ -0,0 +1,49 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  dev                                   |
+|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       dictionary;
+    location    "system";
+    object      controlDict;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+application     simpleFoam;
+
+startFrom       startTime;
+
+startTime       0;
+
+stopAt          endTime;
+
+endTime         1000;
+
+deltaT          1;
+
+writeControl    timeStep;
+
+writeInterval   100;
+
+purgeWrite      0;
+
+writeFormat     ascii;
+
+writePrecision  6;
+
+writeCompression uncompressed;
+
+timeFormat      general;
+
+timePrecision   6;
+
+runTimeModifiable true;
+
+
+// ************************************************************************* //
diff --git a/tutorials/incompressible/simpleFoam/pipeCyclic/system/decomposeParDict b/tutorials/incompressible/simpleFoam/pipeCyclic/system/decomposeParDict
new file mode 100644
index 0000000000000000000000000000000000000000..b76e7ccd2433c14c5c5c4d63a0c6cdf71617ee53
--- /dev/null
+++ b/tutorials/incompressible/simpleFoam/pipeCyclic/system/decomposeParDict
@@ -0,0 +1,22 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  dev                                   |
+|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       dictionary;
+    object      decomposeParDict;
+}
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+numberOfSubdomains 5;
+
+method          scotch;
+
+// ************************************************************************* //
diff --git a/tutorials/incompressible/simpleFoam/pipeCyclic/system/fvSchemes b/tutorials/incompressible/simpleFoam/pipeCyclic/system/fvSchemes
new file mode 100644
index 0000000000000000000000000000000000000000..c1af3f96495a78e314042566f18171c71f5523d6
--- /dev/null
+++ b/tutorials/incompressible/simpleFoam/pipeCyclic/system/fvSchemes
@@ -0,0 +1,71 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  dev                                   |
+|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       dictionary;
+    location    "system";
+    object      fvSchemes;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+ddtSchemes
+{
+    default         steadyState;
+}
+
+gradSchemes
+{
+    default         Gauss linear;
+    grad(p)         Gauss linear;
+    grad(U)         Gauss linear;
+}
+
+divSchemes
+{
+    default         none;
+    div(phi,U)      Gauss limitedLinearV 1;
+    div(phi,k)      Gauss limitedLinear 1;
+    div(phi,epsilon) Gauss limitedLinear 1;
+    div(phi,R)      Gauss limitedLinear 1;
+    div(R)          Gauss linear;
+    div(phi,nuTilda) Gauss limitedLinear 1;
+    div((nuEff*dev(T(grad(U))))) Gauss linear;
+}
+
+laplacianSchemes
+{
+    default         none;
+    laplacian(nuEff,U) Gauss linear corrected;
+    laplacian((1|A(U)),p) Gauss linear corrected;
+    laplacian(DkEff,k) Gauss linear corrected;
+    laplacian(DepsilonEff,epsilon) Gauss linear corrected;
+    laplacian(DREff,R) Gauss linear corrected;
+    laplacian(DnuTildaEff,nuTilda) Gauss linear corrected;
+}
+
+interpolationSchemes
+{
+    default         linear;
+    interpolate(U)  linear;
+}
+
+snGradSchemes
+{
+    default         corrected;
+}
+
+fluxRequired
+{
+    default         no;
+    p               ;
+}
+
+
+// ************************************************************************* //
diff --git a/tutorials/incompressible/simpleFoam/pipeCyclic/system/fvSolution b/tutorials/incompressible/simpleFoam/pipeCyclic/system/fvSolution
new file mode 100644
index 0000000000000000000000000000000000000000..5d305469b4f164c77d1b4aa0db7f96f10c725efa
--- /dev/null
+++ b/tutorials/incompressible/simpleFoam/pipeCyclic/system/fvSolution
@@ -0,0 +1,104 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  dev                                   |
+|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       dictionary;
+    location    "system";
+    object      fvSolution;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+solvers
+{
+    p
+    {
+        solver          GAMG;
+        smoother        GaussSeidel;
+        cacheAgglomeration true;
+        nCellsInCoarsestLevel 10;
+        agglomerator    faceAreaPair;
+        mergeLevels     1;
+
+        tolerance       1e-06;
+        relTol          0.05;
+    }
+
+    pFinal
+    {
+        solver          GAMG;
+        smoother        GaussSeidel;
+        cacheAgglomeration true;
+        nCellsInCoarsestLevel 10;
+        agglomerator    faceAreaPair;
+        mergeLevels     1;
+
+        tolerance       1e-06;
+        relTol          0;
+    }
+
+    "(U|k|epsilon)"
+    {
+        solver          smoothSolver;
+        smoother        GaussSeidel;
+        tolerance       1e-05;
+        relTol          0.1;
+    }
+
+    "(U|k|epsilon)Final"
+    {
+        solver          PBiCG;
+        preconditioner  DILU;
+
+        tolerance       1e-05;
+        relTol          0;
+    }
+}
+
+PIMPLE
+{
+    nOuterCorrectors 4;
+    nCorrectors     1;
+    nNonOrthogonalCorrectors 0;
+    pRefCell        0;
+    pRefValue       0;
+}
+
+SIMPLE
+{
+    nNonOrthogonalCorrectors 0;
+    residualControl
+    {
+        p               1e-2;
+        U               1e-3;
+        "(k|epsilon)"   1e-3;
+    }
+}
+
+relaxationFactors
+{
+    fields
+    {
+        p               0.3;
+    }
+    equations
+    {
+        U               0.7;
+        k               0.7;
+        "epsilon.*"     0.7;
+    }
+}
+
+cache
+{
+    grad(U);
+}
+
+
+// ************************************************************************* //
diff --git a/tutorials/incompressible/simpleFoam/pipeCyclic/system/topoSetDict b/tutorials/incompressible/simpleFoam/pipeCyclic/system/topoSetDict
new file mode 100644
index 0000000000000000000000000000000000000000..bce9f890216e54a92681e0ed7536ec0ef261d6ec
--- /dev/null
+++ b/tutorials/incompressible/simpleFoam/pipeCyclic/system/topoSetDict
@@ -0,0 +1,76 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  dev                                   |
+|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       dictionary;
+    object      topoSetDict;
+}
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+actions
+(
+    {
+        name    f0;
+        type    faceSet;
+        action  new;
+        source  patchToFace;
+        sourceInfo
+        {
+            name "side1";
+        }
+    }
+    {
+        name    f0;
+        type    faceSet;
+        action  subset;
+        source  boxToFace;
+        sourceInfo
+        {
+            box (0 -100 -100)(100 -0.2 100);
+        }
+    }
+    {
+        name    c0;
+        type    cellSet;
+        action  new;
+        source  faceToCell;
+        sourceInfo
+        {
+            set     f0;
+            option  any;
+        }
+    }
+
+
+    {
+        name    walls;
+        type    faceSet;
+        action  new;
+        source  patchToFace;
+        sourceInfo
+        {
+            name "walls";
+        }
+    }
+    {
+        name    c0;
+        type    cellSet;
+        action  delete;
+        source  faceToCell;
+        sourceInfo
+        {
+            set     walls;
+            option  any;
+        }
+    }
+);
+
+// ************************************************************************* //