diff --git a/applications/utilities/mesh/manipulation/createBaffles/createBaffles.C b/applications/utilities/mesh/manipulation/createBaffles/createBaffles.C
index fb53d4fef43eee2bb2521bb725cd66eb3c6a5f23..bc0e78a67f847cfe5d670f89ffc4142ffa96dbca 100644
--- a/applications/utilities/mesh/manipulation/createBaffles/createBaffles.C
+++ b/applications/utilities/mesh/manipulation/createBaffles/createBaffles.C
@@ -54,6 +54,57 @@ using namespace Foam;
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
+label addPatch
+(
+    fvMesh& mesh,
+    const word& patchName,
+    const word& groupName,
+    const dictionary& patchDict
+)
+{
+    const polyBoundaryMesh& pbm = mesh.boundaryMesh();
+
+    if (pbm.findPatchID(patchName) == -1)
+    {
+        autoPtr<polyPatch> ppPtr
+        (
+            polyPatch::New
+            (
+                patchName,
+                patchDict,
+                0,
+                pbm
+            )
+        );
+        polyPatch& pp = ppPtr();
+
+        if (!groupName.empty() && !pp.inGroup(groupName))
+        {
+            pp.inGroups().append(groupName);
+        }
+
+        // Add patch, create calculated everywhere
+        fvMeshTools::addPatch
+        (
+            mesh,
+            pp,
+            dictionary(),   // do not set specialised patchFields
+            calculatedFvPatchField<scalar>::typeName,
+            true            // parallel sync'ed addition
+        );
+    }
+    else
+    {
+        Info<< "Patch '" << patchName
+            << "' already exists.  Only "
+            << "moving patch faces - type will remain the same"
+            << endl;
+    }
+
+    return pbm.findPatchID(patchName);
+}
+
+
 void modifyOrAddFace
 (
     polyTopoChange& meshMod,
@@ -111,6 +162,185 @@ void modifyOrAddFace
 }
 
 
+// Create faces for fZone faces. Usually newMasterPatches, newSlavePatches
+// only size one but can be more for duplicate baffle sets
+void createFaces
+(
+    const bool internalFacesOnly,
+    const fvMesh& mesh,
+    const faceZone& fZone,
+    const labelList& newMasterPatches,
+    const labelList& newSlavePatches,
+    polyTopoChange& meshMod,
+    PackedBoolList& modifiedFace,
+    label& nModified
+)
+{
+    const polyBoundaryMesh& pbm = mesh.boundaryMesh();
+
+    forAll(newMasterPatches, i)
+    {
+        // Pass 1. Do selected side of zone
+        // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+        for (label faceI = 0; faceI < mesh.nInternalFaces(); faceI++)
+        {
+            label zoneFaceI = fZone.whichFace(faceI);
+
+            if (zoneFaceI != -1)
+            {
+                if (!fZone.flipMap()[zoneFaceI])
+                {
+                    // Use owner side of face
+                    modifyOrAddFace
+                    (
+                        meshMod,
+                        mesh.faces()[faceI],    // modified face
+                        faceI,                  // label of face
+                        mesh.faceOwner()[faceI],// owner
+                        false,                  // face flip
+                        newMasterPatches[i],    // patch for face
+                        fZone.index(),          // zone for face
+                        false,                  // face flip in zone
+                        modifiedFace            // modify or add status
+                    );
+                }
+                else
+                {
+                    // Use neighbour side of face
+                    modifyOrAddFace
+                    (
+                        meshMod,
+                        mesh.faces()[faceI].reverseFace(),  // modified face
+                        faceI,                      // label of face
+                        mesh.faceNeighbour()[faceI],// owner
+                        true,                       // face flip
+                        newMasterPatches[i],        // patch for face
+                        fZone.index(),              // zone for face
+                        true,                       // face flip in zone
+                        modifiedFace                // modify or add status
+                    );
+                }
+
+                nModified++;
+            }
+        }
+
+
+        // Pass 2. Do other side of zone
+        // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+        for (label faceI = 0; faceI < mesh.nInternalFaces(); faceI++)
+        {
+            label zoneFaceI = fZone.whichFace(faceI);
+
+            if (zoneFaceI != -1)
+            {
+                if (!fZone.flipMap()[zoneFaceI])
+                {
+                    // Use neighbour side of face
+                    modifyOrAddFace
+                    (
+                        meshMod,
+                        mesh.faces()[faceI].reverseFace(),  // modified face
+                        faceI,                          // label of face
+                        mesh.faceNeighbour()[faceI],    // owner
+                        true,                           // face flip
+                        newSlavePatches[i],             // patch for face
+                        fZone.index(),                  // zone for face
+                        true,                           // face flip in zone
+                        modifiedFace                    // modify or add
+                    );
+                }
+                else
+                {
+                    // Use owner side of face
+                    modifyOrAddFace
+                    (
+                        meshMod,
+                        mesh.faces()[faceI],    // modified face
+                        faceI,                  // label of face
+                        mesh.faceOwner()[faceI],// owner
+                        false,                  // face flip
+                        newSlavePatches[i],     // patch for face
+                        fZone.index(),          // zone for face
+                        false,                  // face flip in zone
+                        modifiedFace            // modify or add status
+                    );
+                }
+            }
+        }
+
+
+        // Modify any boundary faces
+        // ~~~~~~~~~~~~~~~~~~~~~~~~~
+
+        // Normal boundary:
+        // - move to new patch. Might already be back-to-back baffle
+        // you want to add cyclic to. Do warn though.
+        //
+        // Processor boundary:
+        // - do not move to cyclic
+        // - add normal patches though.
+
+        // For warning once per patch.
+        labelHashSet patchWarned;
+
+        forAll(pbm, patchI)
+        {
+            const polyPatch& pp = pbm[patchI];
+
+            label newPatchI = newMasterPatches[i];
+
+            if (pp.coupled() && pbm[newPatchI].coupled())
+            {
+                // Do not allow coupled faces to be moved to different
+                // coupled patches.
+            }
+            else if (pp.coupled() || !internalFacesOnly)
+            {
+                forAll(pp, i)
+                {
+                    label faceI = pp.start()+i;
+
+                    label zoneFaceI = fZone.whichFace(faceI);
+
+                    if (zoneFaceI != -1)
+                    {
+                        if (patchWarned.insert(patchI))
+                        {
+                            WarningIn("createFaces(..)")
+                                << "Found boundary face (in patch "
+                                << pp.name()
+                                << ") in faceZone " << fZone.name()
+                                << " to convert to baffle patch "
+                                << pbm[newPatchI].name()
+                                << endl
+                                << "    Run with -internalFacesOnly option"
+                                << " if you don't wish to convert"
+                                << " boundary faces." << endl;
+                        }
+
+                        modifyOrAddFace
+                        (
+                            meshMod,
+                            mesh.faces()[faceI],        // modified face
+                            faceI,                      // label of face
+                            mesh.faceOwner()[faceI],    // owner
+                            false,                      // face flip
+                            newPatchI,                  // patch for face
+                            fZone.index(),              // zone for face
+                            fZone.flipMap()[zoneFaceI], // face flip in zone
+                            modifiedFace                // modify or add
+                        );
+                        nModified++;
+                    }
+                }
+            }
+        }
+    }
+}
+
 
 int main(int argc, char *argv[])
 {
@@ -220,8 +450,8 @@ int main(int argc, char *argv[])
 
 
 
-    // Creating (if necessary) baffles
-    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+    // Creating (if necessary) faceZones
+    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
     forAll(selectors, selectorI)
     {
@@ -308,21 +538,28 @@ int main(int argc, char *argv[])
     {
         forAll(selectors, selectorI)
         {
-            const dictionary& patchSources
-            (
-                selectors[selectorI].dict().subDict("patches")
-            );
-            forAllConstIter(dictionary, patchSources, iter)
+            const dictionary& dict = selectors[selectorI].dict();
+
+            if (dict.found("patches"))
             {
-                //const word& patchName = iter().keyword();
-                const word patchName(iter().dict()["name"]);
-                bafflePatches.insert(patchName);
+                const dictionary& patchSources = dict.subDict("patches");
+                forAllConstIter(dictionary, patchSources, iter)
+                {
+                    const word patchName(iter().dict()["name"]);
+                    bafflePatches.insert(patchName);
+                }
+            }
+            else
+            {
+                const word masterName = selectors[selectorI].name() + "_master";
+                bafflePatches.insert(masterName);
+                const word slaveName = selectors[selectorI].name() + "_slave";
+                bafflePatches.insert(slaveName);
             }
         }
     }
 
 
-
     // Create baffles
     // ~~~~~~~~~~~~~~
     // Is done in multiple steps
@@ -344,56 +581,52 @@ int main(int argc, char *argv[])
         const polyBoundaryMesh& pbm = mesh.boundaryMesh();
         forAll(selectors, selectorI)
         {
-            const dictionary& patchSources
-            (
-                selectors[selectorI].dict().subDict("patches")
-            );
-            forAllConstIter(dictionary, patchSources, iter)
-            {
-                //const word& patchName = iter().keyword();
-                const word patchName(iter().dict()["name"]);
-
-                label destPatchI = pbm.findPatchID(patchName);
+            const dictionary& dict = selectors[selectorI].dict();
+            const word& groupName = selectors[selectorI].name();
 
-                if (destPatchI == -1)
+            if (dict.found("patches"))
+            {
+                const dictionary& patchSources = dict.subDict("patches");
+                forAllConstIter(dictionary, patchSources, iter)
                 {
-                    dictionary patchDict = iter().dict();
-                    patchDict.set("nFaces", 0);
-                    patchDict.set("startFace", 0);
+                    const word patchName(iter().dict()["name"]);
 
-                    Info<< "Adding new patch " << patchName
-                        << " from " << patchDict << endl;
+                    if (pbm.findPatchID(patchName) == -1)
+                    {
+                        dictionary patchDict = iter().dict();
+                        patchDict.set("nFaces", 0);
+                        patchDict.set("startFace", 0);
 
-                    autoPtr<polyPatch> ppPtr
-                    (
-                        polyPatch::New
-                        (
-                            patchName,
-                            patchDict,
-                            0,
-                            pbm
-                        )
-                    );
+                        // Note: do not set coupleGroup if constructed from
+                        //       baffles so you have freedom specifying it
+                        //       yourself.
+                        //patchDict.set("coupleGroup", groupName);
 
-                    // Add patch, create calculated everywhere
-                    fvMeshTools::addPatch
-                    (
-                        mesh,
-                        ppPtr(),
-                        dictionary(),   // do not set specialised patchFields
-                        calculatedFvPatchField<scalar>::typeName,
-                        true            // parallel sync'ed addition
-                    );
-
-                    //addedPatches.insert(patchName);
-                }
-                else
-                {
-                    Info<< "Patch '" << patchName << "' already exists.  Only "
-                        << "moving patch faces - type will remain the same"
-                        << endl;
+                        addPatch(mesh, patchName, groupName, patchDict);
+                    }
+                    else
+                    {
+                        Info<< "Patch '" << patchName
+                            << "' already exists.  Only "
+                            << "moving patch faces - type will remain the same"
+                            << endl;
+                    }
                 }
             }
+            else
+            {
+                const dictionary& patchSource = dict.subDict("patchPairs");
+                const word masterName = groupName + "_master";
+                const word slaveName = groupName + "_slave";
+
+                dictionary patchDict = patchSource;
+                patchDict.set("nFaces", 0);
+                patchDict.set("startFace", 0);
+                patchDict.set("coupleGroup", groupName);
+
+                addPatch(mesh, masterName, groupName, patchDict);
+                addPatch(mesh, slaveName, groupName, patchDict);
+            }
         }
     }
 
@@ -428,195 +661,53 @@ int main(int argc, char *argv[])
         label zoneID = mesh.faceZones().findZoneID(name);
         const faceZone& fZone = mesh.faceZones()[zoneID];
 
-        const dictionary& patchSources
-        (
-            selectors[selectorI].dict().subDict("patches")
-        );
-
-        DynamicList<label> newMasterPatches(patchSources.size());
-        DynamicList<label> newSlavePatches(patchSources.size());
+        const dictionary& dict = selectors[selectorI].dict();
 
-        bool master = true;
+        DynamicList<label> newMasterPatches;
+        DynamicList<label> newSlavePatches;
 
-        forAllConstIter(dictionary, patchSources, iter)
+        if (dict.found("patches"))
         {
-            //const word& patchName = iter().keyword();
-            const word patchName(iter().dict()["name"]);
-            label patchI = pbm.findPatchID(patchName);
-            if (master)
-            {
-                newMasterPatches.append(patchI);
-            }
-            else
-            {
-                newSlavePatches.append(patchI);
-            }
-            master = !master;
-        }
-
+            const dictionary& patchSources = dict.subDict("patches");
 
-
-        forAll(newMasterPatches, i)
-        {
-            // Pass 1. Do selected side of zone
-            // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-            for (label faceI = 0; faceI < mesh.nInternalFaces(); faceI++)
+            bool master = true;
+            forAllConstIter(dictionary, patchSources, iter)
             {
-                label zoneFaceI = fZone.whichFace(faceI);
-
-                if (zoneFaceI != -1)
+                const word patchName(iter().dict()["name"]);
+                label patchI = pbm.findPatchID(patchName);
+                if (master)
                 {
-                    if (!fZone.flipMap()[zoneFaceI])
-                    {
-                        // Use owner side of face
-                        modifyOrAddFace
-                        (
-                            meshMod,
-                            mesh.faces()[faceI],    // modified face
-                            faceI,                  // label of face
-                            mesh.faceOwner()[faceI],// owner
-                            false,                  // face flip
-                            newMasterPatches[i],    // patch for face
-                            fZone.index(),          // zone for face
-                            false,                  // face flip in zone
-                            modifiedFace            // modify or add status
-                        );
-                    }
-                    else
-                    {
-                        // Use neighbour side of face
-                        modifyOrAddFace
-                        (
-                            meshMod,
-                            mesh.faces()[faceI].reverseFace(),  // modified face
-                            faceI,                      // label of face
-                            mesh.faceNeighbour()[faceI],// owner
-                            true,                       // face flip
-                            newMasterPatches[i],        // patch for face
-                            fZone.index(),              // zone for face
-                            true,                       // face flip in zone
-                            modifiedFace                // modify or add status
-                        );
-                    }
-
-                    nModified++;
+                    newMasterPatches.append(patchI);
                 }
-            }
-
-
-            // Pass 2. Do other side of zone
-            // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-            for (label faceI = 0; faceI < mesh.nInternalFaces(); faceI++)
-            {
-                label zoneFaceI = fZone.whichFace(faceI);
-
-                if (zoneFaceI != -1)
+                else
                 {
-                    if (!fZone.flipMap()[zoneFaceI])
-                    {
-                        // Use neighbour side of face
-                        modifyOrAddFace
-                        (
-                            meshMod,
-                            mesh.faces()[faceI].reverseFace(),  // modified face
-                            faceI,                          // label of face
-                            mesh.faceNeighbour()[faceI],    // owner
-                            true,                           // face flip
-                            newSlavePatches[i],             // patch for face
-                            fZone.index(),                  // zone for face
-                            true,                           // face flip in zone
-                            modifiedFace                    // modify or add
-                        );
-                    }
-                    else
-                    {
-                        // Use owner side of face
-                        modifyOrAddFace
-                        (
-                            meshMod,
-                            mesh.faces()[faceI],    // modified face
-                            faceI,                  // label of face
-                            mesh.faceOwner()[faceI],// owner
-                            false,                  // face flip
-                            newSlavePatches[i],     // patch for face
-                            fZone.index(),          // zone for face
-                            false,                  // face flip in zone
-                            modifiedFace            // modify or add status
-                        );
-                    }
+                    newSlavePatches.append(patchI);
                 }
+                master = !master;
             }
+        }
+        else
+        {
+            const word masterName = selectors[selectorI].name() + "_master";
+            newMasterPatches.append(pbm.findPatchID(masterName));
 
+            const word slaveName = selectors[selectorI].name() + "_slave";
+            newSlavePatches.append(pbm.findPatchID(slaveName));
+        }
 
-            // Modify any boundary faces
-            // ~~~~~~~~~~~~~~~~~~~~~~~~~
-
-            // Normal boundary:
-            // - move to new patch. Might already be back-to-back baffle
-            // you want to add cyclic to. Do warn though.
-            //
-            // Processor boundary:
-            // - do not move to cyclic
-            // - add normal patches though.
-
-            // For warning once per patch.
-            labelHashSet patchWarned;
-
-            forAll(pbm, patchI)
-            {
-                const polyPatch& pp = pbm[patchI];
-
-                label newPatchI = newMasterPatches[i];
-
-                if (pp.coupled() && pbm[newPatchI].coupled())
-                {
-                    // Do not allow coupled faces to be moved to different
-                    // coupled patches.
-                }
-                else if (pp.coupled() || !internalFacesOnly)
-                {
-                    forAll(pp, i)
-                    {
-                        label faceI = pp.start()+i;
 
-                        label zoneFaceI = fZone.whichFace(faceI);
 
-                        if (zoneFaceI != -1)
-                        {
-                            if (patchWarned.insert(patchI))
-                            {
-                                WarningIn(args.executable())
-                                    << "Found boundary face (in patch "
-                                    << pp.name()
-                                    << ") in faceZone " << fZone.name()
-                                    << " to convert to baffle patch "
-                                    << pbm[newPatchI].name()
-                                    << endl
-                                    << "    Run with -internalFacesOnly option"
-                                    << " if you don't wish to convert"
-                                    << " boundary faces." << endl;
-                            }
-
-                            modifyOrAddFace
-                            (
-                                meshMod,
-                                mesh.faces()[faceI],        // modified face
-                                faceI,                      // label of face
-                                mesh.faceOwner()[faceI],    // owner
-                                false,                      // face flip
-                                newPatchI,                  // patch for face
-                                fZone.index(),              // zone for face
-                                fZone.flipMap()[zoneFaceI], // face flip in zone
-                                modifiedFace                // modify or add
-                            );
-                            nModified++;
-                        }
-                    }
-                }
-            }
-        }
+        createFaces
+        (
+            internalFacesOnly,
+            mesh,
+            fZone,
+            newMasterPatches,
+            newSlavePatches,
+            meshMod,
+            modifiedFace,
+            nModified
+        );
     }
 
 
