diff --git a/src/OpenFOAM/Make/files b/src/OpenFOAM/Make/files
index 6fca790005eb02edff2868c435b3fea16877bce1..4d2062b421ce99be31940ed4632f827bf6f89803 100644
--- a/src/OpenFOAM/Make/files
+++ b/src/OpenFOAM/Make/files
@@ -387,6 +387,7 @@ $(cellShape)/cellShapeIO.C
 $(cellShape)/cellShapeIOList.C
 
 meshes/Identifiers/patch/patchIdentifier.C
+meshes/Identifiers/patch/coupleGroupIdentifier.C
 
 meshes/MeshObject/meshObject.C
 
diff --git a/src/meshTools/mappedPatches/mappedPolyPatch/coupleGroupIdentifier.C b/src/OpenFOAM/meshes/Identifiers/patch/coupleGroupIdentifier.C
similarity index 100%
rename from src/meshTools/mappedPatches/mappedPolyPatch/coupleGroupIdentifier.C
rename to src/OpenFOAM/meshes/Identifiers/patch/coupleGroupIdentifier.C
diff --git a/src/meshTools/mappedPatches/mappedPolyPatch/coupleGroupIdentifier.H b/src/OpenFOAM/meshes/Identifiers/patch/coupleGroupIdentifier.H
similarity index 100%
rename from src/meshTools/mappedPatches/mappedPolyPatch/coupleGroupIdentifier.H
rename to src/OpenFOAM/meshes/Identifiers/patch/coupleGroupIdentifier.H
diff --git a/src/meshTools/mappedPatches/mappedPolyPatch/coupleGroupIdentifierI.H b/src/OpenFOAM/meshes/Identifiers/patch/coupleGroupIdentifierI.H
similarity index 100%
rename from src/meshTools/mappedPatches/mappedPolyPatch/coupleGroupIdentifierI.H
rename to src/OpenFOAM/meshes/Identifiers/patch/coupleGroupIdentifierI.H
diff --git a/src/OpenFOAM/meshes/polyMesh/polyPatches/constraint/cyclic/cyclicPolyPatch.C b/src/OpenFOAM/meshes/polyMesh/polyPatches/constraint/cyclic/cyclicPolyPatch.C
index 54a49523f7718189c4bdb1c3ba378a121c272e1e..9f451bd77216e9986655deffd774d61db3572f00 100644
--- a/src/OpenFOAM/meshes/polyMesh/polyPatches/constraint/cyclic/cyclicPolyPatch.C
+++ b/src/OpenFOAM/meshes/polyMesh/polyPatches/constraint/cyclic/cyclicPolyPatch.C
@@ -171,7 +171,7 @@ void Foam::cyclicPolyPatch::calcTransforms
             "cyclicPolyPatch::calcTransforms()"
         )   << "Patch " << name()
             << " has transform type " << transformTypeNames[transform()]
-            << ", neighbour patch " << neighbPatchName_
+            << ", neighbour patch " << neighbPatchName()
             << " has transform type "
             << neighbPatch().transformTypeNames[neighbPatch().transform()]
             << exit(FatalError);
@@ -350,7 +350,7 @@ void Foam::cyclicPolyPatch::calcTransforms
                         << neighbPatch().separationVector_
                         << " by more than tolerance " << avgTol << endl
                         << "patch:" << name()
-                        << " neighbour:" << neighbPatchName_
+                        << " neighbour:" << neighbPatchName()
                         << endl;
                 }
 
@@ -374,7 +374,7 @@ void Foam::cyclicPolyPatch::calcTransforms
                         << "Continuing with specified separation vector "
                         << separationVector_ << endl
                         << "patch:" << name()
-                        << " neighbour:" << neighbPatchName_
+                        << " neighbour:" << neighbPatchName()
                         << endl;
                 }
 
@@ -658,6 +658,7 @@ Foam::cyclicPolyPatch::cyclicPolyPatch
 :
     coupledPolyPatch(name, dict, index, bm, patchType),
     neighbPatchName_(dict.lookupOrDefault("neighbourPatch", word::null)),
+    coupleGroup_(dict),
     neighbPatchID_(-1),
     rotationAxis_(vector::zero),
     rotationCentre_(point::zero),