@@ -672,29 +763,64 @@ int main(int argc, char *argv[])
         const polyBoundaryMesh& pbm = mesh.boundaryMesh();
         forAll(selectors, selectorI)
         {
-            const dictionary& patchSources
-            (
-                selectors[selectorI].dict().subDict("patches")
-            );
-            forAllConstIter(dictionary, patchSources, iter)
+            const dictionary& dict = selectors[selectorI].dict();
+            if (dict.found("patches"))
             {
-                //const word& patchName = iter().keyword();
-                const word patchName(iter().dict()["name"]);
-                label patchI = pbm.findPatchID(patchName);
+                const dictionary& patchSources = dict.subDict("patches");
 
-                if (iter().dict().found("patchFields"))
+                forAllConstIter(dictionary, patchSources, iter)
                 {
-                    const dictionary& patchFieldsDict = iter().dict().subDict
+                    const word patchName(iter().dict()["name"]);
+                    label patchI = pbm.findPatchID(patchName);
+
+                    if (iter().dict().found("patchFields"))
+                    {
+                        const dictionary& patchFieldsDict =
+                            iter().dict().subDict
+                            (
+                                "patchFields"
+                            );
+
+                        fvMeshTools::setPatchFields
+                        (
+                            mesh,
+                            patchI,
+                            patchFieldsDict
+                        );
+                    }
+                }
+            }
+            else
+            {
+                const dictionary& patchSource = dict.subDict("patchPairs");
+                const word& groupName = selectors[selectorI].name();
+
+                if (patchSource.found("patchFields"))
+                {
+                    dictionary patchFieldsDict = patchSource.subDict
                     (
                         "patchFields"
                     );
+                    // Add coupleGroup to all entries
+                    forAllIter(dictionary, patchFieldsDict, iter)
+                    {
+                        if (iter().isDict())
+                        {
+                            dictionary& dict = iter().dict();
+                            dict.set("coupleGroup", groupName);
+                        }
+                    }
 
-                    fvMeshTools::setPatchFields
-                    (
-                        mesh,
-                        patchI,
-                        patchFieldsDict
-                    );
+                    const labelList& patchIDs = pbm.groupPatchIDs()[groupName];
+                    forAll(patchIDs, i)
+                    {
+                        fvMeshTools::setPatchFields
+                        (
+                            mesh,
+                            patchIDs[i],
+                            patchFieldsDict
+                        );
+                    }
                 }
             }
         }