@@ -665,7 +666,7 @@ Foam::cyclicPolyPatch::cyclicPolyPatch
     coupledPointsPtr_(NULL),
     coupledEdgesPtr_(NULL)
 {
-    if (neighbPatchName_ == word::null)
+    if (neighbPatchName_ == word::null && !coupleGroup_.valid())
     {
         FatalIOErrorIn
         (
@@ -733,7 +734,8 @@ Foam::cyclicPolyPatch::cyclicPolyPatch
 )
 :
     coupledPolyPatch(pp, bm),
-    neighbPatchName_(pp.neighbPatchName()),
+    neighbPatchName_(pp.neighbPatchName_),
+    coupleGroup_(pp.coupleGroup_),
     neighbPatchID_(-1),
     rotationAxis_(pp.rotationAxis_),
     rotationCentre_(pp.rotationCentre_),
@@ -753,11 +755,12 @@ Foam::cyclicPolyPatch::cyclicPolyPatch
     const label index,
     const label newSize,
     const label newStart,
-    const word& neighbPatchName
+    const word& neighbName
 )
 :
     coupledPolyPatch(pp, bm, index, newSize, newStart),
-    neighbPatchName_(neighbPatchName),
+    neighbPatchName_(neighbName),
+    coupleGroup_(pp.coupleGroup_),
     neighbPatchID_(-1),
     rotationAxis_(pp.rotationAxis_),
     rotationCentre_(pp.rotationCentre_),
@@ -765,10 +768,10 @@ Foam::cyclicPolyPatch::cyclicPolyPatch
     coupledPointsPtr_(NULL),
     coupledEdgesPtr_(NULL)
 {
-    if (neighbPatchName_ == name())
+    if (neighbName == name())
     {
         FatalErrorIn("cyclicPolyPatch::cyclicPolyPatch(..)")
-            << "Neighbour patch name " << neighbPatchName_
+            << "Neighbour patch name " << neighbName
             << " cannot be the same as this patch " << name()
             << exit(FatalError);
     }
@@ -789,6 +792,7 @@ Foam::cyclicPolyPatch::cyclicPolyPatch
 :
     coupledPolyPatch(pp, bm, index, mapAddressing, newStart),
     neighbPatchName_(pp.neighbPatchName_),
+    coupleGroup_(pp.coupleGroup_),
     neighbPatchID_(-1),
     rotationAxis_(pp.rotationAxis_),
     rotationCentre_(pp.rotationCentre_),
@@ -809,16 +813,29 @@ Foam::cyclicPolyPatch::~cyclicPolyPatch()
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
+const Foam::word& Foam::cyclicPolyPatch::neighbPatchName() const
+{
+    if (neighbPatchName_.empty())
+    {
+        // Try and use patchGroup to find samplePatch and sampleRegion
+        label patchID = coupleGroup_.findOtherPatchID(*this);
+
+        neighbPatchName_ = boundaryMesh()[patchID].name();
+    }
+    return neighbPatchName_;
+}
+
+
 Foam::label Foam::cyclicPolyPatch::neighbPatchID() const
 {
     if (neighbPatchID_ == -1)
     {
-        neighbPatchID_ = this->boundaryMesh().findPatchID(neighbPatchName_);
+        neighbPatchID_ = this->boundaryMesh().findPatchID(neighbPatchName());
 
         if (neighbPatchID_ == -1)
         {
             FatalErrorIn("cyclicPolyPatch::neighbPatchID() const")
-                << "Illegal neighbourPatch name " << neighbPatchName_
+                << "Illegal neighbourPatch name " << neighbPatchName()
                 << endl << "Valid patch names are "
                 << this->boundaryMesh().names()
                 << exit(FatalError);
@@ -1256,7 +1273,7 @@ bool Foam::cyclicPolyPatch::order
     {
         Pout<< "order : of " << pp.size()
             << " faces of patch:" << name()
-            << " neighbour:" << neighbPatchName_
+            << " neighbour:" << neighbPatchName()
             << endl;
     }
     faceMap.setSize(pp.size());
@@ -1444,8 +1461,12 @@ bool Foam::cyclicPolyPatch::order
 void Foam::cyclicPolyPatch::write(Ostream& os) const
 {
     coupledPolyPatch::write(os);
-    os.writeKeyword("neighbourPatch") << neighbPatchName_
-        << token::END_STATEMENT << nl;
+    if (!neighbPatchName_.empty())
+    {
+        os.writeKeyword("neighbourPatch") << neighbPatchName_
+            << token::END_STATEMENT << nl;
+    }
+    coupleGroup_.write(os);
     switch (transform())
     {
         case ROTATIONAL:
diff --git a/src/OpenFOAM/meshes/polyMesh/polyPatches/constraint/cyclic/cyclicPolyPatch.H b/src/OpenFOAM/meshes/polyMesh/polyPatches/constraint/cyclic/cyclicPolyPatch.H
index 8f094da8cf9a5559dc4bdff15cec9ac9c3da56b4..90474015ce71a099b48ef1d34b0c02acc386e353 100644
--- a/src/OpenFOAM/meshes/polyMesh/polyPatches/constraint/cyclic/cyclicPolyPatch.H
+++ b/src/OpenFOAM/meshes/polyMesh/polyPatches/constraint/cyclic/cyclicPolyPatch.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-2012 OpenFOAM Foundation
+    \\  /    A nd           | Copyright (C) 2011-2013 OpenFOAM Foundation
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -50,6 +50,7 @@ SourceFiles
 #include "edgeList.H"
 #include "polyBoundaryMesh.H"
 #include "diagTensorField.H"
+#include "coupleGroupIdentifier.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -67,7 +68,10 @@ class cyclicPolyPatch
     // Private data
 
         //- Name of other half
-        const word neighbPatchName_;
+        mutable word neighbPatchName_;
+
+        //- Optional patchGroup to find neighbPatch
+        const coupleGroupIdentifier coupleGroup_;
 
         //- Index of other half
         mutable label neighbPatchID_;
@@ -306,12 +310,10 @@ public:
 
     // Member Functions
 
-        const word& neighbPatchName() const
-        {
-            return neighbPatchName_;
-        }
+        //- Neighbour patch name
+        const word& neighbPatchName() const;
 
-        //- Neighbour patchID.
+        //- Neighbour patchID
         virtual label neighbPatchID() const;
 
         virtual bool owner() const
diff --git a/src/meshTools/AMIInterpolation/patches/cyclicAMI/cyclicAMIPolyPatch/cyclicAMIPolyPatch.C b/src/meshTools/AMIInterpolation/patches/cyclicAMI/cyclicAMIPolyPatch/cyclicAMIPolyPatch.C
index 14e1c7ddf47adc97988bc798cbf156df813fc991..e906689415121d6de4a74250597006d7aabfd852 100644
--- a/src/meshTools/AMIInterpolation/patches/cyclicAMI/cyclicAMIPolyPatch/cyclicAMIPolyPatch.C
+++ b/src/meshTools/AMIInterpolation/patches/cyclicAMI/cyclicAMIPolyPatch/cyclicAMIPolyPatch.C
@@ -125,7 +125,7 @@ void Foam::cyclicAMIPolyPatch::calcTransforms
         FatalErrorIn("cyclicAMIPolyPatch::calcTransforms()")
             << "Patch " << name()
             << " has transform type " << transformTypeNames[transform()]
-            << ", neighbour patch " << nbrPatchName_
+            << ", neighbour patch " << neighbPatchName()
             << " has transform type "
             << neighbPatch().transformTypeNames[neighbPatch().transform()]
             << exit(FatalError);
@@ -416,7 +416,8 @@ Foam::cyclicAMIPolyPatch::cyclicAMIPolyPatch
 )
 :
     coupledPolyPatch(name, dict, index, bm, patchType),
-    nbrPatchName_(dict.lookup("neighbourPatch")),
+    nbrPatchName_(dict.lookupOrDefault<word>("neighbourPatch", "")),
+    coupleGroup_(dict),
     nbrPatchID_(-1),
     rotationAxis_(vector::zero),
     rotationCentre_(point::zero),
@@ -426,6 +427,22 @@ Foam::cyclicAMIPolyPatch::cyclicAMIPolyPatch
     surfPtr_(NULL),
     surfDict_(dict.subOrEmptyDict("surface"))
 {
+    if (nbrPatchName_ == word::null && !coupleGroup_.valid())
+    {
+        FatalIOErrorIn
+        (
+            "cyclicAMIPolyPatch::cyclicAMIPolyPatch"
+            "("
+                "const word&, "
+                "const dictionary&, "
+                "const label, "
+                "const polyBoundaryMesh&"
+            ")",
+            dict
+        )   << "No \"neighbourPatch\" or \"coupleGroup\" provided."
+            << exit(FatalIOError);
+    }
+
     if (nbrPatchName_ == name)
     {
         FatalIOErrorIn
@@ -495,6 +512,7 @@ Foam::cyclicAMIPolyPatch::cyclicAMIPolyPatch
 :
     coupledPolyPatch(pp, bm),
     nbrPatchName_(pp.nbrPatchName_),
+    coupleGroup_(pp.coupleGroup_),
     nbrPatchID_(-1),
     rotationAxis_(pp.rotationAxis_),
     rotationCentre_(pp.rotationCentre_),
@@ -521,6 +539,7 @@ Foam::cyclicAMIPolyPatch::cyclicAMIPolyPatch
 :
     coupledPolyPatch(pp, bm, index, newSize, newStart),
     nbrPatchName_(nbrPatchName),
+    coupleGroup_(pp.coupleGroup_),
     nbrPatchID_(-1),
     rotationAxis_(pp.rotationAxis_),
     rotationCentre_(pp.rotationCentre_),
@@ -561,6 +580,7 @@ Foam::cyclicAMIPolyPatch::cyclicAMIPolyPatch
 :
     coupledPolyPatch(pp, bm, index, mapAddressing, newStart),
     nbrPatchName_(pp.nbrPatchName_),
+    coupleGroup_(pp.coupleGroup_),
     nbrPatchID_(-1),
     rotationAxis_(pp.rotationAxis_),
     rotationCentre_(pp.rotationCentre_),
@@ -584,12 +604,12 @@ Foam::label Foam::cyclicAMIPolyPatch::neighbPatchID() const
 {
     if (nbrPatchID_ == -1)
     {
-        nbrPatchID_ = this->boundaryMesh().findPatchID(nbrPatchName_);
+        nbrPatchID_ = this->boundaryMesh().findPatchID(neighbPatchName());
 
         if (nbrPatchID_ == -1)
         {
             FatalErrorIn("cyclicPolyAMIPatch::neighbPatchID() const")
-                << "Illegal neighbourPatch name " << nbrPatchName_
+                << "Illegal neighbourPatch name " << neighbPatchName()
                 << nl << "Valid patch names are "
                 << this->boundaryMesh().names()
                 << exit(FatalError);
@@ -832,8 +852,12 @@ Foam::label Foam::cyclicAMIPolyPatch::pointFace
 void Foam::cyclicAMIPolyPatch::write(Ostream& os) const
 {
     coupledPolyPatch::write(os);
-    os.writeKeyword("neighbourPatch") << nbrPatchName_
-        << token::END_STATEMENT << nl;
+    if (!nbrPatchName_.empty())
+    {
+        os.writeKeyword("neighbourPatch") << nbrPatchName_
+            << token::END_STATEMENT << nl;
+    }
+    coupleGroup_.write(os);
 
     switch (transform())
     {
diff --git a/src/meshTools/AMIInterpolation/patches/cyclicAMI/cyclicAMIPolyPatch/cyclicAMIPolyPatch.H b/src/meshTools/AMIInterpolation/patches/cyclicAMI/cyclicAMIPolyPatch/cyclicAMIPolyPatch.H
index 28b0e5e17cb9baac5abaea765b6a6580192136e4..9c0f5fc3162baa9e34f977d0f9b6a277b624c987 100644
--- a/src/meshTools/AMIInterpolation/patches/cyclicAMI/cyclicAMIPolyPatch/cyclicAMIPolyPatch.H
+++ b/src/meshTools/AMIInterpolation/patches/cyclicAMI/cyclicAMIPolyPatch/cyclicAMIPolyPatch.H
@@ -38,6 +38,7 @@ SourceFiles
 #include "coupledPolyPatch.H"
 #include "AMIPatchToPatchInterpolation.H"
 #include "polyBoundaryMesh.H"
+#include "coupleGroupIdentifier.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -58,7 +59,10 @@ private:
     // Private data
 
         //- Name of other half
-        const word nbrPatchName_;
+        mutable word nbrPatchName_;
+
+        //- Optional patchGroup to find neighbPatch
+        const coupleGroupIdentifier coupleGroup_;
 
         //- Index of other half
         mutable label nbrPatchID_;
diff --git a/src/meshTools/AMIInterpolation/patches/cyclicAMI/cyclicAMIPolyPatch/cyclicAMIPolyPatchI.H b/src/meshTools/AMIInterpolation/patches/cyclicAMI/cyclicAMIPolyPatch/cyclicAMIPolyPatchI.H
index 66a273e0c7a61d3771e8c5f5b3a0ae8ab9f4b77f..217d189ae32275d94d532446bfd02e44ae3be8bc 100644
--- a/src/meshTools/AMIInterpolation/patches/cyclicAMI/cyclicAMIPolyPatch/cyclicAMIPolyPatchI.H
+++ b/src/meshTools/AMIInterpolation/patches/cyclicAMI/cyclicAMIPolyPatch/cyclicAMIPolyPatchI.H
@@ -27,6 +27,13 @@ License
 
 inline const Foam::word& Foam::cyclicAMIPolyPatch::neighbPatchName() const
 {
+    if (nbrPatchName_.empty())
+    {
+        // Try and use patchGroup to find samplePatch and sampleRegion
+        label patchID = coupleGroup_.findOtherPatchID(*this);
+
+        nbrPatchName_ = boundaryMesh()[patchID].name();
+    }
     return nbrPatchName_;
 }
 
diff --git a/src/meshTools/Make/files b/src/meshTools/Make/files
index 2adea5c4e113bb20cbf8c0e5b0d6f8a8219648aa..6b52b27068e611261b59ba1e90bbe2aedfdd9df1 100644
--- a/src/meshTools/Make/files
+++ b/src/meshTools/Make/files
@@ -199,7 +199,6 @@ mappedPatches/mappedPolyPatch/mappedPatchBase.C
 mappedPatches/mappedPolyPatch/mappedPolyPatch.C
 mappedPatches/mappedPolyPatch/mappedWallPolyPatch.C
 mappedPatches/mappedPolyPatch/mappedVariableThicknessWallPolyPatch.C
-mappedPatches/mappedPolyPatch/coupleGroupIdentifier.C
 
 mappedPatches/mappedPointPatch/mappedPointPatch.C
 mappedPatches/mappedPointPatch/mappedWallPointPatch.C
diff --git a/src/meshTools/mappedPatches/mappedPolyPatch/mappedPatchBase.C b/src/meshTools/mappedPatches/mappedPolyPatch/mappedPatchBase.C
index 30edacf93cf6d52e65ed5d5c113979e4a65d99d7..93c05785bbf705e4d382c246314414e4e78f62e6 100644
--- a/src/meshTools/mappedPatches/mappedPolyPatch/mappedPatchBase.C
+++ b/src/meshTools/mappedPatches/mappedPolyPatch/mappedPatchBase.C
@@ -1402,10 +1402,16 @@ void Foam::mappedPatchBase::write(Ostream& os) const
 {
     os.writeKeyword("sampleMode") << sampleModeNames_[mode_]
         << token::END_STATEMENT << nl;
-    os.writeKeyword("sampleRegion") << sampleRegion()
-        << token::END_STATEMENT << nl;
-    os.writeKeyword("samplePatch") << samplePatch()
-        << token::END_STATEMENT << nl;
+    if (!sampleRegion_.empty())
+    {
+        os.writeKeyword("sampleRegion") << sampleRegion_
+            << token::END_STATEMENT << nl;
+    }
+    if (!samplePatch_.empty())
+    {
+        os.writeKeyword("samplePatch") << samplePatch_
+            << token::END_STATEMENT << nl;
+    }
     coupleGroup_.write(os);
 
     if