diff --git a/applications/utilities/mesh/manipulation/createBaffles/createBafflesDict b/applications/utilities/mesh/manipulation/createBaffles/createBafflesDict
index ef2eb96227f804d67ccc9b686455c4e6833b442e..27ff9d287e27e84e62c95be51d4bcf266642e0ba 100644
--- a/applications/utilities/mesh/manipulation/createBaffles/createBafflesDict
+++ b/applications/utilities/mesh/manipulation/createBaffles/createBafflesDict
@@ -40,123 +40,47 @@ internalFacesOnly true;
 // Baffles to create.
 baffles
 {
-    baffleFaces
+    baffle1
     {
-        //- Use predefined faceZone to select faces and orientation.
-        type        faceZone;
-        zoneName    baffleFaces;
-
-
+        //- Use surface to select faces and orientation.
+        type        searchableSurface;
+        surface     triSurfaceMesh;
+        name        baffle1D.stl;
         //- Optional flip
         //flip        false;
 
-        patches
-        {
-            master
-            {
-                //- Master side patch
-                name            baffles;
-                type            wall;
 
-                //- Optional override of added patchfields. If not specified
-                //  any added patchfields are of type calculated.
-                patchFields
-                {
-                    epsilon
-                    {
-                        type            epsilonWallFunction;
-                        Cmu             0.09;
-                        kappa           0.41;
-                        E               9.8;
-                        value           uniform 0;
-                    }
-                    k
-                    {
-                        type            kqRWallFunction;
-                        value           uniform 0;
-                    }
-                    nut
-                    {
-                        type            nutkWallFunction;
-                        Cmu             0.09;
-                        kappa           0.41;
-                        E               9.8;
-                        value           uniform 0;
-                    }
-                    nuTilda
-                    {
-                        type            zeroGradient;
-                    }
-                    p
-                    {
-                        type            zeroGradient;
-                    }
-                    U
-                    {
-                        type            fixedValue;
-                        value           uniform (0 0 0);
-                    }
-                }
-            }
-            slave
+        // Generate patchGroup baffle1 with two patches:
+        //  - baffle1_master
+        //  - baffle1_slave
+        patchPairs
+        {
+            type            wall;
+            //- Optional override of added patchfields. If not specified
+            //  any added patchfields are of type calculated.
+            patchFields
             {
-                //- Slave side patch
-                name            baffles;
-                type            wall;
-
-                patchFields
+                U
                 {
-                    epsilon
-                    {
-                        type            epsilonWallFunction;
-                        Cmu             0.09;
-                        kappa           0.41;
-                        E               9.8;
-                        value           uniform 0;
-                    }
-                    k
-                    {
-                        type            kqRWallFunction;
-                        value           uniform 0;
-                    }
-                    nut
-                    {
-                        type            nutkWallFunction;
-                        Cmu             0.09;
-                        kappa           0.41;
-                        E               9.8;
-                        value           uniform 0;
-                    }
-                    nuTilda
-                    {
-                        type            zeroGradient;
-                    }
-                    p
-                    {
-                        type            zeroGradient;
-                    }
-                    U
-                    {
-                        type            fixedValue;
-                        value           uniform (0 0 0);
-                    }
+                    type            fixedValue;
+                    value           uniform (0 0 0);
                 }
             }
         }
     }
 
 
-
     cyclicFaces
     {
         //- Select faces and orientation through a searchableSurface
         type        searchableSurface;
         surface     searchablePlate;
-        //name sphere.stl;  // name if surface=triSurfaceMesh
 
         origin      (0.099 -0.006 0.004);
         span        (0 0.012 0.012);
 
+
+        // Generate patches explicitly
         patches
         {
             master
diff --git a/applications/utilities/postProcessing/sampling/sample/sampleDict b/applications/utilities/postProcessing/sampling/sample/sampleDict
index 60e1d7d0ee232b2fc1ad2be493a563d6a7c11e70..3962e633bce4e78fcb564eaa552aea7eef8fac0f 100644
--- a/applications/utilities/postProcessing/sampling/sample/sampleDict
+++ b/applications/utilities/postProcessing/sampling/sample/sampleDict
@@ -303,7 +303,9 @@ surfaces
         // Sampling on triSurface
         type        sampledTriSurfaceMesh;
         surface     integrationPlane.stl;
-        source      boundaryFaces;  // sample cells or boundaryFaces
+        source      boundaryFaces;  // What to sample: cells (nearest cell)
+                                    // insideCells (only triangles inside cell)
+                                    // boundaryFaces (nearest boundary face)
         interpolate true;
     }
 );
diff --git a/applications/utilities/preProcessing/mapFieldsNew/mapFieldsDict b/applications/utilities/preProcessing/mapFieldsNew/mapFieldsDict
index 00a190cc77e4ee16f157198cee7af4e5ce19e8f1..65e33997d938c53ab2f1b2ff5e35a2961b0ec3ef 100644
--- a/applications/utilities/preProcessing/mapFieldsNew/mapFieldsDict
+++ b/applications/utilities/preProcessing/mapFieldsNew/mapFieldsDict
@@ -14,7 +14,13 @@ FoamFile
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-// List of pairs of source/target patches for mapping
+// Specify how to map patches. There are three different options:
+// - patch exists in the source case: specify mapping (patchMap)
+// - patch should be interpolated from internal values in source case
+//   (cuttingPatches)
+// - patch should not be mapped. Default if not in patchMap or cuttingPatches
+
+// List of pairs of target/source patches for mapping
 patchMap
 (
     lid movingWall
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/OpenFOAM/meshes/Identifiers/patch/coupleGroupIdentifier.C b/src/OpenFOAM/meshes/Identifiers/patch/coupleGroupIdentifier.C
new file mode 100644
index 0000000000000000000000000000000000000000..e520c539616bec12be3f1327b3ba18e6a860f398
--- /dev/null
+++ b/src/OpenFOAM/meshes/Identifiers/patch/coupleGroupIdentifier.C
@@ -0,0 +1,260 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2013 OpenFOAM Foundation
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+\*---------------------------------------------------------------------------*/
+
+#include "coupleGroupIdentifier.H"
+#include "polyMesh.H"
+#include "Time.H"
+
+// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
+
+Foam::label Foam::coupleGroupIdentifier::findOtherPatchID
+(
+    const polyMesh& mesh,
+    const polyPatch& thisPatch
+) const
+{
+    const polyBoundaryMesh& pbm = mesh.boundaryMesh();
+
+    if (!valid())
+    {
+        FatalErrorIn
+        (
+            "coupleGroupIdentifier::findOtherPatchID(const polyPatch&) const"
+        )   << "Invalid coupleGroup patch group"
+            << " on patch " << thisPatch.name()
+            << " in region " << pbm.mesh().name()
+            << exit(FatalError);
+    }
+
+    HashTable<labelList, word>::const_iterator fnd =
+        pbm.groupPatchIDs().find(name());
+
+    if (fnd == pbm.groupPatchIDs().end())
+    {
+        if (&mesh == &thisPatch.boundaryMesh().mesh())
+        {
+            // thisPatch should be in patchGroup
+            FatalErrorIn
+            (
+                "coupleGroupIdentifier::findOtherPatchID"
+                "(const polyMesh&, const polyPatch&) const"
+            )   << "Patch " << thisPatch.name()
+                << " should be in patchGroup " << name()
+                << " in region " << pbm.mesh().name()
+                << exit(FatalError);
+        }
+
+        return -1;
+    }
+
+    // Mesh has patch group
+    const labelList& patchIDs = fnd();
+
+    if (&mesh == &thisPatch.boundaryMesh().mesh())
+    {
+        if (patchIDs.size() > 2 || patchIDs.size() == 0)
+        {
+            FatalErrorIn
+            (
+                "coupleGroupIdentifier::findOtherPatchID"
+                "(const polyMesh&, const polyPatch&) const"
+            )   << "Couple patchGroup " << name()
+                << " with contents " << patchIDs
+                << " not of size < 2"
+                << " on patch " << thisPatch.name()
+                << " region " << thisPatch.boundaryMesh().mesh().name()
+                << exit(FatalError);
+
+            return -1;
+        }
+
+        label index = findIndex(patchIDs, thisPatch.index());
+
+        if (index == -1)
+        {
+            FatalErrorIn
+            (
+                "coupleGroupIdentifier::findOtherPatchID"
+                "(const polyMesh&, const polyPatch&) const"
+            )   << "Couple patchGroup " << name()
+                << " with contents " << patchIDs
+                << " does not contain patch " << thisPatch.name()
+                << " in region " << pbm.mesh().name()
+                << exit(FatalError);
+
+            return -1;
+        }
+
+
+        if (patchIDs.size() == 2)
+        {
+            // Return the other patch
+            return patchIDs[1-index];
+        }
+        else    // size == 1
+        {
+            return -1;
+        }
+    }
+    else
+    {
+        if (patchIDs.size() != 1)
+        {
+            FatalErrorIn
+            (
+                "coupleGroupIdentifier::findOtherPatchID"
+                "(const polyMesh&, const polyPatch&) const"
+            )   << "Couple patchGroup " << name()
+                << " with contents " << patchIDs
+                << " in region " << mesh.name()
+                << " should only contain a single patch"
+                << " when matching patch " << thisPatch.name()
+                << " in region " << pbm.mesh().name()
+                << exit(FatalError);
+        }
+
+        return patchIDs[0];
+    }
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::coupleGroupIdentifier::coupleGroupIdentifier()
+:
+    name_()
+{}
+
+
+Foam::coupleGroupIdentifier::coupleGroupIdentifier(const word& name)
+:
+    name_(name)
+{}
+
+
+Foam::coupleGroupIdentifier::coupleGroupIdentifier(const dictionary& dict)
+:
+    name_(dict.lookupOrDefault<word>("coupleGroup", ""))
+{}
+
+
+// * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * * //
+
+Foam::label Foam::coupleGroupIdentifier::findOtherPatchID
+(
+    const polyPatch& thisPatch
+) const
+{
+    const polyBoundaryMesh& pbm = thisPatch.boundaryMesh();
+
+    return findOtherPatchID(pbm.mesh(), thisPatch);
+}
+
+
+Foam::label Foam::coupleGroupIdentifier::findOtherPatchID
+(
+    const polyPatch& thisPatch,
+    word& otherRegion
+) const
+{
+    const polyBoundaryMesh& pbm = thisPatch.boundaryMesh();
+    const polyMesh& thisMesh = pbm.mesh();
+    const Time& runTime = thisMesh.time();
+
+
+    // Loop over all regions to find other patch in coupleGroup
+    HashTable<const polyMesh*> meshSet = runTime.lookupClass<polyMesh>();
+
+    label otherPatchID = -1;
+
+    forAllConstIter(HashTable<const polyMesh*>, meshSet, iter)
+    {
+        const polyMesh& mesh = *iter();
+
+        label patchID = findOtherPatchID(mesh, thisPatch);
+
+        if (patchID != -1)
+        {
+            if (otherPatchID != -1)
+            {
+                FatalErrorIn
+                (
+                    "coupleGroupIdentifier::findOtherPatchID"
+                    "(const polyPatch&, word&) const"
+                )   << "Couple patchGroup " << name()
+                    << " should be present on only two patches"
+                    << " in any of the meshes in " << meshSet.sortedToc()
+                    << endl
+                    << "    It seems to be present on patch "
+                    << thisPatch.name()
+                    << " in region " << thisMesh.name()
+                    << ", on patch " << otherPatchID
+                    << " in region " << otherRegion
+                    << " and on patch " << patchID
+                    << " in region " << mesh.name()
+                    << exit(FatalError);
+            }
+            otherPatchID = patchID;
+            otherRegion = mesh.name();
+        }
+    }
+
+    if (otherPatchID == -1)
+    {
+        FatalErrorIn
+        (
+            "coupleGroupIdentifier::findOtherPatchID"
+            "(const polyPatch&, word&) const"
+        )   << "Couple patchGroup " << name()
+            << " not found in any of the other meshes " << meshSet.sortedToc()
+            << " on patch " << thisPatch.name()
+            << " region " << thisMesh.name()
+            << exit(FatalError);
+    }
+
+    return otherPatchID;
+}
+
+
+void Foam::coupleGroupIdentifier::write(Ostream& os) const
+{
+    if (valid())
+    {
+        os.writeKeyword("coupleGroup") << name() << token::END_STATEMENT << nl;
+    }
+}
+
+
+// * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * * //
+
+Foam::Ostream& Foam::operator<<(Ostream& os, const coupleGroupIdentifier& p)
+{
+    p.write(os);
+    os.check("Ostream& operator<<(Ostream& os, const coupleGroupIdentifier& p");
+    return os;
+}
+
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/meshes/Identifiers/patch/coupleGroupIdentifier.H b/src/OpenFOAM/meshes/Identifiers/patch/coupleGroupIdentifier.H
new file mode 100644
index 0000000000000000000000000000000000000000..895dcf53ffabc0fa5fa5cd81dc17f091ce9027a8
--- /dev/null
+++ b/src/OpenFOAM/meshes/Identifiers/patch/coupleGroupIdentifier.H
@@ -0,0 +1,128 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2013 OpenFOAM Foundation
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+Class
+    Foam::coupleGroupIdentifier
+
+Description
+    Encapsulates using patchGroups to specify coupled patch
+
+SourceFiles
+    coupleGroupIdentifierI.H
+    coupleGroupIdentifier.C
+    coupleGroupIdentifierIO.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef coupleGroupIdentifier_H
+#define coupleGroupIdentifier_H
+
+#include "word.H"
+#include "label.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+// Forward declaration of classes
+class dictionary;
+class polyMesh;
+class polyPatch;
+class Ostream;
+
+// Forward declaration of friend functions and operators
+class coupleGroupIdentifier;
+Ostream& operator<<(Ostream&, const coupleGroupIdentifier&);
+
+
+/*---------------------------------------------------------------------------*\
+                         Class coupleGroupIdentifier Declaration
+\*---------------------------------------------------------------------------*/
+
+class coupleGroupIdentifier
+{
+    // Private data
+
+        //- Name of patchGroup
+        word name_;
+
+
+    // Private Member Functions
+
+        //- Find other patch in specified mesh. Returns index of patch or -1.
+        label findOtherPatchID(const polyMesh&, const polyPatch&) const;
+
+
+public:
+
+    // Constructors
+
+        //- Construct null
+        coupleGroupIdentifier();
+
+        //- Construct from components
+        coupleGroupIdentifier(const word& patchGroupName);
+
+        //- Construct from dictionary
+        coupleGroupIdentifier(const dictionary&);
+
+
+    // Member Functions
+
+        //- Name of patchGroup
+        inline const word& name() const;
+
+        //- Is a valid patchGroup
+        inline bool valid() const;
+
+        //- Find other patch in same region. Returns index of patch or -1.
+        label findOtherPatchID(const polyPatch&) const;
+
+        //- Find other patch and region. Returns index of patch and sets
+        //  otherRegion to name of region. Fatal error if patch not found
+        label findOtherPatchID(const polyPatch&, word&) const;
+
+        //- Write the data as a dictionary
+        void write(Ostream&) const;
+
+
+    // IOstream Operators
+
+        friend Ostream& operator<<(Ostream&, const coupleGroupIdentifier&);
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#include "coupleGroupIdentifierI.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/meshes/Identifiers/patch/coupleGroupIdentifierI.H b/src/OpenFOAM/meshes/Identifiers/patch/coupleGroupIdentifierI.H
new file mode 100644
index 0000000000000000000000000000000000000000..ee6503514c190fb639a267e1a0ee9c928e72f062
--- /dev/null
+++ b/src/OpenFOAM/meshes/Identifiers/patch/coupleGroupIdentifierI.H
@@ -0,0 +1,42 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2013 OpenFOAM Foundation
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+\*---------------------------------------------------------------------------*/
+
+#include "coupleGroupIdentifier.H"
+
+// * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * * //
+
+const Foam::word& Foam::coupleGroupIdentifier::name() const
+{
+    return name_;
+}
+
+
+bool Foam::coupleGroupIdentifier::valid() const
+{
+    return !name_.empty();
+}
+
+
+// ************************************************************************* //
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/lagrangian/intermediate/clouds/Templates/KinematicCloud/KinematicCloud.C b/src/lagrangian/intermediate/clouds/Templates/KinematicCloud/KinematicCloud.C
index dc42e0f9db6267e8a75dff92eed00ce8706a44e8..42cced7658919002b4468a82a60d115e04ac1899 100644
--- a/src/lagrangian/intermediate/clouds/Templates/KinematicCloud/KinematicCloud.C
+++ b/src/lagrangian/intermediate/clouds/Templates/KinematicCloud/KinematicCloud.C
@@ -321,6 +321,7 @@ Foam::KinematicCloud<CloudType>::KinematicCloud
       : -1
     ),
     cellOccupancyPtr_(),
+    cellLengthScale_(cbrt(mesh_.V())),
     rho_(rho),
     U_(U),
     mu_(mu),
@@ -421,6 +422,7 @@ Foam::KinematicCloud<CloudType>::KinematicCloud
     subModelProperties_(c.subModelProperties_),
     rndGen_(c.rndGen_, true),
     cellOccupancyPtr_(NULL),
+    cellLengthScale_(c.cellLengthScale_),
     rho_(c.rho_),
     U_(c.U_),
     mu_(c.mu_),
@@ -511,6 +513,7 @@ Foam::KinematicCloud<CloudType>::KinematicCloud
     subModelProperties_(dictionary::null),
     rndGen_(0, 0),
     cellOccupancyPtr_(NULL),
+    cellLengthScale_(c.cellLengthScale_),
     rho_(c.rho_),
     U_(c.U_),
     mu_(c.mu_),
@@ -842,7 +845,9 @@ void Foam::KinematicCloud<CloudType>::patchData
 template<class CloudType>
 void Foam::KinematicCloud<CloudType>::updateMesh()
 {
+    updateCellOccupancy();
     injectors_.updateMesh();
+    cellLengthScale_ = cbrt(mesh_.V());
 }
 
 
diff --git a/src/lagrangian/intermediate/clouds/Templates/KinematicCloud/KinematicCloud.H b/src/lagrangian/intermediate/clouds/Templates/KinematicCloud/KinematicCloud.H
index e32a3bdf4ff4e4aa58cfebdce6c1fc4c385ac95a..9c2a75157b9f562aed954c1bba148b7f6ed5303b 100644
--- a/src/lagrangian/intermediate/clouds/Templates/KinematicCloud/KinematicCloud.H
+++ b/src/lagrangian/intermediate/clouds/Templates/KinematicCloud/KinematicCloud.H
@@ -165,6 +165,9 @@ protected:
         //- Cell occupancy information for each parcel, (demand driven)
         autoPtr<List<DynamicList<parcelType*> > > cellOccupancyPtr_;
 
+        //- Cell length scale
+        scalarField cellLengthScale_;
+
 
         // References to the carrier gas fields
 
@@ -368,6 +371,9 @@ public:
                 //  if particles are removed or created.
                 inline List<DynamicList<parcelType*> >& cellOccupancy();
 
+                //- Return the cell length scale
+                inline const scalarField& cellLengthScale() const;
+
 
             // References to the carrier gas fields
 
diff --git a/src/lagrangian/intermediate/clouds/Templates/KinematicCloud/KinematicCloudI.H b/src/lagrangian/intermediate/clouds/Templates/KinematicCloud/KinematicCloudI.H
index 1bbf47b41a553037757ef18001e7671d0864041f..ed0f74793f4cbbbbaae5ec393fef45ce001aedf7 100644
--- a/src/lagrangian/intermediate/clouds/Templates/KinematicCloud/KinematicCloudI.H
+++ b/src/lagrangian/intermediate/clouds/Templates/KinematicCloud/KinematicCloudI.H
@@ -517,6 +517,14 @@ Foam::KinematicCloud<CloudType>::cellOccupancy()
 }
 
 
+template<class CloudType>
+inline const Foam::scalarField&
+Foam::KinematicCloud<CloudType>::cellLengthScale() const
+{
+    return cellLengthScale_;
+}
+
+
 template<class CloudType>
 inline Foam::DimensionedField<Foam::vector, Foam::volMesh>&
 Foam::KinematicCloud<CloudType>::UTrans()
diff --git a/src/lagrangian/intermediate/parcels/Templates/KinematicParcel/KinematicParcel.C b/src/lagrangian/intermediate/parcels/Templates/KinematicParcel/KinematicParcel.C
index b8339628257adc84672f39d2a93bb95a7b7419c2..22e01b9a98ced336dbbfb5e0745ed8cc93034a69 100644
--- a/src/lagrangian/intermediate/parcels/Templates/KinematicParcel/KinematicParcel.C
+++ b/src/lagrangian/intermediate/parcels/Templates/KinematicParcel/KinematicParcel.C
@@ -265,7 +265,7 @@ bool Foam::KinematicParcel<ParcelType>::move
 
     const polyMesh& mesh = td.cloud().pMesh();
     const polyBoundaryMesh& pbMesh = mesh.boundaryMesh();
-    const scalarField& V = mesh.cellVolumes();
+    const scalarField& cellLengthScale = td.cloud().cellLengthScale();
     const scalar maxCo = td.cloud().solution().maxCo();
 
     scalar tEnd = (1.0 - p.stepFraction())*trackTime;
@@ -290,7 +290,7 @@ bool Foam::KinematicParcel<ParcelType>::move
         if (p.active() && moving && (magU > ROOTVSMALL))
         {
             const scalar d = dt*magU;
-            const scalar dCorr = min(d, maxCo*cbrt(V[cellI]));
+            const scalar dCorr = min(d, maxCo*cellLengthScale[cellI]);
             dt *=
                 dCorr/d
                *p.trackToFace(p.position() + dCorr*U_/magU, td);
diff --git a/src/lagrangian/intermediate/parcels/Templates/ReactingParcel/ReactingParcelI.H b/src/lagrangian/intermediate/parcels/Templates/ReactingParcel/ReactingParcelI.H
index d4bb6002c181404556ecd34225fca27861cd3e9f..243488140186f2965a9ee9368a136e80124902a4 100644
--- a/src/lagrangian/intermediate/parcels/Templates/ReactingParcel/ReactingParcelI.H
+++ b/src/lagrangian/intermediate/parcels/Templates/ReactingParcel/ReactingParcelI.H
@@ -55,7 +55,7 @@ inline Foam::ReactingParcel<ParcelType>::constantProperties::constantProperties
 :
     ParcelType::constantProperties(parentDict),
     pMin_(this->dict_, "pMin", 1000.0),
-    constantVolume_(this->dict_, "constantVolume")
+    constantVolume_(this->dict_, word("constantVolume"))
 {}
 
 
diff --git a/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/InflationInjection/InflationInjection.C b/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/InflationInjection/InflationInjection.C
index 3b732df8fd827d87a4a38d49a45ae2cccc05cdeb..31b746625d39daf61f58240a5e7890dd4ae400a9 100644
--- a/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/InflationInjection/InflationInjection.C
+++ b/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/InflationInjection/InflationInjection.C
@@ -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
@@ -213,8 +213,8 @@ Foam::label Foam::InflationInjection<CloudType>::parcelsToInject
 
     if ((time0 >= 0.0) && (time0 < duration_))
     {
-         volumeAccumulator_ +=
-             fraction_*flowRateProfile_.integrate(time0, time1);
+        volumeAccumulator_ +=
+            fraction_*flowRateProfile_.integrate(time0, time1);
     }
 
     labelHashSet cellCentresUsed;
diff --git a/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/InjectionModel/InjectionModel.C b/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/InjectionModel/InjectionModel.C
index 7d3ccf083ca569e3418093ea90c4cad3f3ed8eff..82080c417405b8c22c0205db1caea4c9d6148cfe 100644
--- a/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/InjectionModel/InjectionModel.C
+++ b/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/InjectionModel/InjectionModel.C
@@ -586,27 +586,25 @@ void Foam::InjectionModel<CloudType>::inject(TrackData& td)
                             pPtr->rho()
                         );
 
-                    const scalar mParcel0 = pPtr->nParticle()*pPtr->mass();
-
-                    if (!pPtr->move(td, dt))
-                    {
-                        massAdded += mParcel0;
-                        delete pPtr;
-                    }
-                    else
+                    if (pPtr->nParticle() >= 1.0)
                     {
-                        if (pPtr->nParticle() >= 1.0)
+                        parcelsAdded++;
+                        massAdded += pPtr->nParticle()*pPtr->mass();
+
+                        if (pPtr->move(td, dt))
                         {
                             td.cloud().addParticle(pPtr);
-                            massAdded += mParcel0;
-                            parcelsAdded++;
                         }
                         else
                         {
-                            delayedVolume += pPtr->nParticle()*pPtr->volume();
                             delete pPtr;
                         }
                     }
+                    else
+                    {
+                        delayedVolume += pPtr->nParticle()*pPtr->volume();
+                        delete pPtr;
+                    }
                 }
             }
         }
diff --git a/src/lagrangian/spray/parcels/Templates/SprayParcel/SprayParcel.C b/src/lagrangian/spray/parcels/Templates/SprayParcel/SprayParcel.C
index 15d5cb1b622d7a2fae0749131a7947b357d9530d..16af6adc2af4e2fe2235ba4b4507dda3b92d833a 100644
--- a/src/lagrangian/spray/parcels/Templates/SprayParcel/SprayParcel.C
+++ b/src/lagrangian/spray/parcels/Templates/SprayParcel/SprayParcel.C
@@ -93,13 +93,11 @@ void Foam::SprayParcel<ParcelType>::calc
     td.cloud().constProps().setTMax(TMax);
 
     // store the parcel properties
-    const scalarField& Y(this->Y());
-    scalarField X(composition.liquids().X(Y));
-
-    this->Cp() = composition.liquids().Cp(this->pc_, T0, X);
-    sigma_ = composition.liquids().sigma(this->pc_, T0, X);
-    scalar rho0 = composition.liquids().rho(this->pc_, T0, X);
+    this->Cp() = composition.liquids().Cp(pc0, T0, X0);
+    sigma_ = composition.liquids().sigma(pc0, T0, X0);
+    scalar rho0 = composition.liquids().rho(pc0, T0, X0);
     this->rho() = rho0;
+    mu_ = composition.liquids().mu(pc0, T0, X0);
 
     ParcelType::calc(td, dt, cellI);
 
@@ -113,11 +111,13 @@ void Foam::SprayParcel<ParcelType>::calc
 
         this->Cp() = composition.liquids().Cp(this->pc_, T1, X1);
 
-        sigma_ = composition.liquids().sigma(this->pc_, T1, X);
+        sigma_ = composition.liquids().sigma(this->pc_, T1, X1);
 
         scalar rho1 = composition.liquids().rho(this->pc_, T1, X1);
         this->rho() = rho1;
 
+        mu_ = composition.liquids().mu(this->pc_, T1, X1);
+
         scalar d1 = this->d()*cbrt(rho0/rho1);
         this->d() = d1;
 
@@ -360,10 +360,6 @@ void Foam::SprayParcel<ParcelType>::solveTABEq
     const scalar dt
 )
 {
-    typedef typename TrackData::cloudType::reactingCloudType reactingCloudType;
-    const CompositionModel<reactingCloudType>& composition =
-        td.cloud().composition();
-
     const scalar& TABCmu = td.cloud().breakup().TABCmu();
     const scalar& TABWeCrit = td.cloud().breakup().TABWeCrit();
     const scalar& TABComega = td.cloud().breakup().TABComega();
@@ -372,26 +368,19 @@ void Foam::SprayParcel<ParcelType>::solveTABEq
     scalar r2 = r*r;
     scalar r3 = r*r2;
 
-    const scalarField& Y(this->Y());
-    scalarField X(composition.liquids().X(Y));
-
-    scalar rho = composition.liquids().rho(this->pc(), this->T(), X);
-    scalar mu = composition.liquids().mu(this->pc(), this->T(), X);
-    scalar sigma = composition.liquids().sigma(this->pc(), this->T(), X);
-
     // inverse of characteristic viscous damping time
-    scalar rtd = 0.5*TABCmu*mu/(rho*r2);
+    scalar rtd = 0.5*TABCmu*mu_/(this->rho()*r2);
 
     // oscillation frequency (squared)
-    scalar omega2 = TABComega*sigma/(rho*r3) - rtd*rtd;
+    scalar omega2 = TABComega*sigma_/(this->rho()*r3) - rtd*rtd;
 
     if (omega2 > 0)
     {
         scalar omega = sqrt(omega2);
         scalar rhoc = this->rhoc();
-        scalar Wetmp = this->We(this->U(), r, rhoc, sigma)/TABWeCrit;
+        scalar We = this->We(this->U(), r, rhoc, sigma_)/TABWeCrit;
 
-        scalar y1 = this->y() - Wetmp;
+        scalar y1 = this->y() - We;
         scalar y2 = this->yDot()/omega;
 
         // update distortion parameters
@@ -400,7 +389,7 @@ void Foam::SprayParcel<ParcelType>::solveTABEq
         scalar e = exp(-rtd*dt);
         y2 = (this->yDot() + y1*rtd)/omega;
 
-        this->y() = Wetmp + e*(y1*c + y2*s);
+        this->y() = We + e*(y1*c + y2*s);
         if (this->y() < 0)
         {
             this->y() = 0.0;
@@ -408,7 +397,7 @@ void Foam::SprayParcel<ParcelType>::solveTABEq
         }
         else
         {
-            this->yDot() = (Wetmp - this->y())*rtd + e*omega*(y2*c - y1*s);
+            this->yDot() = (We - this->y())*rtd + e*omega*(y2*c - y1*s);
         }
     }
     else
diff --git a/src/lagrangian/spray/submodels/BreakupModel/ReitzDiwakar/ReitzDiwakar.C b/src/lagrangian/spray/submodels/BreakupModel/ReitzDiwakar/ReitzDiwakar.C
index 79b26186eb154f6f85b2e09d4194dd62a6e92fbf..504b681dc631f5482cfd819617cf46757ef997de 100644
--- a/src/lagrangian/spray/submodels/BreakupModel/ReitzDiwakar/ReitzDiwakar.C
+++ b/src/lagrangian/spray/submodels/BreakupModel/ReitzDiwakar/ReitzDiwakar.C
@@ -101,11 +101,9 @@ bool Foam::ReitzDiwakar<CloudType>::update
     scalar We = 0.5*rhoc*sqr(Urmag)*d/sigma;
     scalar Re = Urmag*d/nuc;
 
-    scalar sqRey = sqrt(Re);
-
     if (We > Cbag_)
     {
-        if (We > Cstrip_*sqRey)
+        if (We > Cstrip_*sqrt(Re))
         {
             scalar dStrip = sqr(2.0*Cstrip_*sigma)/(rhoc*pow3(Urmag)*muc);
             scalar tauStrip = Cs_*d*sqrt(rho/rhoc)/Urmag;
@@ -117,9 +115,7 @@ bool Foam::ReitzDiwakar<CloudType>::update
         else
         {
             scalar dBag = 2.0*Cbag_*sigma/(rhoc*sqr(Urmag));
-
             scalar tauBag = Cb_*d*sqrt(rho*d/sigma);
-
             scalar fraction = dt/tauBag;
 
             // new droplet diameter, implicit calculation
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/cellDist/wallPoint/wallPointI.H b/src/meshTools/cellDist/wallPoint/wallPointI.H
index 95f0f02cdb3372cb463efa529f276a691aad2f73..306a274984be67e220f86fd089fdd2cc934ef6ea 100644
--- a/src/meshTools/cellDist/wallPoint/wallPointI.H
+++ b/src/meshTools/cellDist/wallPoint/wallPointI.H
@@ -144,8 +144,7 @@ inline bool Foam::wallPoint::sameGeometry
     const wallPoint& w2,
     const scalar tol,
     TrackingData& td
-)
- const
+) const
 {
     scalar diff = mag(distSqr() - w2.distSqr());
 
diff --git a/src/meshTools/mappedPatches/mappedPolyPatch/mappedPatchBase.C b/src/meshTools/mappedPatches/mappedPolyPatch/mappedPatchBase.C
index 129445ef80d70eb12665e15b8aa23b8e9822cda4..93c05785bbf705e4d382c246314414e4e78f62e6 100644
--- a/src/meshTools/mappedPatches/mappedPolyPatch/mappedPatchBase.C
+++ b/src/meshTools/mappedPatches/mappedPolyPatch/mappedPatchBase.C
@@ -40,6 +40,7 @@ License
 #include "SubField.H"
 #include "triPointRef.H"
 #include "syncTools.H"
+#include "treeDataCell.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -202,7 +203,7 @@ void Foam::mappedPatchBase::findSamples
     {
         case NEARESTCELL:
         {
-            if (samplePatch_.size() && samplePatch_ != "none")
+            if (samplePatch().size() && samplePatch() != "none")
             {
                 FatalErrorIn
                 (
@@ -213,14 +214,13 @@ void Foam::mappedPatchBase::findSamples
             }
 
             //- Note: face-diagonal decomposition
-            const meshSearchMeshObject& meshSearchEngine =
-                meshSearchMeshObject::New(mesh);
+            const indexedOctree<Foam::treeDataCell>& tree = mesh.cellTree();
 
             forAll(samples, sampleI)
             {
                 const point& sample = samples[sampleI];
 
-                label cellI = meshSearchEngine.findCell(sample);
+                label cellI = tree.findInside(sample);
 
                 if (cellI == -1)
                 {
@@ -391,7 +391,7 @@ void Foam::mappedPatchBase::findSamples
 
         case NEARESTFACE:
         {
-            if (samplePatch_.size() && samplePatch_ != "none")
+            if (samplePatch().size() && samplePatch() != "none")
             {
                 FatalErrorIn
                 (
@@ -454,7 +454,7 @@ void Foam::mappedPatchBase::findSamples
 
     if (debug)
     {
-        Info<< "mappedPatchBase::findSamples on mesh " << sampleRegion_
+        Info<< "mappedPatchBase::findSamples on mesh " << sampleRegion()
             << " : " << endl;
         forAll(nearest, sampleI)
         {
@@ -516,8 +516,8 @@ void Foam::mappedPatchBase::calcMapping() const
     bool sampleMyself =
     (
         mode_ == NEARESTPATCHFACE
-     && sampleRegion_ == patch_.boundaryMesh().mesh().name()
-     && samplePatch_ == patch_.name()
+     && sampleRegion() == patch_.boundaryMesh().mesh().name()
+     && samplePatch() == patch_.name()
     );
 
     // Check offset
@@ -544,9 +544,9 @@ void Foam::mappedPatchBase::calcMapping() const
             << " will find the faces themselves which does not make sense"
             << " for anything but testing." << endl
             << "patch_:" << patch_.name() << endl
-            << "sampleRegion_:" << sampleRegion_ << endl
+            << "sampleRegion_:" << sampleRegion() << endl
             << "mode_:" << sampleModeNames_[mode_] << endl
-            << "samplePatch_:" << samplePatch_ << endl
+            << "samplePatch_:" << samplePatch() << endl
             << "offsetMode_:" << offsetModeNames_[offsetMode_] << endl;
     }
 
@@ -604,12 +604,10 @@ void Foam::mappedPatchBase::calcMapping() const
                     << " out of " << sampleProcs.size() << " total samples."
                     << " Sampling these on owner cell centre instead." << endl
                     << "On patch " << patch_.name()
-                    << " on region " << sampleRegion_
+                    << " on region " << sampleRegion()
                     << " in mode " << sampleModeNames_[mode_] << endl
-                    << "whilst sampling patch " << samplePatch_ << endl
-                    << " with offset mode " << offsetModeNames_[offsetMode_]
-                    << endl
-                    << "Suppressing further warnings from " << type() << endl;
+                    << "with offset mode " << offsetModeNames_[offsetMode_]
+                    << ". Suppressing further warnings from " << type() << endl;
 
                 hasWarned = true;
             }
@@ -657,7 +655,7 @@ void Foam::mappedPatchBase::calcMapping() const
     //        << " for proc:" << patchFaceProcs[i]
     //        << " face:" << patchFaces[i]
     //        << " at:" << patchFc[i] << endl
-    //        << "Found data in region " << sampleRegion_
+    //        << "Found data in region " << sampleRegion()
     //        << " at proc:" << sampleProcs[i]
     //        << " face:" << sampleIndices[i]
     //        << " at:" << sampleLocations[i]
@@ -942,7 +940,8 @@ Foam::mappedPatchBase::mappedPatchBase
     patch_(pp),
     sampleRegion_(patch_.boundaryMesh().mesh().name()),
     mode_(NEARESTPATCHFACE),
-    samplePatch_("none"),
+    samplePatch_(""),
+    coupleGroup_(),
     offsetMode_(UNIFORM),
     offset_(vector::zero),
     offsets_(pp.size(), offset_),
@@ -969,6 +968,7 @@ Foam::mappedPatchBase::mappedPatchBase
     sampleRegion_(sampleRegion),
     mode_(mode),
     samplePatch_(samplePatch),
+    coupleGroup_(),
     offsetMode_(NONUNIFORM),
     offset_(vector::zero),
     offsets_(offsets),
@@ -995,6 +995,7 @@ Foam::mappedPatchBase::mappedPatchBase
     sampleRegion_(sampleRegion),
     mode_(mode),
     samplePatch_(samplePatch),
+    coupleGroup_(),
     offsetMode_(UNIFORM),
     offset_(offset),
     offsets_(0),
@@ -1021,6 +1022,7 @@ Foam::mappedPatchBase::mappedPatchBase
     sampleRegion_(sampleRegion),
     mode_(mode),
     samplePatch_(samplePatch),
+    coupleGroup_(),
     offsetMode_(NORMAL),
     offset_(vector::zero),
     offsets_(0),
@@ -1041,16 +1043,10 @@ Foam::mappedPatchBase::mappedPatchBase
 )
 :
     patch_(pp),
-    sampleRegion_
-    (
-        dict.lookupOrDefault
-        (
-            "sampleRegion",
-            patch_.boundaryMesh().mesh().name()
-        )
-    ),
+    sampleRegion_(dict.lookupOrDefault<word>("sampleRegion", "")),
     mode_(sampleModeNames_.read(dict.lookup("sampleMode"))),
-    samplePatch_(dict.lookup("samplePatch")),
+    samplePatch_(dict.lookupOrDefault<word>("samplePatch", "")),
+    coupleGroup_(dict),
     offsetMode_(UNIFORM),
     offset_(vector::zero),
     offsets_(0),
@@ -1062,6 +1058,16 @@ Foam::mappedPatchBase::mappedPatchBase
     surfPtr_(NULL),
     surfDict_(dict.subOrEmptyDict("surface"))
 {
+    if (!coupleGroup_.valid())
+    {
+        if (sampleRegion_.empty())
+        {
+            // If no coupleGroup and no sampleRegion assume local region
+            sampleRegion_ = patch_.boundaryMesh().mesh().name();
+            sameRegion_ = true;
+        }
+    }
+
     if (dict.found("offsetMode"))
     {
         offsetMode_ = offsetModeNames_.read(dict.lookup("offsetMode"));
@@ -1099,7 +1105,7 @@ Foam::mappedPatchBase::mappedPatchBase
         //offsets_ = pointField(dict.lookup("offsets"));
         offsets_ = readListOrField("offsets", dict, patch_.size());
     }
-    else
+    else if (mode_ != NEARESTPATCHFACE && mode_ != NEARESTPATCHFACEAMI)
     {
         FatalIOErrorIn
         (
@@ -1116,6 +1122,60 @@ Foam::mappedPatchBase::mappedPatchBase
 }
 
 
+Foam::mappedPatchBase::mappedPatchBase
+(
+    const polyPatch& pp,
+    const sampleMode mode,
+    const dictionary& dict
+)
+:
+    patch_(pp),
+    sampleRegion_(dict.lookupOrDefault<word>("sampleRegion", "")),
+    mode_(mode),
+    samplePatch_(dict.lookupOrDefault<word>("samplePatch", "")),
+    coupleGroup_(dict), //dict.lookupOrDefault<word>("coupleGroup", "")),
+    offsetMode_(UNIFORM),
+    offset_(vector::zero),
+    offsets_(0),
+    distance_(0.0),
+    sameRegion_(sampleRegion_ == patch_.boundaryMesh().mesh().name()),
+    mapPtr_(NULL),
+    AMIPtr_(NULL),
+    AMIReverse_(dict.lookupOrDefault<bool>("flipNormals", false)),
+    surfPtr_(NULL),
+    surfDict_(dict.subOrEmptyDict("surface"))
+{
+    if (mode != NEARESTPATCHFACE && mode != NEARESTPATCHFACEAMI)
+    {
+        FatalIOErrorIn
+        (
+            "mappedPatchBase::mappedPatchBase\n"
+            "(\n"
+            "    const polyPatch&,\n"
+            "    const sampleMode,\n"
+            "    const dictionary&\n"
+            ")\n",
+            dict
+        )   << "Construct from sampleMode and dictionary only applicable for "
+            << " collocated patches in modes "
+            << sampleModeNames_[NEARESTPATCHFACE] << ','
+            << sampleModeNames_[NEARESTPATCHFACEAMI]
+            << exit(FatalIOError);
+    }
+
+
+    if (!coupleGroup_.valid())
+    {
+        if (sampleRegion_.empty())
+        {
+            // If no coupleGroup and no sampleRegion assume local region
+            sampleRegion_ = patch_.boundaryMesh().mesh().name();
+            sameRegion_ = true;
+        }
+    }
+}
+
+
 Foam::mappedPatchBase::mappedPatchBase
 (
     const polyPatch& pp,
@@ -1126,6 +1186,7 @@ Foam::mappedPatchBase::mappedPatchBase
     sampleRegion_(mpb.sampleRegion_),
     mode_(mpb.mode_),
     samplePatch_(mpb.samplePatch_),
+    coupleGroup_(mpb.coupleGroup_),
     offsetMode_(mpb.offsetMode_),
     offset_(mpb.offset_),
     offsets_(mpb.offsets_),
@@ -1150,6 +1211,7 @@ Foam::mappedPatchBase::mappedPatchBase
     sampleRegion_(mpb.sampleRegion_),
     mode_(mpb.mode_),
     samplePatch_(mpb.samplePatch_),
+    coupleGroup_(mpb.coupleGroup_),
     offsetMode_(mpb.offsetMode_),
     offset_(mpb.offset_),
     offsets_
@@ -1190,7 +1252,7 @@ const Foam::polyMesh& Foam::mappedPatchBase::sampleMesh() const
 {
     return patch_.boundaryMesh().mesh().time().lookupObject<polyMesh>
     (
-        sampleRegion_
+        sampleRegion()
     );
 }
 
@@ -1199,12 +1261,12 @@ const Foam::polyPatch& Foam::mappedPatchBase::samplePolyPatch() const
 {
     const polyMesh& nbrMesh = sampleMesh();
 
-    const label patchI = nbrMesh.boundaryMesh().findPatchID(samplePatch_);
+    const label patchI = nbrMesh.boundaryMesh().findPatchID(samplePatch());
 
     if (patchI == -1)
     {
         FatalErrorIn("mappedPatchBase::samplePolyPatch()")
-            << "Cannot find patch " << samplePatch_
+            << "Cannot find patch " << samplePatch()
             << " in region " << sampleRegion_ << endl
             << "Valid patches are " << nbrMesh.boundaryMesh().names()
             << exit(FatalError);
@@ -1340,46 +1402,66 @@ 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;
-
-    os.writeKeyword("offsetMode") << offsetModeNames_[offsetMode_]
-        << token::END_STATEMENT << nl;
-
-    switch (offsetMode_)
+    if (!sampleRegion_.empty())
     {
-        case UNIFORM:
-        {
-            os.writeKeyword("offset") << offset_ << token::END_STATEMENT << nl;
-            break;
-        }
-        case NONUNIFORM:
-        {
-            offsets_.writeEntry("offsets", os);
-            break;
-        }
-        case NORMAL:
-        {
-            os.writeKeyword("distance") << distance_ << token::END_STATEMENT
-                << nl;
-            break;
-        }
+        os.writeKeyword("sampleRegion") << sampleRegion_
+            << token::END_STATEMENT << nl;
+    }
+    if (!samplePatch_.empty())
+    {
+        os.writeKeyword("samplePatch") << samplePatch_
+            << token::END_STATEMENT << nl;
     }
+    coupleGroup_.write(os);
 
-    if (mode_ == NEARESTPATCHFACEAMI)
+    if
+    (
+        offsetMode_ == UNIFORM
+     && offset_ == vector::zero
+     && (mode_ == NEARESTPATCHFACE || mode_ == NEARESTPATCHFACEAMI)
+    )
     {
-        if (AMIReverse_)
+        // Collocated mode. No need to write offset data
+    }
+    else
+    {
+        os.writeKeyword("offsetMode") << offsetModeNames_[offsetMode_]
+            << token::END_STATEMENT << nl;
+
+        switch (offsetMode_)
         {
-            os.writeKeyword("flipNormals") << AMIReverse_
-                << token::END_STATEMENT << nl;
+            case UNIFORM:
+            {
+                os.writeKeyword("offset") << offset_ << token::END_STATEMENT
+                    << nl;
+                break;
+            }
+            case NONUNIFORM:
+            {
+                offsets_.writeEntry("offsets", os);
+                break;
+            }
+            case NORMAL:
+            {
+                os.writeKeyword("distance") << distance_ << token::END_STATEMENT
+                    << nl;
+                break;
+            }
         }
 
-        if (!surfDict_.empty())
+        if (mode_ == NEARESTPATCHFACEAMI)
         {
-            os.writeKeyword(surfDict_.dictName());
-            os  << surfDict_;
+            if (AMIReverse_)
+            {
+                os.writeKeyword("flipNormals") << AMIReverse_
+                    << token::END_STATEMENT << nl;
+            }
+
+            if (!surfDict_.empty())
+            {
+                os.writeKeyword(surfDict_.dictName());
+                os  << surfDict_;
+            }
         }
     }
 }
diff --git a/src/meshTools/mappedPatches/mappedPolyPatch/mappedPatchBase.H b/src/meshTools/mappedPatches/mappedPolyPatch/mappedPatchBase.H
index f72f407d8102a991e070229c3b1d34cc6c097a31..928a1d5b85fea42c6574ae9c5235986226d46337 100644
--- a/src/meshTools/mappedPatches/mappedPolyPatch/mappedPatchBase.H
+++ b/src/meshTools/mappedPatches/mappedPolyPatch/mappedPatchBase.H
@@ -45,9 +45,13 @@ Description
         //                         beforehand)
         sampleMode nearestCell;
 
-        // If sampleMod is nearestPatchFace : patch to find faces of
+        // If sampleMode is nearestPatchFace : patch to find faces of
         samplePatch movingWall;
 
+        // If sampleMode is nearestPatchFace : specify patchgroup to find
+        // samplePatch and sampleRegion (if not provided)
+        coupleGroup baffleGroup;
+
         // How to supply offset (w.r.t. my patch face centres):
         // - uniform : single offset vector
         // - nonuniform : per-face offset vector
@@ -78,6 +82,7 @@ SourceFiles
 #include "Tuple2.H"
 #include "pointIndexHit.H"
 #include "AMIPatchToPatchInterpolation.H"
+#include "coupleGroupIdentifier.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -180,13 +185,16 @@ protected:
         const polyPatch& patch_;
 
         //- Region to sample
-        const word sampleRegion_;
+        mutable word sampleRegion_;
 
         //- What to sample
         const sampleMode mode_;
 
         //- Patch (if in sampleMode NEARESTPATCH*)
-        const word samplePatch_;
+        mutable word samplePatch_;
+
+        //- PatchGroup (if in sampleMode NEARESTPATCH*)
+        const coupleGroupIdentifier coupleGroup_;
 
         //- How to obtain samples
         offsetMode offsetMode_;
@@ -201,7 +209,7 @@ protected:
         scalar distance_;
 
         //- Same region
-        const bool sameRegion_;
+        mutable bool sameRegion_;
 
 
         // Derived information
@@ -315,6 +323,11 @@ public:
         //- Construct from dictionary
         mappedPatchBase(const polyPatch&, const dictionary&);
 
+        //- Construct from dictionary and (collocated) sample mode
+        //  (only for nearestPatchFace, nearestPatchFaceAMI, nearestPatchPoint)
+        //  Assumes zero offset.
+        mappedPatchBase(const polyPatch&, const sampleMode, const dictionary&);
+
         //- Construct as copy, resetting patch
         mappedPatchBase(const polyPatch&, const mappedPatchBase&);
 
@@ -346,6 +359,9 @@ public:
             //- Patch (only if NEARESTPATCHFACE)
             inline const word& samplePatch() const;
 
+            //- PatchGroup (only if NEARESTPATCHFACE)
+            inline const word& coupleGroup() const;
+
             //- Return size of mapped mesh/patch/boundary
             inline label sampleSize() const;
 
diff --git a/src/meshTools/mappedPatches/mappedPolyPatch/mappedPatchBaseI.H b/src/meshTools/mappedPatches/mappedPolyPatch/mappedPatchBaseI.H
index 927534210f1079d551dde3be37d7ff2bcd99a9a8..8133a9d69234ae1d7c9c2e1ccb140740ed4b1bf3 100644
--- a/src/meshTools/mappedPatches/mappedPolyPatch/mappedPatchBaseI.H
+++ b/src/meshTools/mappedPatches/mappedPolyPatch/mappedPatchBaseI.H
@@ -32,16 +32,62 @@ Foam::mappedPatchBase::mode() const
 
 inline const Foam::word& Foam::mappedPatchBase::sampleRegion() const
 {
+    if (sampleRegion_.empty())
+    {
+        if (!coupleGroup_.valid())
+        {
+            FatalErrorIn("mappedPatchBase::sampleRegion()")
+                << "Supply either a regionName or a coupleGroup"
+                << " for patch " << patch_.name()
+                << " in region " << patch_.boundaryMesh().mesh().name()
+                << exit(FatalError);
+        }
+
+        // Try and use patchGroup to find samplePatch and sampleRegion
+        label samplePatchID = coupleGroup_.findOtherPatchID
+        (
+            patch_,
+            sampleRegion_
+        );
+
+        samplePatch_ = sampleMesh().boundaryMesh()[samplePatchID].name();
+    }
     return sampleRegion_;
 }
 
 
 inline const Foam::word& Foam::mappedPatchBase::samplePatch() const
 {
+    if (samplePatch_.empty())
+    {
+        if (!coupleGroup_.valid())
+        {
+            FatalErrorIn("mappedPatchBase::samplePolyPatch()")
+                << "Supply either a patchName or a coupleGroup"
+                << " for patch " << patch_.name()
+                << " in region " << patch_.boundaryMesh().mesh().name()
+                << exit(FatalError);
+        }
+
+        // Try and use patchGroup to find samplePatch and sampleRegion
+        label samplePatchID = coupleGroup_.findOtherPatchID
+        (
+            patch_,
+            sampleRegion_
+        );
+
+        samplePatch_ = sampleMesh().boundaryMesh()[samplePatchID].name();
+    }
     return samplePatch_;
 }
 
 
+inline const Foam::word& Foam::mappedPatchBase::coupleGroup() const
+{
+    return coupleGroup_.name();
+}
+
+
 inline Foam::label Foam::mappedPatchBase::sampleSize() const
 {
     switch (mode_)
diff --git a/src/meshTools/tetOverlapVolume/tetOverlapVolume.C b/src/meshTools/tetOverlapVolume/tetOverlapVolume.C
index e73df2f6952c2137a280a649bb2470b2edf7eb25..c44384084e81843db4c404aa34fbd010a1762fdf 100644
--- a/src/meshTools/tetOverlapVolume/tetOverlapVolume.C
+++ b/src/meshTools/tetOverlapVolume/tetOverlapVolume.C
@@ -396,10 +396,7 @@ Foam::labelList Foam::tetOverlapVolume::overlappingCells
 {
     const indexedOctree<treeDataCell>& treeA = fromMesh.cellTree();
 
-    treeBoundBox bbB
-    (
-        pointField(toMesh.points(), toMesh.cellPoints()[iTo])
-    );
+    treeBoundBox bbB(toMesh.points(), toMesh.cellPoints()[iTo]);
 
     return treeA.findBox(bbB);
 }
diff --git a/src/meshTools/triSurface/booleanOps/booleanSurface/booleanSurface.C b/src/meshTools/triSurface/booleanOps/booleanSurface/booleanSurface.C
index d171b432a036ae72d22796a34794842e924ed6d4..3d66eb6b8b04f62f2b7a1c0e1516732088f0558e 100644
--- a/src/meshTools/triSurface/booleanOps/booleanSurface/booleanSurface.C
+++ b/src/meshTools/triSurface/booleanOps/booleanSurface/booleanSurface.C
@@ -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
@@ -326,7 +326,7 @@ void Foam::booleanSurface::propagateSide
     {
         side[faceI] = prevState;
 
-        const labelledTri& tri = surf[faceI];
+        const labelledTri& tri = surf.localFaces()[faceI];
 
         // Get copy of face labels
         label a = tri[0];
diff --git a/src/sampling/meshToMeshInterpolation/meshToMeshNew/calcMethod/meshToMeshMethod/meshToMeshMethod.C b/src/sampling/meshToMeshInterpolation/meshToMeshNew/calcMethod/meshToMeshMethod/meshToMeshMethod.C
index 29e066dd542937b69a6872ca663bd0c9e1622c18..9bfb15adc06132042dc160efc0d9e70a923aa239 100644
--- a/src/sampling/meshToMeshInterpolation/meshToMeshNew/calcMethod/meshToMeshMethod/meshToMeshMethod.C
+++ b/src/sampling/meshToMeshInterpolation/meshToMeshNew/calcMethod/meshToMeshMethod/meshToMeshMethod.C
@@ -84,14 +84,7 @@ bool Foam::meshToMeshMethod::intersect
 
     tetOverlapVolume overlapEngine;
 
-    treeBoundBox bbTgtCell
-    (
-        pointField
-        (
-            tgt_.points(),
-            tgt_.cellPoints()[tgtCellI]
-        )
-    );
+    treeBoundBox bbTgtCell(tgt_.points(), tgt_.cellPoints()[tgtCellI]);
 
     return overlapEngine.cellCellOverlapMinDecomp
     (
@@ -113,14 +106,7 @@ Foam::scalar Foam::meshToMeshMethod::interVol
 {
     tetOverlapVolume overlapEngine;
 
-    treeBoundBox bbTgtCell
-    (
-        pointField
-        (
-            tgt_.points(),
-            tgt_.cellPoints()[tgtCellI]
-        )
-    );
+    treeBoundBox bbTgtCell(tgt_.points(), tgt_.cellPoints()[tgtCellI]);
 
     scalar vol = overlapEngine.cellCellOverlapVolumeMinDecomp
     (
diff --git a/src/sampling/sampledSurface/sampledTriSurfaceMesh/sampledTriSurfaceMesh.C b/src/sampling/sampledSurface/sampledTriSurfaceMesh/sampledTriSurfaceMesh.C
index 20b57d80b38a5ab7cb491961ba7dc6e05d64c2cd..5ae942673ad0ca3335f813c253b5908f1c53367b 100644
--- a/src/sampling/sampledSurface/sampledTriSurfaceMesh/sampledTriSurfaceMesh.C
+++ b/src/sampling/sampledSurface/sampledTriSurfaceMesh/sampledTriSurfaceMesh.C
@@ -46,13 +46,14 @@ namespace Foam
     );
 
     template<>
-    const char* NamedEnum<sampledTriSurfaceMesh::samplingSource, 2>::names[] =
+    const char* NamedEnum<sampledTriSurfaceMesh::samplingSource, 3>::names[] =
     {
         "cells",
+        "insideCells",
         "boundaryFaces"
     };
 
-    const NamedEnum<sampledTriSurfaceMesh::samplingSource, 2>
+    const NamedEnum<sampledTriSurfaceMesh::samplingSource, 3>
     sampledTriSurfaceMesh::samplingSourceNames_;
 
 
@@ -147,7 +148,7 @@ bool Foam::sampledTriSurfaceMesh::update(const meshSearch& meshSearcher)
     // elements
     globalIndex globalCells
     (
-        sampleSource_ == cells
+        (sampleSource_ == cells || sampleSource_ == insideCells)
       ? mesh().nCells()
       : mesh().nFaces()
     );
@@ -178,6 +179,25 @@ bool Foam::sampledTriSurfaceMesh::update(const meshSearch& meshSearcher)
             }
         }
     }
+    else if (sampleSource_ == insideCells)
+    {
+        // Search for cell containing point
+
+        const indexedOctree<treeDataCell>& cellTree = meshSearcher.cellTree();
+
+        forAll(fc, triI)
+        {
+            if (cellTree.bb().contains(fc[triI]))
+            {
+                label index = cellTree.findInside(fc[triI]);
+                if (index != -1)
+                {
+                    nearest[triI].first() = 0.0;
+                    nearest[triI].second() = globalCells.toGlobal(index);
+                }
+            }
+        }
+    }
     else
     {
         // Search for nearest boundaryFace
@@ -364,6 +384,19 @@ bool Foam::sampledTriSurfaceMesh::update(const meshSearch& meshSearcher)
                 }
             }
         }
+        else if (sampleSource_ == insideCells)
+        {
+            // samplePoints_   : per surface point a location inside the cell
+            // sampleElements_ : per surface point the cell
+
+            forAll(points(), pointI)
+            {
+                const point& pt = points()[pointI];
+                label cellI = cellOrFaceLabels[pointToFace[pointI]];
+                sampleElements_[pointI] = cellI;
+                samplePoints_[pointI] = pt;
+            }
+        }
         else
         {
             // samplePoints_   : per surface point a location on the boundary
@@ -388,6 +421,9 @@ bool Foam::sampledTriSurfaceMesh::update(const meshSearch& meshSearcher)
         // if sampleSource_ == cells:
         //      samplePoints_   : n/a
         //      sampleElements_ : per surface triangle the cell
+        // if sampleSource_ == insideCells:
+        //      samplePoints_   : n/a
+        //      sampleElements_ : -1 or per surface triangle the cell
         // else:
         //      samplePoints_   : n/a
         //      sampleElements_ : per surface triangle the boundary face
@@ -406,7 +442,7 @@ bool Foam::sampledTriSurfaceMesh::update(const meshSearch& meshSearcher)
 
         if (sampledSurface::interpolate())
         {
-            if (sampleSource_ == cells)
+            if (sampleSource_ == cells || sampleSource_ == insideCells)
             {
                 forAll(samplePoints_, pointI)
                 {
@@ -443,7 +479,7 @@ bool Foam::sampledTriSurfaceMesh::update(const meshSearch& meshSearcher)
         }
         else
         {
-            if (sampleSource_ == cells)
+            if (sampleSource_ == cells || sampleSource_ == insideCells)
             {
                 forAll(sampleElements_, triI)
                 {
diff --git a/src/sampling/sampledSurface/sampledTriSurfaceMesh/sampledTriSurfaceMesh.H b/src/sampling/sampledSurface/sampledTriSurfaceMesh/sampledTriSurfaceMesh.H
index 7ef68570c43b0a67ac48c7b13005de6ca249bc0a..1e7cd4e6ed36a82bae54774d07c1dbfcf328c71b 100644
--- a/src/sampling/sampledSurface/sampledTriSurfaceMesh/sampledTriSurfaceMesh.H
+++ b/src/sampling/sampledSurface/sampledTriSurfaceMesh/sampledTriSurfaceMesh.H
@@ -30,7 +30,7 @@ Description
 
     - it either samples cells or (non-coupled) boundary faces
 
-    - 4 different modes:
+    - 6 different modes:
         - source=cells, interpolate=false:
             finds per triangle centre the nearest cell centre and uses its value
         - source=cells, interpolate=true
@@ -40,6 +40,12 @@ Description
             the boundary of the cell (to make sure interpolateCellPoint
             gets a valid location)
 
+        - source=insideCells, interpolate=false:
+            finds per triangle centre the cell containing it and uses its value.
+            Trims triangles outside mesh.
+        - source=insideCells, interpolate=true
+            Per surface point interpolate cell containing it.
+
         - source=boundaryFaces, interpolate=false:
             finds per triangle centre the nearest point on the boundary
             (uncoupled faces only) and uses the value (or 0 if the nearest
@@ -88,7 +94,8 @@ public:
         enum samplingSource
         {
             cells,
-            boundaryFaces
+            insideCells,
+            boundaryFaces,
         };
 
 private:
@@ -99,7 +106,7 @@ private:
 
     // Private data
 
-        static const NamedEnum<samplingSource, 2> samplingSourceNames_;
+        static const NamedEnum<samplingSource, 3> samplingSourceNames_;
 
         //- Surface to sample on
         const triSurfaceMesh surface_;
diff --git a/src/sampling/sampledSurface/sampledTriSurfaceMesh/sampledTriSurfaceMeshTemplates.C b/src/sampling/sampledSurface/sampledTriSurfaceMesh/sampledTriSurfaceMeshTemplates.C
index ca6931ef8745d5c23516627bf8d8504507299bda..d251431a550ea89caf5e5c7fd67c4bf2a56919e3 100644
--- a/src/sampling/sampledSurface/sampledTriSurfaceMesh/sampledTriSurfaceMeshTemplates.C
+++ b/src/sampling/sampledSurface/sampledTriSurfaceMesh/sampledTriSurfaceMeshTemplates.C
@@ -38,7 +38,7 @@ Foam::sampledTriSurfaceMesh::sampleField
     tmp<Field<Type> > tvalues(new Field<Type>(sampleElements_.size()));
     Field<Type>& values = tvalues();
 
-    if (sampleSource_ == cells)
+    if (sampleSource_ == cells || sampleSource_ == insideCells)
     {
         // Sample cells
 
@@ -94,7 +94,7 @@ Foam::sampledTriSurfaceMesh::interpolateField
     tmp<Field<Type> > tvalues(new Field<Type>(sampleElements_.size()));
     Field<Type>& values = tvalues();
 
-    if (sampleSource_ == cells)
+    if (sampleSource_ == cells || sampleSource_ == insideCells)
     {
         // Sample cells.
 
diff --git a/src/triSurface/triSurface/interfaces/OBJ/readOBJ.C b/src/triSurface/triSurface/interfaces/OBJ/readOBJ.C
index 14a7f697f53a2694bd9a7d48af938a04c4879033..004661ab3cf36831c3bed3a63ee79d5797fe8e48 100644
--- a/src/triSurface/triSurface/interfaces/OBJ/readOBJ.C
+++ b/src/triSurface/triSurface/interfaces/OBJ/readOBJ.C
@@ -104,7 +104,7 @@ bool Foam::triSurface::readOBJ(const fileName& OBJfileName)
             while (true)
             {
                 string::size_type startNum =
-                    line.find_first_not_of(' ', endNum);
+                    line.find_first_not_of(" \r", endNum);
 
                 if (startNum == string::npos)
                 {
diff --git a/src/turbulenceModels/compressible/turbulenceModel/derivedFvPatchFields/thermalBaffle1D/thermalBaffle1DFvPatchScalarField.C b/src/turbulenceModels/compressible/turbulenceModel/derivedFvPatchFields/thermalBaffle1D/thermalBaffle1DFvPatchScalarField.C
index 45565764ef2a8be0e8b8b98c835b0329250f9b5e..30ccbc2fd1f71560c057e09f1046f961ef9e8dff 100644
--- a/src/turbulenceModels/compressible/turbulenceModel/derivedFvPatchFields/thermalBaffle1D/thermalBaffle1DFvPatchScalarField.C
+++ b/src/turbulenceModels/compressible/turbulenceModel/derivedFvPatchFields/thermalBaffle1D/thermalBaffle1DFvPatchScalarField.C
@@ -93,14 +93,7 @@ thermalBaffle1DFvPatchScalarField
     const dictionary& dict
 )
 :
-    mappedPatchBase
-    (
-        p.patch(),
-        p.boundaryMesh().mesh().name(),
-        NEARESTPATCHFACE,
-        dict.lookup("samplePatch"),
-        0.0
-    ),
+    mappedPatchBase(p.patch(), NEARESTPATCHFACE, dict),
     mixedFvPatchScalarField(p, iF),
     TName_("T"),
     baffleActivated_(dict.lookupOrDefault<bool>("baffleActivated", true)),
diff --git a/tutorials/heatTransfer/buoyantSimpleFoam/circuitBoardCooling/0.org/include/1DBaffle/1DTemperatureMasterBafflePatches b/tutorials/heatTransfer/buoyantSimpleFoam/circuitBoardCooling/0.org/include/1DBaffle/1DTemperatureMasterBafflePatches
index 5e2ff882e363d59c2536f1ca83bd32a73b663932..1c2a91f28cbe1f0eb8a84bfd761318ad9c609660 100644
--- a/tutorials/heatTransfer/buoyantSimpleFoam/circuitBoardCooling/0.org/include/1DBaffle/1DTemperatureMasterBafflePatches
+++ b/tutorials/heatTransfer/buoyantSimpleFoam/circuitBoardCooling/0.org/include/1DBaffle/1DTemperatureMasterBafflePatches
@@ -9,7 +9,6 @@
 T
 {
     type   compressible::thermalBaffle1D<hConstSolidThermoPhysics>;
-    samplePatch     baffle1DWall_slave;
 
     thickness       uniform 0.005;  // thickness [m]
     Qs              uniform 100;    // heat flux [W/m2]
diff --git a/tutorials/heatTransfer/buoyantSimpleFoam/circuitBoardCooling/system/createBafflesDict b/tutorials/heatTransfer/buoyantSimpleFoam/circuitBoardCooling/system/createBafflesDict
index feb96c24ba198d3e8cf9d907f98bfd9c13a45a1a..fe16ef97a259ec6b8886c14ee462a6c0bdc0c79e 100644
--- a/tutorials/heatTransfer/buoyantSimpleFoam/circuitBoardCooling/system/createBafflesDict
+++ b/tutorials/heatTransfer/buoyantSimpleFoam/circuitBoardCooling/system/createBafflesDict
@@ -29,35 +29,13 @@ baffles
         surface     triSurfaceMesh;
         name        baffle1D.stl;
 
-        patches
+        patchPairs
         {
-            master
-            {
-                //- Master side patch
-                name            baffle1DWall_master;
-
-                type            wall;
-                inGroups        (baffleWallGroup);
-
-                patchFields
-                {
-                    #include "./0/include/wallBafflePatches"
-                    #include "./0/include/1DBaffle/1DTemperatureMasterBafflePatches"
-                }
-            }
-            slave
+            type            wall;
+            patchFields
             {
-                //- Slave side patch
-                name            baffle1DWall_slave;
-
-                type            wall;
-                inGroups        (baffleWallGroup);
-
-                patchFields
-                {
-                    #include "./0/include/wallBafflePatches"
-                    #include "./0/include/1DBaffle/1DTemperatureSlaveBafflePatches"
-                }
+                #include "./0/include/wallBafflePatches"
+                #include "./0/include/1DBaffle/1DTemperatureMasterBafflePatches"
             }
         }
     }
@@ -78,10 +56,7 @@ baffles
                 name            ${masterPatchName};
 
                 type            mappedWall;
-
-
-                type            interRegionMappedWallGenerator;
-                                inGroups        (baffleWallGroup);
+                inGroups        (baffleWallGroup);
 
                 sampleMode      nearestPatchFace;
                 sampleRegion    ${baffleRegionName};
diff --git a/tutorials/incompressible/pimpleFoam/TJunctionFan/Allclean b/tutorials/incompressible/pimpleFoam/TJunctionFan/Allclean
new file mode 100755
index 0000000000000000000000000000000000000000..3c02c9465508095a6e968179f0b86e3419602054
--- /dev/null
+++ b/tutorials/incompressible/pimpleFoam/TJunctionFan/Allclean
@@ -0,0 +1,10 @@
+#!/bin/sh
+cd ${0%/*} || exit 1    # run from this directory
+
+# Source tutorial clean functions
+. $WM_PROJECT_DIR/bin/tools/CleanFunctions
+
+cleanCase
+rm -rf 0
+
+# ----------------------------------------------------------------- end-of-file
diff --git a/tutorials/incompressible/pimpleFoam/TJunctionFan/Allrun b/tutorials/incompressible/pimpleFoam/TJunctionFan/Allrun
index 932dded90be1d07e045f395b723c0a5a02dc65b3..628bd511a9424eac90f7addd67860d518b258814 100755
--- a/tutorials/incompressible/pimpleFoam/TJunctionFan/Allrun
+++ b/tutorials/incompressible/pimpleFoam/TJunctionFan/Allrun
@@ -11,6 +11,8 @@ runApplication blockMesh
 # Create faceZones for baffles and fan
 runApplication topoSet
 
+cp -r 0.org 0
+
 # Create wall and cyclic baffles and the fields on them
 runApplication createBaffles -overwrite
 
diff --git a/tutorials/incompressible/pimpleFoam/TJunctionFan/system/createBafflesDict b/tutorials/incompressible/pimpleFoam/TJunctionFan/system/createBafflesDict
index f70ad3e89bda2de93f8d64451856d211af71e2c9..19ea37dfdba5c1aefc2f3650944421354069cf82 100644
--- a/tutorials/incompressible/pimpleFoam/TJunctionFan/system/createBafflesDict
+++ b/tutorials/incompressible/pimpleFoam/TJunctionFan/system/createBafflesDict
@@ -29,60 +29,46 @@ baffles
         type        faceZone;
         zoneName    baffleFaces;
 
-
-        //- Optional flip
-        //flip        false;
-
-        patches
+        patchPairs
         {
-            master
-            {
-                //- Master side patch
-                name            baffles;
-                type            wall;
+            type            wall;
 
-                patchFields
+            patchFields
+            {
+                epsilon
                 {
-                    epsilon
-                    {
-                        type            epsilonWallFunction;
-                        Cmu             0.09;
-                        kappa           0.41;
-                        E               9.8;
-                        value           uniform 0;
-                    }
-                    k
-                    {
-                        type            kqRWallFunction;
-                        value           uniform 0;
-                    }
-                    nut
-                    {
-                        type            nutkWallFunction;
-                        Cmu             0.09;
-                        kappa           0.41;
-                        E               9.8;
-                        value           uniform 0;
-                    }
-                    nuTilda
-                    {
-                        type            zeroGradient;
-                    }
-                    p
-                    {
-                        type            zeroGradient;
-                    }
-                    U
-                    {
-                        type            fixedValue;
-                        value           uniform (0 0 0);
-                    }
+                    type            epsilonWallFunction;
+                    Cmu             0.09;
+                    kappa           0.41;
+                    E               9.8;
+                    value           uniform 0;
+                }
+                k
+                {
+                    type            kqRWallFunction;
+                    value           uniform 0;
+                }
+                nut
+                {
+                    type            nutkWallFunction;
+                    Cmu             0.09;
+                    kappa           0.41;
+                    E               9.8;
+                    value           uniform 0;
+                }
+                nuTilda
+                {
+                    type            zeroGradient;
+                }
+                p
+                {
+                    type            zeroGradient;
+                }
+                U
+                {
+                    type            fixedValue;
+                    value           uniform (0 0 0);
                 }
-            }
-            slave
-            {
-                // Reuse master data
-                ${..master}
             }
         }
     }
@@ -97,46 +83,21 @@ baffles
         origin      (0.099 -0.006 0.004);
         span        (0 0.012 0.012);
 
-        patches
+        patchPairs
         {
-            master
-            {
-                //- Master side patch
-
-                name            fan_half0;
-                type            cyclic;
-                neighbourPatch  fan_half1;
+            type            cyclic;
 
-                //- Optional override of added patchfields. If not specified
-                //  any added patchfields are of type calculated.
-                patchFields
-                {
-                    p
-                    {
-                        type            fan;
-                        patchType       cyclic;
-                        jump            uniform 0;
-                        value           uniform 0;
-                        jumpTable       polynomial 1((100 0));
-                    }
-                }
-            }
-            slave
+            //- Optional override of added patchfields. If not specified
+            //  any added patchfields are of type calculated.
+            patchFields
             {
-                //- Slave side patch
-
-                name            fan_half1;
-                type            cyclic;
-                neighbourPatch  fan_half0;
-
-                patchFields
+                p
                 {
-                    p
-                    {
-                        type            fan;
-                        patchType       cyclic;
-                        value           uniform 0;
-                    }
+                    type            fan;
+                    patchType       cyclic;
+                    jump            uniform 0;
+                    value           uniform 0;
+                    jumpTable       polynomial 1((100 0));
                 }
             }
         }
diff --git a/tutorials/lagrangian/reactingParcelFoam/verticalChannel/constant/chemistryProperties b/tutorials/lagrangian/reactingParcelFoam/verticalChannel/constant/chemistryProperties
index ff1c96ea9660b955dffc025eda37ee04bd8ef0ba..16abe88752c48159501619254405bab19431985b 100644
--- a/tutorials/lagrangian/reactingParcelFoam/verticalChannel/constant/chemistryProperties
+++ b/tutorials/lagrangian/reactingParcelFoam/verticalChannel/constant/chemistryProperties
@@ -17,7 +17,7 @@ FoamFile
 
 chemistryType
 {
-    chemistrySolver   ode;
+    chemistrySolver   noChemistrySolver;
     chemistryThermo   rho;
 }