diff --git a/CHANGES-splitCyclic b/CHANGES-splitCyclic
new file mode 100644
index 0000000000000000000000000000000000000000..fc0ff4880f6ffa3c0ec73d62c35b4e412e56ec8b
--- /dev/null
+++ b/CHANGES-splitCyclic
@@ -0,0 +1,113 @@
+Short overview of the changes to have cyclics split into two halves.
+
+Cyclics
+-------
+The two cyclic halves are now split like processor patches. There should be no
+difference in running.
+
+Advantages:
+- decomposed cyclics can now be handled properly. It just needs to preserve
+the cyclic patch it originates from.
+- We can now construct a table of global transformations and handle
+points/edges/cells with transformations.
+- face ordering after topological changes becomes much easier since we
+now preserve what half the face comes from.
+- cyclic handling becomes more consistent with processor handling and can
+quite often be handled in the same condition.
+- transformation tensors now become single entry.
+
+The disadvantages:
+- a patch-wise loop now might need to store data to go to the neighbour half
+since it is no longer handled in a single patch.
+- decomposed cyclics now require overlapping communications so will
+only work in non-blocking mode. Hence the underlying message passing library
+will require overlapping communications with message tags.
+- it is quite a code-change and there might be some oversights.
+- once converted (see foamUpgradeCyclics below) cases are not backwards
+compatible with previous versions.
+
+
+blockMesh
+---------
+blockMeshDict now allows patch definition using the construct-from-dictionary
+constructor. This helps defining patches that require additional input e.g.
+directMapped and now cyclic:
+
+boundary         
+(
+    sides2_half0
+    {
+        type            cyclic;
+        neighbourPatch  sides2_half1;
+        faces           ((2 4 5 3));
+    }
+
+The syntax is - like the polyMesh/boundary file - a list of dictionaries with
+one additional entry 'faces' for the block faces. Above shows the new
+required entry 'neighbourPatch' for cyclic.
+
+blockMesh still reads the old format. For a cyclic it will automatically
+introduce two patches for the halves, with names xxx_half0 and xxx_half1.
+
+
+foamUpgradeCyclics
+------------------
+This is a tool which reads the polyMesh/boundary file and any vol/surface/point
+fields and converts them.
+It will check if anything needs to be converted, backup the current file to .old
+and split any cyclic patchFields into two entries.
+
+
+decomposePar
+------------
+Decomposes cyclics into processorCyclic:
+
+    procBoundary0to1throughsides1_half0
+    {
+        type            processorCyclic;
+        nFaces          1000;
+        startFace       91350;
+        myProcNo        0;
+        neighbProcNo    1;
+        referPatch      sides1_half0;
+    }
+
+They have an additional 'referPatch' entry which gives the (cyclic) patch
+to use for any transformation.
+
+
+Details
+-------
+- the cyclic patch dictionary has an entry neighbourPatch. The
+patch has new member functions:
+
+    //- Get neighbouring patchID
+    label neighbPatchID() const
+
+    //- Get neighbouring patch
+    const cyclicPolyPatch& neighbPatch()
+
+    //- Am I the owner half
+    bool owner()
+
+The cyclic still has forward() and reverse() transformations (with
+the reverse() equal to the neighbPatch().forward()).
+
+There is no transformLocalFace anymore - the ordering is the same for
+both halves.
+
+
+- 'pure' processor patches now are always coincident - they (should) have no
+transformation. As said above cyclics are decomposed into a derived
+type 'processorCyclic'.
+
+
+- processor patches use overlapping communication using a different message
+tag. This maps straight through into the MPI message tag.
+
+
+- when constructing a GeometricField from a dictionary it will explicitly
+check for non-existing entries for cyclic patches and exit with an error message
+warning to run foamUpgradeCyclics.
+
+
diff --git a/TODO b/TODO
new file mode 100644
index 0000000000000000000000000000000000000000..de142d2889f8a5c53a0207d5d35239752ca6b2f8
--- /dev/null
+++ b/TODO
@@ -0,0 +1,100 @@
+- allocate/free tags.
+Not tested.
+
+OK - test blockMesh with cyclics
+unitTestCases/singleCyclic/
+
+OK - test cyclics sequential running.
+unitTestCases/singleCyclic/
+
+OK - test decomposePar
+tested channel395
+
+OK - FaceCellWave
+    unitTestCases/twoCavityCyclicForWallDistance/
+
+OK - non-parallel finite volume : channelFoam
+    unitTestCases/channel395-splitCyclic vs. channel395-dev
+
+OK - parallel finite volume with processorCyclic: channelFoam
+    unitTestCases/channel395-splitCyclic vs. channel395-dev
+
+OK - preProcessing/foamUpgradeCyclics
+
+OK - gamg - sequential.
+Tested on channel395-splitCyclic with GAMG.
+OK - gamg parallel.
+Tested on channel395-splitCyclic with GAMG.
+
+- initTransfer in GAMGprocessorInterfaces using nonblocking+tags
+untested.
+
+OK - cyclic baffles.
+Tested on t-junction-with-fan
+
+OK. - jumpCyclics/fanFvPatchField. All usages of jump() now need to account
+for being owner() or not.
+Tested on t-junction-with-fan.
+
+OK - regionSplit
+tested on singleCyclic
+
+OK - pointFields on cyclics. volPointInterpolation.
+tested on channel395-splitCyclic
+
+OK - fvMeshSubset
+tested on singleCyclic
+
+OK - pointEdgeWave (maybe test through inversePointDistanceDiffusivity?)
+tested on twoCavityCyclicForWallDistance
+
+OK - scotchDecomp
+tested with testCalcCSR on twoCavityCyclicForWallDistance
+
+NOT WORKING - fvMeshDistribute to split cyclic patches into ones
+  with different separation.
+tested on singleCyclic
+
+OK - test createPatch pointSync
+note: only works if face-centre position of 0th faces is ok since uses
+this for separation. Should in fact make cyclic planar using patch centre and
+normal?
+test on twoCavityCyclicForWallDistance with point (0 1 0) set to (0 1.001 0)
+
+NO PROBLEM - renumberMesh
+It doesn't do renumbering through cyclics.
+
+OK - rotational cyclics.
+Tested on movingCone-with-cyclics
+
+OK - LUscalarMatrix::convert still expects interfaces to be cyclic
+tested on channel395 with 'directSolveCoarsest true;' 
+
+OK - grep for size()/2
+
+- all tutorials with cyclics:
+    OK - incompressible/DNS/dnsFoam/boxTurb16
+    OK - incompressible/channelFoam/channel395
+    slight differences due to divergence. combustion/XiFoam/les/pitzDaily3D
+    OK - no cyclics. combustion/fireFoam/les/smallPoolFire2D
+    discreteMethods/dsmcFoam/freeSpacePeriodic
+    discreteMethods/dsmcFoam/wedge15Ma5
+    discreteMethods/molecularDynamics/mdEquilibrationFoam/periodicCubeArgon
+    OK - incompressible/boundaryFoam/boundaryLaunderSharma
+    OK - incompressible/boundaryFoam/boundaryWallFunctions
+    OK - incompressible/boundaryFoam/boundaryWallFunctionsProfile
+    OK - needs createBaffles. incompressible/pimpleFoam/t-junction-with-fan
+    OK - incompressible/simpleSRFFoam/mixer
+    OK - needs createBaffles. lagrangian/porousExplicitSourceReactingParcelFoam/filter
+    needs special coupledbcs. lagrangian/reactingParcelFilmFoam/multipleBoxes
+
+
+OK - createBaffles
+
+- have foamUpgradeCyclics split 'value' field
+- activeBaffleVelocity
+- kivaToFoam/readKivaGrid.H sorts cyclics (but in incorrect order?)
+- isoSurface.C
+- referredCellList.C
+- work out scheduled communication?
+OK - add neighbourPatch checking to 16x.
diff --git a/applications/utilities/mesh/advanced/combinePatchFaces/combinePatchFaces.C b/applications/utilities/mesh/advanced/combinePatchFaces/combinePatchFaces.C
index 56ea5e124f47d1d4ea52c414e2ad93e76c357e33..0b09b7859d730cb90cbb079deaef88d690eee64b 100644
--- a/applications/utilities/mesh/advanced/combinePatchFaces/combinePatchFaces.C
+++ b/applications/utilities/mesh/advanced/combinePatchFaces/combinePatchFaces.C
@@ -295,8 +295,7 @@ label mergePatchFaces
                     const faceZone& fZone = mesh.faceZones()[zoneID];
                     zoneFlip = fZone.flipMap()[fZone.whichFace(newMasterI)];
                 }
-                label patchI = mesh.boundaryMesh().whichPatch(newMasterI);
-
+                label patchID = mesh.boundaryMesh().whichPatch(newMasterI);
 
                 Pout<< "Restoring new master face " << newMasterI
                     << " to vertices " << setFaceVerts[0] << endl;
@@ -311,7 +310,7 @@ label mergePatchFaces
                         own,                            // owner
                         -1,                             // neighbour
                         false,                          // face flip
-                        patchI,                         // patch for face
+                        patchID,                        // patch for face
                         false,                          // remove from zone
                         zoneID,                         // zone for face
                         zoneFlip                        // face flip in zone
@@ -336,7 +335,7 @@ label mergePatchFaces
                             -1,                     // masterEdgeID,
                             newMasterI,             // masterFaceID,
                             false,                  // flipFaceFlux,
-                            patchI,                 // patchID,
+                            patchID,                // patchID,
                             zoneID,                 // zoneID,
                             zoneFlip                // zoneFlip
                         )
diff --git a/applications/utilities/mesh/generation/blockMesh/blockMeshApp.C b/applications/utilities/mesh/generation/blockMesh/blockMeshApp.C
index b896cb30335bab051d94cf45343c7a1013794ca5..3f8086bb8038dd03236912dec6721cd43e19c73b 100644
--- a/applications/utilities/mesh/generation/blockMesh/blockMeshApp.C
+++ b/applications/utilities/mesh/generation/blockMesh/blockMeshApp.C
@@ -206,25 +206,8 @@ int main(int argc, char *argv[])
 
     Info<< nl << "Creating polyMesh from blockMesh" << endl;
 
-    wordList patchNames = blocks.patchNames();
-    wordList patchTypes = blocks.patchTypes();
     word defaultFacesName = "defaultFaces";
     word defaultFacesType = emptyPolyPatch::typeName;
-    wordList patchPhysicalTypes = blocks.patchPhysicalTypes();
-
-
-    preservePatchTypes
-    (
-        runTime,
-        runTime.constant(),
-        polyMeshDir,
-        patchNames,
-        patchTypes,
-        defaultFacesName,
-        defaultFacesType,
-        patchPhysicalTypes
-    );
-
     polyMesh mesh
     (
         IOobject
@@ -236,11 +219,9 @@ int main(int argc, char *argv[])
         xferCopy(blocks.points()),           // could we re-use space?
         blocks.cells(),
         blocks.patches(),
-        patchNames,
-        patchTypes,
+        blocks.patchDicts(),
         defaultFacesName,
-        defaultFacesType,
-        patchPhysicalTypes
+        defaultFacesType
     );
 
 
diff --git a/applications/utilities/mesh/manipulation/createBaffles/createBaffles.C b/applications/utilities/mesh/manipulation/createBaffles/createBaffles.C
index 22720cbf65a0b20b8e71c7edc43f89ab7a84ac34..b3c4ca35e764f61faa606dbab7c3b6c1c5b005ff 100644
--- a/applications/utilities/mesh/manipulation/createBaffles/createBaffles.C
+++ b/applications/utilities/mesh/manipulation/createBaffles/createBaffles.C
@@ -134,7 +134,13 @@ int main(int argc, char *argv[])
     #include "addRegionOption.H"
 
     argList::validArgs.append("faceZone");
-    argList::validArgs.append("patch");
+    argList::validArgs.append("(masterPatch slavePatch)");
+    argList::addOption
+    (
+        "additionalPatches",
+        "((master2 slave2) .. (masterN slaveN))"
+    );
+    argList::addBoolOption("internalFacesOnly");
 
     argList::addOption
     (
@@ -159,7 +165,7 @@ int main(int argc, char *argv[])
     const faceZoneMesh& faceZones = mesh.faceZones();
 
     // Faces to baffle
-    faceZoneID zoneID(args[1], faceZones);
+    faceZoneID zoneID(args.additionalArgs()[0], faceZones);
 
     Info<< "Converting faces on zone " << zoneID.name()
         << " into baffles." << nl << endl;
@@ -182,28 +188,36 @@ int main(int argc, char *argv[])
     fZone.checkParallelSync(true);
 
     // Patches to put baffles into
-    DynamicList<label> newPatches(1);
+    DynamicList<label> newMasterPatches(1);
+    DynamicList<label> newSlavePatches(1);
 
-    const word patchName = args[2];
-    newPatches.append(findPatchID(mesh, patchName));
-    Info<< "Using patch " << patchName
-        << " at index " << newPatches[0] << endl;
+    const Pair<word> patchNames(IStringStream(args.additionalArgs()[1])());
+    newMasterPatches.append(findPatchID(mesh, patchNames[0]));
+    newSlavePatches.append(findPatchID(mesh, patchNames[1]));
+    Info<< "Using master patch " << patchNames[0]
+        << " at index " << newMasterPatches[0] << endl;
+    Info<< "Using slave patch " << patchNames[1]
+        << " at index " << newSlavePatches[0] << endl;
 
 
     // Additional patches
     if (args.optionFound("additionalPatches"))
     {
-        const wordList patchNames
+        const List<Pair<word> > patchNames
         (
             args.optionLookup("additionalPatches")()
         );
 
-        newPatches.reserve(patchNames.size() + 1);
+        newMasterPatches.reserve(patchNames.size() + 1);
+        newSlavePatches.reserve(patchNames.size() + 1);
         forAll(patchNames, i)
         {
-            newPatches.append(findPatchID(mesh, patchNames[i]));
-            Info<< "Using additional patch " << patchNames[i]
-                << " at index " << newPatches.last() << endl;
+            newMasterPatches.append(findPatchID(mesh, patchNames[i][0]));
+            newSlavePatches.append(findPatchID(mesh, patchNames[i][1]));
+            Info<< "Using additional patches " << patchNames[i]
+                << " at indices " << newMasterPatches.last()
+                << " and " << newSlavePatches.last()
+                << endl;
         }
     }
 
@@ -282,10 +296,8 @@ int main(int argc, char *argv[])
     }
     label nModified = 0;
 
-    forAll(newPatches, i)
+    forAll(newMasterPatches, i)
     {
-        label newPatchI = newPatches[i];
-
         // Pass 1. Do selected side of zone
         // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
@@ -305,7 +317,7 @@ int main(int argc, char *argv[])
                         faceI,                  // label of face
                         mesh.faceOwner()[faceI],// owner
                         false,                  // face flip
-                        newPatchI,              // patch for face
+                        newMasterPatches[i],    // patch for face
                         zoneID.index(),         // zone for face
                         false,                  // face flip in zone
                         modifiedFace            // modify or add status
@@ -321,7 +333,7 @@ int main(int argc, char *argv[])
                         faceI,                      // label of face
                         mesh.faceNeighbour()[faceI],// owner
                         true,                       // face flip
-                        newPatchI,                  // patch for face
+                        newMasterPatches[i],        // patch for face
                         zoneID.index(),             // zone for face
                         true,                       // face flip in zone
                         modifiedFace                // modify or add status
@@ -352,7 +364,7 @@ int main(int argc, char *argv[])
                         faceI,                              // label of face
                         mesh.faceNeighbour()[faceI],        // owner
                         true,                               // face flip
-                        newPatchI,                          // patch for face
+                        newSlavePatches[i],                 // patch for face
                         zoneID.index(),                     // zone for face
                         true,                               // face flip in zone
                         modifiedFace                        // modify or add
@@ -368,7 +380,7 @@ int main(int argc, char *argv[])
                         faceI,                  // label of face
                         mesh.faceOwner()[faceI],// owner
                         false,                  // face flip
-                        newPatchI,              // patch for face
+                        newSlavePatches[i],     // patch for face
                         zoneID.index(),         // zone for face
                         false,                  // face flip in zone
                         modifiedFace            // modify or add status
@@ -396,6 +408,8 @@ int main(int argc, char *argv[])
         {
             const polyPatch& pp = patches[patchI];
 
+            label newPatchI = newMasterPatches[i];
+
             if (pp.coupled() && patches[newPatchI].coupled())
             {
                 // Do not allow coupled faces to be moved to different coupled
@@ -445,7 +459,7 @@ int main(int argc, char *argv[])
 
 
     Info<< "Converted " << returnReduce(nModified, sumOp<label>())
-        << " faces into boundary faces on patch " << patchName << nl << endl;
+        << " faces into boundary faces on patches " << patchNames << nl << endl;
 
     if (!overwrite)
     {
diff --git a/applications/utilities/mesh/manipulation/createPatch/createPatch.C b/applications/utilities/mesh/manipulation/createPatch/createPatch.C
index 8ec77b011125354929c2a85703a10450b581f95b..43652bbbeaeac27c05de5134a3dc84811e6558ad 100644
--- a/applications/utilities/mesh/manipulation/createPatch/createPatch.C
+++ b/applications/utilities/mesh/manipulation/createPatch/createPatch.C
@@ -197,69 +197,55 @@ void dumpCyclicMatch(const fileName& prefix, const polyMesh& mesh)
 
     forAll(patches, patchI)
     {
-        if (isA<cyclicPolyPatch>(patches[patchI]))
+        if
+        (
+            isA<cyclicPolyPatch>(patches[patchI])
+         && refCast<const cyclicPolyPatch>(patches[patchI]).owner()
+        )
         {
             const cyclicPolyPatch& cycPatch =
                 refCast<const cyclicPolyPatch>(patches[patchI]);
 
-            label halfSize = cycPatch.size()/2;
-
-            // Dump halves
+            // Dump patches
             {
-                OFstream str(prefix+cycPatch.name()+"_half0.obj");
+                OFstream str(prefix+cycPatch.name()+".obj");
                 Pout<< "Dumping " << cycPatch.name()
-                    << " half0 faces to " << str.name() << endl;
+                    << " faces to " << str.name() << endl;
                 meshTools::writeOBJ
                 (
                     str,
-                    static_cast<faceList>
-                    (
-                        SubList<face>
-                        (
-                            cycPatch,
-                            halfSize
-                        )
-                    ),
+                    cycPatch,
                     cycPatch.points()
                 );
             }
+
+            const cyclicPolyPatch& nbrPatch = cycPatch.neighbPatch();
             {
-                OFstream str(prefix+cycPatch.name()+"_half1.obj");
-                Pout<< "Dumping " << cycPatch.name()
-                    << " half1 faces to " << str.name() << endl;
+                OFstream str(prefix+nbrPatch.name()+".obj");
+                Pout<< "Dumping " << nbrPatch.name()
+                    << " faces to " << str.name() << endl;
                 meshTools::writeOBJ
                 (
                     str,
-                    static_cast<faceList>
-                    (
-                        SubList<face>
-                        (
-                            cycPatch,
-                            halfSize,
-                            halfSize
-                        )
-                    ),
-                    cycPatch.points()
+                    nbrPatch,
+                    nbrPatch.points()
                 );
             }
 
 
             // Lines between corresponding face centres
-            OFstream str(prefix+cycPatch.name()+"_match.obj");
+            OFstream str(prefix+cycPatch.name()+nbrPatch.name()+"_match.obj");
             label vertI = 0;
 
             Pout<< "Dumping cyclic match as lines between face centres to "
                 << str.name() << endl;
 
-            for (label faceI = 0; faceI < halfSize; faceI++)
+            forAll(cycPatch, faceI)
             {
                 const point& fc0 = mesh.faceCentres()[cycPatch.start()+faceI];
                 meshTools::writeOBJ(str, fc0);
                 vertI++;
-
-                label nbrFaceI = halfSize + faceI;
-                const point& fc1 =
-                    mesh.faceCentres()[cycPatch.start()+nbrFaceI];
+                const point& fc1 = mesh.faceCentres()[nbrPatch.start()+faceI];
                 meshTools::writeOBJ(str, fc1);
                 vertI++;
 
@@ -426,13 +412,19 @@ void syncPoints
     {
         const polyPatch& pp = patches[patchI];
 
-        if (isA<cyclicPolyPatch>(pp))
+        if
+        (
+            isA<cyclicPolyPatch>(pp)
+         && refCast<const cyclicPolyPatch>(pp).owner()
+        )
         {
             const cyclicPolyPatch& cycPatch =
                 refCast<const cyclicPolyPatch>(pp);
 
             const edgeList& coupledPoints = cycPatch.coupledPoints();
             const labelList& meshPts = cycPatch.meshPoints();
+            const cyclicPolyPatch& nbrPatch = cycPatch.neighbPatch();
+            const labelList& nbrMeshPts = nbrPatch.meshPoints();
 
             pointField half0Values(coupledPoints.size());
 
@@ -451,14 +443,13 @@ void syncPoints
             else if (cycPatch.separated())
             {
                 hasTransformation = true;
-                const vectorField& v = cycPatch.coupledPolyPatch::separation();
-                separateList(v, half0Values);
+                separateList(cycPatch.separation(), half0Values);
             }
 
             forAll(coupledPoints, i)
             {
                 const edge& e = coupledPoints[i];
-                label point1 = meshPts[e[1]];
+                label point1 = nbrMeshPts[e[1]];
                 points[point1] = half0Values[i];
             }
         }
@@ -785,13 +776,8 @@ int main(int argc, char *argv[])
         // current separation also includes the normal
         // ( separation_ = (nf&(Cr - Cf))*nf ).
 
-        // For processor patches:
-        // - disallow multiple separation/transformation. This basically
-        //   excludes decomposed cyclics. Use the (probably 0) separation
-        //   to align the points.
         // For cyclic patches:
-        // - for separated ones use our own recalculated offset vector
-        // - for rotational ones use current one.
+        // - for separated ones use user specified offset vector
 
         forAll(mesh.boundaryMesh(), patchI)
         {
@@ -808,13 +794,14 @@ int main(int argc, char *argv[])
                         << " separation[0] was "
                         << cpp.separation()[0] << endl;
 
-                    if (isA<cyclicPolyPatch>(pp))
+                    if (isA<cyclicPolyPatch>(pp) && pp.size())
                     {
                         const cyclicPolyPatch& cycpp =
                             refCast<const cyclicPolyPatch>(pp);
 
                         if (cycpp.transform() == cyclicPolyPatch::TRANSLATIONAL)
                         {
+                            // Force to wanted separation
                             Info<< "On cyclic translation patch " << pp.name()
                                 << " forcing uniform separation of "
                                 << cycpp.separationVector() << endl;
@@ -823,20 +810,16 @@ int main(int argc, char *argv[])
                         }
                         else
                         {
+                            const cyclicPolyPatch& nbr = cycpp.neighbPatch();
                             const_cast<vectorField&>(cpp.separation()) =
                                 pointField
                                 (
                                     1,
-                                    pp[pp.size()/2].centre(mesh.points())
-                                  - pp[0].centre(mesh.points())
+                                    nbr[0].centre(mesh.points())
+                                  - cycpp[0].centre(mesh.points())
                                 );
                         }
                     }
-                    else
-                    {
-                        const_cast<vectorField&>(cpp.separation())
-                        .setSize(1);
-                    }
                     Info<< "On coupled patch " << pp.name()
                         << " forcing uniform separation of "
                         << cpp.separation() << endl;
diff --git a/applications/utilities/mesh/manipulation/renumberMesh/renumberMesh.C b/applications/utilities/mesh/manipulation/renumberMesh/renumberMesh.C
index 80f9b6f93a5c40352f20ad8e058ed9e73413bce9..495e07f2901be7a3aa329a2b83021b7a3cf2cfea 100644
--- a/applications/utilities/mesh/manipulation/renumberMesh/renumberMesh.C
+++ b/applications/utilities/mesh/manipulation/renumberMesh/renumberMesh.C
@@ -305,6 +305,7 @@ autoPtr<mapPolyMesh> reorderMesh
     labelList patchStarts(patches.size());
     labelList oldPatchNMeshPoints(patches.size());
     labelListList patchPointMap(patches.size());
+
     forAll(patches, patchI)
     {
         patchSizes[patchI] = patches[patchI].size();
@@ -320,7 +321,8 @@ autoPtr<mapPolyMesh> reorderMesh
         xferMove(newOwner),
         xferMove(newNeighbour),
         patchSizes,
-        patchStarts
+        patchStarts,
+        true
     );
 
     return autoPtr<mapPolyMesh>
diff --git a/applications/utilities/mesh/manipulation/splitMeshRegions/splitMeshRegions.C b/applications/utilities/mesh/manipulation/splitMeshRegions/splitMeshRegions.C
index 1b38f6b23973cb9db83a65aa9367d496831b4037..e9c20f1afbf34e6d1c31b84f02616e63a69e7727 100644
--- a/applications/utilities/mesh/manipulation/splitMeshRegions/splitMeshRegions.C
+++ b/applications/utilities/mesh/manipulation/splitMeshRegions/splitMeshRegions.C
@@ -560,7 +560,7 @@ void getInterfaceSizes
         label cellI = mesh.faceOwner()[i+mesh.nInternalFaces()];
         coupledRegion[i] = cellRegion[cellI];
     }
-    syncTools::swapBoundaryFaceList(mesh, coupledRegion, false);
+    syncTools::swapBoundaryFaceList(mesh, coupledRegion);
 
     forAll(coupledRegion, i)
     {
@@ -730,7 +730,7 @@ autoPtr<mapPolyMesh> createRegionMesh
         label cellI = mesh.faceOwner()[i+mesh.nInternalFaces()];
         coupledRegion[i] = cellRegion[cellI];
     }
-    syncTools::swapBoundaryFaceList(mesh, coupledRegion, false);
+    syncTools::swapBoundaryFaceList(mesh, coupledRegion);
 
 
     // Topology change container. Start off from existing mesh.
@@ -1300,7 +1300,7 @@ void getZoneID
     {
         neiZoneID[i] = zoneID[mesh.faceOwner()[i+mesh.nInternalFaces()]];
     }
-    syncTools::swapBoundaryFaceList(mesh, neiZoneID, false);
+    syncTools::swapBoundaryFaceList(mesh, neiZoneID);
 }
 
 
diff --git a/applications/utilities/parallelProcessing/decomposePar/decomposePar.C b/applications/utilities/parallelProcessing/decomposePar/decomposePar.C
index c465aa3c3befb513ed63f035b90c817a04840425..b50db4a76ccccb0191a0b4f42898bd6f57d0080d 100644
--- a/applications/utilities/parallelProcessing/decomposePar/decomposePar.C
+++ b/applications/utilities/parallelProcessing/decomposePar/decomposePar.C
@@ -62,7 +62,6 @@ Usage
 #include "OSspecific.H"
 #include "fvCFD.H"
 #include "IOobjectList.H"
-#include "processorFvPatchFields.H"
 #include "domainDecomposition.H"
 #include "labelIOField.H"
 #include "scalarIOField.H"
diff --git a/applications/utilities/parallelProcessing/decomposePar/domainDecomposition.C b/applications/utilities/parallelProcessing/decomposePar/domainDecomposition.C
index b144e757583409c559607482288d43e783f50a47..bcc8bff6c4372333c773e06526127cae6e20aece 100644
--- a/applications/utilities/parallelProcessing/decomposePar/domainDecomposition.C
+++ b/applications/utilities/parallelProcessing/decomposePar/domainDecomposition.C
@@ -28,6 +28,7 @@ License
 #include "dictionary.H"
 #include "labelIOList.H"
 #include "processorPolyPatch.H"
+#include "processorCyclicPolyPatch.H"
 #include "fvMesh.H"
 #include "OSspecific.H"
 #include "Map.H"
@@ -108,7 +109,8 @@ Foam::domainDecomposition::domainDecomposition(const IOobject& io)
     procNeighbourProcessors_(nProcs_),
     procProcessorPatchSize_(nProcs_),
     procProcessorPatchStartIndex_(nProcs_),
-    cyclicParallel_(false)
+    procProcessorPatchSubPatchIDs_(nProcs_),
+    procProcessorPatchSubPatchStarts_(nProcs_)
 {
     if (decompositionDict_.found("distributed"))
     {
@@ -343,12 +345,42 @@ bool Foam::domainDecomposition::writeDecomposition()
         const labelList& curProcessorPatchStarts =
             procProcessorPatchStartIndex_[procI];
 
+        const labelListList& curSubPatchIDs = 
+            procProcessorPatchSubPatchIDs_[procI];
+
+        const labelListList& curSubStarts = 
+            procProcessorPatchSubPatchStarts_[procI];
+
         const polyPatchList& meshPatches = boundaryMesh();
 
+
+        // Count the number of inter-proc patches
+        label nInterProcPatches = 0;
+        forAll(curSubPatchIDs, procPatchI)
+        {
+            Info<< "For processor " << procI
+                << " have to destination processor "
+                << curNeighbourProcessors[procPatchI] << endl;
+
+            forAll(curSubPatchIDs[procPatchI], i)
+            {
+                Info<< "    from patch:" << curSubPatchIDs[procPatchI][i]
+                    << " starting at:" << curSubStarts[procPatchI][i]
+                    << endl;
+            }
+
+            nInterProcPatches += curSubPatchIDs[procPatchI].size();
+        }
+
+        Info<< "For processor " << procI
+            << " have " << nInterProcPatches << " to neighbouring processors"
+            << endl;
+
+
         List<polyPatch*> procPatches
         (
             curPatchSizes.size()
-          + curProcessorPatchSizes.size(),
+          + nInterProcPatches,          //curProcessorPatchSizes.size(),
             reinterpret_cast<polyPatch*>(0)
         );
 
@@ -385,23 +417,84 @@ bool Foam::domainDecomposition::writeDecomposition()
 
         forAll(curProcessorPatchSizes, procPatchI)
         {
-            procPatches[nPatches] =
-                new processorPolyPatch
+            const labelList& subPatchID = curSubPatchIDs[procPatchI];
+            const labelList& subStarts = curSubStarts[procPatchI];
+
+            label curStart = curProcessorPatchStarts[procPatchI];
+
+            forAll(subPatchID, i)
+            {
+                label size =
                 (
-                    word("procBoundary") + Foam::name(procI)
-                  + word("to")
-                  + Foam::name(curNeighbourProcessors[procPatchI]),
-                    curProcessorPatchSizes[procPatchI],
-                    curProcessorPatchStarts[procPatchI],
-                    nPatches,
-                    procMesh.boundaryMesh(),
-                    procI,
-                    curNeighbourProcessors[procPatchI]
-            );
+                    i < subPatchID.size()-1
+                  ? subStarts[i+1] - subStarts[i]
+                  : curProcessorPatchSizes[procPatchI] - subStarts[i]
+                );
 
-            nPatches++;
+                Info<< "From processor:" << procI << endl
+                    << "  to processor:" << curNeighbourProcessors[procPatchI]
+                    << endl
+                    << "    via patch:" << subPatchID[i] << endl
+                    << "    start    :" << curStart << endl
+                    << "    size     :" << size << endl;
+
+                if (subPatchID[i] == -1)
+                {
+                    // From internal faces
+                    procPatches[nPatches] =
+                        new processorPolyPatch
+                        (
+                            word("procBoundary") + Foam::name(procI)
+                          + "to"
+                          + Foam::name(curNeighbourProcessors[procPatchI]),
+                            size,
+                            curStart,
+                            nPatches,
+                            procMesh.boundaryMesh(),
+                            procI,
+                            curNeighbourProcessors[procPatchI]
+                        );
+                }
+                else
+                {
+                    // From cyclic
+                    const word& referPatch =
+                        boundaryMesh()[subPatchID[i]].name();
+
+                    procPatches[nPatches] =
+                        new processorCyclicPolyPatch
+                        (
+                            word("procBoundary") + Foam::name(procI)
+                          + "to"
+                          + Foam::name(curNeighbourProcessors[procPatchI])
+                          + "through"
+                          + referPatch,
+                            size,
+                            curStart,
+                            nPatches,
+                            procMesh.boundaryMesh(),
+                            procI,
+                            curNeighbourProcessors[procPatchI],
+                            referPatch
+                        );
+                }
+
+                curStart += size;
+
+                nPatches++;
+            }
         }
 
+
+forAll(procPatches, patchI)
+{
+    Pout<< "    " << patchI
+        << '\t' << "name:" << procPatches[patchI]->name()
+        << '\t' << "type:" << procPatches[patchI]->type()
+        << '\t' << "size:" << procPatches[patchI]->size()
+        << endl;
+}
+
         // Add boundary patches
         procMesh.addPatches(procPatches);
 
@@ -667,11 +760,7 @@ bool Foam::domainDecomposition::writeDecomposition()
 
         forAll(procMesh.boundaryMesh(), patchi)
         {
-            if
-            (
-                procMesh.boundaryMesh()[patchi].type()
-             == processorPolyPatch::typeName
-            )
+            if (isA<processorPolyPatch>(procMesh.boundaryMesh()[patchi]))
             {
                 const processorPolyPatch& ppp =
                 refCast<const processorPolyPatch>
@@ -749,11 +838,7 @@ bool Foam::domainDecomposition::writeDecomposition()
         // (= identity map for original patches, -1 for processor patches)
         label nMeshPatches = curPatchSizes.size();
         labelList procBoundaryAddressing(identity(nMeshPatches));
-        procBoundaryAddressing.setSize
-        (
-            nMeshPatches+curProcessorPatchSizes.size(),
-            -1
-        );
+        procBoundaryAddressing.setSize(nMeshPatches+nProcPatches, -1);
 
         labelIOList boundaryProcAddressing
         (
diff --git a/applications/utilities/parallelProcessing/decomposePar/domainDecomposition.H b/applications/utilities/parallelProcessing/decomposePar/domainDecomposition.H
index b9dbb74c6fbff5deac8ec0e07fd837c140c22148..d662db75a5096e5fa570f433c964fc0bbeea92b4 100644
--- a/applications/utilities/parallelProcessing/decomposePar/domainDecomposition.H
+++ b/applications/utilities/parallelProcessing/decomposePar/domainDecomposition.H
@@ -29,6 +29,7 @@ Description
 
 SourceFiles
     domainDecomposition.C
+    decomposeMesh.C
 
 \*---------------------------------------------------------------------------*/
 
@@ -78,9 +79,9 @@ class domainDecomposition
         // index is negative, the processor face is the reverse of the
         // original face. In order to do this properly, all face
         // indices will be incremented by 1 and the decremented as
-        // necessary t avoid the problem of face number zero having no
-        // sign.
-        labelListList procFaceAddressing_;
+        // necessary to avoid the problem of face number zero having no
+        // sign.  
+        List<DynamicList<label> > procFaceAddressing_;
 
         //- Labels of cells for each processor
         labelListList procCellAddressing_;
@@ -93,18 +94,23 @@ class domainDecomposition
         // Excludes inter-processor boundaries
         labelListList procPatchStartIndex_;
 
+
+        // Per inter-processor patch information
+
         //- Neighbour processor ID for inter-processor boundaries
         labelListList procNeighbourProcessors_;
 
         //- Sizes for inter-processor patches
         labelListList procProcessorPatchSize_;
 
-        //- Start indices for inter-processor patches
+        //- Start indices (in procFaceAddressing_) for inter-processor patches
         labelListList procProcessorPatchStartIndex_;
 
-        //- Are there cyclic-parallel faces
-        bool cyclicParallel_;
+        //- Sub patch IDs for inter-processor patches
+        List<labelListList> procProcessorPatchSubPatchIDs_;
 
+        //- Sub patch sizes for inter-processor patches
+        List<labelListList> procProcessorPatchSubPatchStarts_;
 
     // Private Member Functions
 
@@ -118,6 +124,21 @@ class domainDecomposition
             labelList& elementToZone
         );
 
+        //- Append single element to list
+        static void append(labelList&, const label);
+
+        //- Add face to interProcessor patch.
+        void addInterProcFace
+        (
+            const label facei,
+            const label ownerProc,
+            const label nbrProc,
+
+            List<Map<label> >&,
+            List<DynamicList<DynamicList<label> > >&
+        ) const;
+
+
 public:
 
     // Constructors
diff --git a/applications/utilities/parallelProcessing/decomposePar/domainDecompositionDistribute.C b/applications/utilities/parallelProcessing/decomposePar/domainDecompositionDistribute.C
index 36ce46e454db12d95b1d108269d1d931b6d4f23b..6adf0639626bd08a62370060d192ae6e33a1de0d 100644
--- a/applications/utilities/parallelProcessing/decomposePar/domainDecompositionDistribute.C
+++ b/applications/utilities/parallelProcessing/decomposePar/domainDecompositionDistribute.C
@@ -26,7 +26,6 @@ License
 #include "domainDecomposition.H"
 #include "decompositionMethod.H"
 #include "cpuTime.H"
-#include "cyclicPolyPatch.H"
 #include "cellSet.H"
 #include "regionSplit.H"
 
diff --git a/applications/utilities/parallelProcessing/decomposePar/domainDecompositionMesh.C b/applications/utilities/parallelProcessing/decomposePar/domainDecompositionMesh.C
index d7487dc58e6ee6cb3b94091a88577638f3aba1fc..4d52a082fff90ffdd9b6bfdfca5fac44197a1039 100644
--- a/applications/utilities/parallelProcessing/decomposePar/domainDecompositionMesh.C
+++ b/applications/utilities/parallelProcessing/decomposePar/domainDecompositionMesh.C
@@ -39,6 +39,63 @@ Description
 
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
+void Foam::domainDecomposition::append(labelList& lst, const label elem)
+{
+    label sz = lst.size();
+    lst.setSize(sz+1);
+    lst[sz] = elem;
+}
+
+
+void Foam::domainDecomposition::addInterProcFace
+(
+    const label facei,
+    const label ownerProc,
+    const label nbrProc,
+
+    List<Map<label> >& nbrToInterPatch,
+    List<DynamicList<DynamicList<label> > >& interPatchFaces
+) const
+{
+    Map<label>::iterator patchIter = nbrToInterPatch[ownerProc].find(nbrProc);
+
+    // Introduce turning index only for internal faces (are duplicated).
+    label ownerIndex = facei+1;
+    label nbrIndex = -(facei+1);
+
+    if (patchIter != nbrToInterPatch[ownerProc].end())
+    {
+        // Existing interproc patch. Add to both sides.
+        label toNbrProcPatchI = patchIter();
+        interPatchFaces[ownerProc][toNbrProcPatchI].append(ownerIndex);
+
+        if (isInternalFace(facei))
+        {
+            label toOwnerProcPatchI = nbrToInterPatch[nbrProc][ownerProc];
+            interPatchFaces[nbrProc][toOwnerProcPatchI].append(nbrIndex);
+        }
+    }
+    else
+    {
+        // Create new interproc patches.
+        label toNbrProcPatchI = nbrToInterPatch[ownerProc].size();
+        nbrToInterPatch[ownerProc].insert(nbrProc, toNbrProcPatchI);
+        DynamicList<label> oneFace;
+        oneFace.append(ownerIndex);
+        interPatchFaces[ownerProc].append(oneFace);
+
+        if (isInternalFace(facei))
+        {
+            label toOwnerProcPatchI = nbrToInterPatch[nbrProc].size();
+            nbrToInterPatch[nbrProc].insert(ownerProc, toOwnerProcPatchI);
+            oneFace.clear();
+            oneFace.append(nbrIndex);
+            interPatchFaces[nbrProc].append(oneFace);
+        }
+    }
+}
+
+
 void Foam::domainDecomposition::decomposeMesh()
 {
     // Decide which cell goes to which processor
@@ -60,31 +117,8 @@ void Foam::domainDecomposition::decomposeMesh()
 
     Info<< "\nDistributing cells to processors" << endl;
 
-    // Memory management
-    {
-        List<SLList<label> > procCellList(nProcs_);
-
-        forAll(cellToProc_, celli)
-        {
-            if (cellToProc_[celli] >= nProcs_)
-            {
-                FatalErrorIn("domainDecomposition::decomposeMesh()")
-                    << "Impossible processor label " << cellToProc_[celli]
-                    << "for cell " << celli
-                    << abort(FatalError);
-            }
-            else
-            {
-                procCellList[cellToProc_[celli]].append(celli);
-            }
-        }
-
-        // Convert linked lists into normal lists
-        forAll(procCellList, procI)
-        {
-            procCellAddressing_[procI] = procCellList[procI];
-        }
-    }
+    // Cells per processor
+    procCellAddressing_ = invertOneToMany(nProcs_, cellToProc_);
 
     Info<< "\nDistributing faces to processors" << endl;
 
@@ -93,503 +127,332 @@ void Foam::domainDecomposition::decomposeMesh()
     // same processor, the face is an internal face. If they are different,
     // it belongs to both processors.
 
-    // Memory management
-    {
-        List<SLList<label> > procFaceList(nProcs_);
+    procFaceAddressing_.setSize(nProcs_);
 
-        forAll(neighbour, facei)
+    // Internal faces
+    forAll (neighbour, facei)
+    {
+        if (cellToProc_[owner[facei]] == cellToProc_[neighbour[facei]])
         {
-            if (cellToProc_[owner[facei]] == cellToProc_[neighbour[facei]])
-            {
-                // Face internal to processor
-                procFaceList[cellToProc_[owner[facei]]].append(facei);
-            }
+            // Face internal to processor. Notice no turning index.
+            procFaceAddressing_[cellToProc_[owner[facei]]].append(facei+1);
         }
+    }
 
-        // Detect inter-processor boundaries
-
-        // Neighbour processor for each subdomain
-        List<SLList<label> > interProcBoundaries(nProcs_);
+    // for all processors, set the size of start index and patch size
+    // lists to the number of patches in the mesh
+    forAll (procPatchSize_, procI)
+    {
+        procPatchSize_[procI].setSize(patches.size());
+        procPatchStartIndex_[procI].setSize(patches.size());
+    }
 
-        // Face labels belonging to each inter-processor boundary
-        List<SLList<SLList<label> > > interProcBFaces(nProcs_);
+    forAll (patches, patchi)
+    {
+        // Reset size and start index for all processors
+        forAll (procPatchSize_, procI)
+        {
+            procPatchSize_[procI][patchi] = 0;
+            procPatchStartIndex_[procI][patchi] =
+                procFaceAddressing_[procI].size();
+        }
 
-        List<SLList<label> > procPatchIndex(nProcs_);
+        const label patchStart = patches[patchi].start();
 
-        forAll(neighbour, facei)
+        if (!isA<cyclicPolyPatch>(patches[patchi]))
         {
-            if (cellToProc_[owner[facei]] != cellToProc_[neighbour[facei]])
-            {
-                // inter - processor patch face found. Go through the list of
-                // inside boundaries for the owner processor and try to find
-                // this inter-processor patch.
+            // Normal patch. Add faces to processor where the cell
+            // next to the face lives
 
-                label ownerProc = cellToProc_[owner[facei]];
-                label neighbourProc = cellToProc_[neighbour[facei]];
+            const unallocLabelList& patchFaceCells =
+                patches[patchi].faceCells();
 
-                SLList<label>::iterator curInterProcBdrsOwnIter =
-                    interProcBoundaries[ownerProc].begin();
+            forAll (patchFaceCells, facei)
+            {
+                const label curProc = cellToProc_[patchFaceCells[facei]];
 
-                SLList<SLList<label> >::iterator curInterProcBFacesOwnIter =
-                    interProcBFaces[ownerProc].begin();
+                // add the face without turning index
+                procFaceAddressing_[curProc].append(patchStart+facei+1);
 
-                bool interProcBouFound = false;
+                // increment the number of faces for this patch
+                procPatchSize_[curProc][patchi]++;
+            }
+        }
+        else
+        {
+            const cyclicPolyPatch& pp = refCast<const cyclicPolyPatch>
+            (
+                patches[patchi]
+            );
+            // cyclic: check opposite side on this processor
+            const unallocLabelList& patchFaceCells = pp.faceCells();
 
-                // WARNING: Synchronous SLList iterators
+            const unallocLabelList& nbrPatchFaceCells =
+                pp.neighbPatch().faceCells();
 
-                for
-                (
-                    ;
-                    curInterProcBdrsOwnIter
-                 != interProcBoundaries[ownerProc].end()
-                 && curInterProcBFacesOwnIter
-                 != interProcBFaces[ownerProc].end();
-                    ++curInterProcBdrsOwnIter, ++curInterProcBFacesOwnIter
-                )
+            forAll (patchFaceCells, facei)
+            {
+                const label curProc = cellToProc_[patchFaceCells[facei]];
+                const label nbrProc = cellToProc_[nbrPatchFaceCells[facei]];
+                if (curProc == nbrProc)
                 {
-                    if (curInterProcBdrsOwnIter() == neighbourProc)
-                    {
-                        // the inter - processor boundary exists. Add the face
-                        interProcBouFound = true;
-
-                        curInterProcBFacesOwnIter().append(facei);
-
-                        SLList<label>::iterator curInterProcBdrsNeiIter =
-                            interProcBoundaries[neighbourProc].begin();
-
-                        SLList<SLList<label> >::iterator
-                            curInterProcBFacesNeiIter =
-                            interProcBFaces[neighbourProc].begin();
-
-                        bool neighbourFound = false;
-
-                        // WARNING: Synchronous SLList iterators
-
-                        for
-                        (
-                            ;
-                            curInterProcBdrsNeiIter !=
-                            interProcBoundaries[neighbourProc].end()
-                         && curInterProcBFacesNeiIter !=
-                            interProcBFaces[neighbourProc].end();
-                            ++curInterProcBdrsNeiIter,
-                            ++curInterProcBFacesNeiIter
-                        )
-                        {
-                            if (curInterProcBdrsNeiIter() == ownerProc)
-                            {
-                                // boundary found. Add the face
-                                neighbourFound = true;
-
-                                curInterProcBFacesNeiIter().append(facei);
-                            }
-
-                            if (neighbourFound) break;
-                        }
-
-                        if (interProcBouFound && !neighbourFound)
-                        {
-                            FatalErrorIn("domainDecomposition::decomposeMesh()")
-                                << "Inconsistency in inter - "
-                                << "processor boundary lists for processors "
-                                << ownerProc << " and " << neighbourProc
-                                << abort(FatalError);
-                        }
-                    }
-
-                    if (interProcBouFound) break;
+                    // add the face without turning index
+                    procFaceAddressing_[curProc].append(patchStart+facei+1);
+                    // increment the number of faces for this patch
+                    procPatchSize_[curProc][patchi]++;
                 }
+            }
+        }
+    }
 
-                if (!interProcBouFound)
-                {
-                    // inter - processor boundaries do not exist and need to
-                    // be created
 
-                    // set the new addressing information
+    // Done internal bits of the new mesh and the ordinary patches.
 
-                    // owner
-                    interProcBoundaries[ownerProc].append(neighbourProc);
-                    interProcBFaces[ownerProc].append(SLList<label>(facei));
 
-                    // neighbour
-                    interProcBoundaries[neighbourProc].append(ownerProc);
-                    interProcBFaces[neighbourProc].append(SLList<label>(facei));
-                }
-            }
-        }
+    // Per processor, from neighbour processor to the interprocessorpatch that
+    // communicates with that neighbour.
+    List<Map<label> > procNbrToInterPatch(nProcs_);
+    // Per processor the faces per interprocessorpatch.
+    List<DynamicList<DynamicList<label> > > interPatchFaces(nProcs_);
 
-        // Loop through patches. For cyclic boundaries detect inter-processor
-        // faces; for all other, add faces to the face list and remember start
-        // and size of all patches.
+    // Processor boundaries from internal faces
+    forAll (neighbour, facei)
+    {
+        label ownerProc = cellToProc_[owner[facei]];
+        label nbrProc = cellToProc_[neighbour[facei]];
 
-        // for all processors, set the size of start index and patch size
-        // lists to the number of patches in the mesh
-        forAll(procPatchSize_, procI)
+        if (ownerProc != nbrProc)
         {
-            procPatchSize_[procI].setSize(patches.size());
-            procPatchStartIndex_[procI].setSize(patches.size());
+            // inter - processor patch face found.
+            addInterProcFace
+            (
+                facei,
+                ownerProc,
+                nbrProc,
+
+                procNbrToInterPatch,
+                interPatchFaces
+            );
         }
+    }
 
-        forAll(patches, patchi)
+    // Add the proper processor faces to the sub information. For faces
+    // originating from internal faces this is always -1.
+    List<labelListList> subPatchIDs(nProcs_);
+    List<labelListList> subPatchStarts(nProcs_);
+    forAll(interPatchFaces, procI)
+    {
+        label nInterfaces = interPatchFaces[procI].size();
+
+        subPatchIDs[procI].setSize(nInterfaces, labelList(1, -1));
+        subPatchStarts[procI].setSize(nInterfaces, labelList(1, 0));
+    }
+
+    // Processor boundaries from split cyclics
+    forAll (patches, patchi)
+    {
+        if (isA<cyclicPolyPatch>(patches[patchi]))
         {
-            // Reset size and start index for all processors
-            forAll(procPatchSize_, procI)
-            {
-                procPatchSize_[procI][patchi] = 0;
-                procPatchStartIndex_[procI][patchi] =
-                    procFaceList[procI].size();
-            }
+            const cyclicPolyPatch& pp = refCast<const cyclicPolyPatch>
+            (
+                patches[patchi]
+            );
 
-            const label patchStart = patches[patchi].start();
+            // cyclic: check opposite side on this processor
+            const unallocLabelList& patchFaceCells = pp.faceCells();
+            const unallocLabelList& nbrPatchFaceCells =
+                pp.neighbPatch().faceCells();
 
-            if (!isA<cyclicPolyPatch>(patches[patchi]))
+            // Store old sizes. Used to detect which inter-proc patches
+            // have been added to.
+            labelListList oldInterfaceSizes(nProcs_);
+            forAll(oldInterfaceSizes, procI)
             {
-                // Normal patch. Add faces to processor where the cell
-                // next to the face lives
-
-                const unallocLabelList& patchFaceCells =
-                    patches[patchi].faceCells();
+                labelList& curOldSizes = oldInterfaceSizes[procI];
 
-                forAll(patchFaceCells, facei)
+                curOldSizes.setSize(interPatchFaces[procI].size());
+                forAll(curOldSizes, interI)
                 {
-                    const label curProc = cellToProc_[patchFaceCells[facei]];
-
-                    // add the face
-                    procFaceList[curProc].append(patchStart + facei);
-
-                    // increment the number of faces for this patch
-                    procPatchSize_[curProc][patchi]++;
+                    curOldSizes[interI] =
+                        interPatchFaces[procI][interI].size();
                 }
             }
-            else
-            {
-                // Cyclic patch special treatment
-
-                const polyPatch& cPatch = patches[patchi];
-
-                const label cycOffset = cPatch.size()/2;
-
-                // Set reference to faceCells for both patches
-                const labelList::subList firstFaceCells
-                (
-                    cPatch.faceCells(),
-                    cycOffset
-                );
-
-                const labelList::subList secondFaceCells
-                (
-                    cPatch.faceCells(),
-                    cycOffset,
-                    cycOffset
-                );
 
-                forAll(firstFaceCells, facei)
+            // Add faces with different owner and neighbour processors
+            forAll (patchFaceCells, facei)
+            {
+                const label ownerProc = cellToProc_[patchFaceCells[facei]];
+                const label nbrProc = cellToProc_[nbrPatchFaceCells[facei]];
+                if (ownerProc != nbrProc)
                 {
-                    if
+                    // inter - processor patch face found.
+                    addInterProcFace
                     (
-                        cellToProc_[firstFaceCells[facei]]
-                     != cellToProc_[secondFaceCells[facei]]
-                    )
-                    {
-                        // This face becomes an inter-processor boundary face
-                        // inter - processor patch face found. Go through
-                        // the list of inside boundaries for the owner
-                        // processor and try to find this inter-processor
-                        // patch.
-
-                        cyclicParallel_ = true;
-
-                        label ownerProc = cellToProc_[firstFaceCells[facei]];
-                        label neighbourProc =
-                            cellToProc_[secondFaceCells[facei]];
-
-                        SLList<label>::iterator curInterProcBdrsOwnIter =
-                            interProcBoundaries[ownerProc].begin();
-
-                        SLList<SLList<label> >::iterator
-                            curInterProcBFacesOwnIter =
-                            interProcBFaces[ownerProc].begin();
-
-                        bool interProcBouFound = false;
-
-                        // WARNING: Synchronous SLList iterators
-
-                        for
-                        (
-                            ;
-                            curInterProcBdrsOwnIter !=
-                            interProcBoundaries[ownerProc].end()
-                         && curInterProcBFacesOwnIter !=
-                            interProcBFaces[ownerProc].end();
-                            ++curInterProcBdrsOwnIter,
-                            ++curInterProcBFacesOwnIter
-                        )
-                        {
-                            if (curInterProcBdrsOwnIter() == neighbourProc)
-                            {
-                                // the inter - processor boundary exists.
-                                // Add the face
-                                interProcBouFound = true;
-
-                                curInterProcBFacesOwnIter().append
-                                    (patchStart + facei);
-
-                                SLList<label>::iterator curInterProcBdrsNeiIter
-                                   = interProcBoundaries[neighbourProc].begin();
-
-                                SLList<SLList<label> >::iterator
-                                    curInterProcBFacesNeiIter =
-                                    interProcBFaces[neighbourProc].begin();
-
-                                bool neighbourFound = false;
-
-                                // WARNING: Synchronous SLList iterators
-
-                                for
-                                (
-                                    ;
-                                    curInterProcBdrsNeiIter
-                                   != interProcBoundaries[neighbourProc].end()
-                                 && curInterProcBFacesNeiIter
-                                   != interProcBFaces[neighbourProc].end();
-                                    ++curInterProcBdrsNeiIter,
-                                    ++curInterProcBFacesNeiIter
-                                )
-                                {
-                                    if (curInterProcBdrsNeiIter() == ownerProc)
-                                    {
-                                        // boundary found. Add the face
-                                        neighbourFound = true;
-
-                                        curInterProcBFacesNeiIter()
-                                            .append
-                                            (
-                                                patchStart
-                                              + cycOffset
-                                              + facei
-                                            );
-                                    }
-
-                                    if (neighbourFound) break;
-                                }
-
-                                if (interProcBouFound && !neighbourFound)
-                                {
-                                    FatalErrorIn
-                                    (
-                                        "domainDecomposition::decomposeMesh()"
-                                    )   << "Inconsistency in inter-processor "
-                                        << "boundary lists for processors "
-                                        << ownerProc << " and " << neighbourProc
-                                        << " in cyclic boundary matching"
-                                        << abort(FatalError);
-                                }
-                            }
-
-                            if (interProcBouFound) break;
-                        }
-
-                        if (!interProcBouFound)
-                        {
-                            // inter - processor boundaries do not exist
-                            // and need to be created
-
-                            // set the new addressing information
-
-                            // owner
-                            interProcBoundaries[ownerProc]
-                                .append(neighbourProc);
-                            interProcBFaces[ownerProc]
-                                .append(SLList<label>(patchStart + facei));
-
-                            // neighbour
-                            interProcBoundaries[neighbourProc]
-                                .append(ownerProc);
-                            interProcBFaces[neighbourProc]
-                                .append
-                                (
-                                    SLList<label>
-                                    (
-                                        patchStart
-                                      + cycOffset
-                                      + facei
-                                    )
-                                );
-                        }
-                    }
-                    else
-                    {
-                        // This cyclic face remains on the processor
-                        label ownerProc = cellToProc_[firstFaceCells[facei]];
-
-                        // add the face
-                        procFaceList[ownerProc].append(patchStart + facei);
-
-                        // increment the number of faces for this patch
-                        procPatchSize_[ownerProc][patchi]++;
-
-                        // Note: I cannot add the other side of the cyclic
-                        // boundary here because this would violate the order.
-                        // They will be added in a separate loop below
-                        //
-                    }
+                        pp.start()+facei,
+                        ownerProc,
+                        nbrProc,
+                        procNbrToInterPatch,
+                        interPatchFaces
+                    );
                 }
+            }
 
-                // Ordering in cyclic boundaries is important.
-                // Add the other half of cyclic faces for cyclic boundaries
-                // that remain on the processor
-                forAll(secondFaceCells, facei)
+            // 1. Check if any faces added to existing interfaces
+            forAll(oldInterfaceSizes, procI)
+            {
+                const labelList& curOldSizes = oldInterfaceSizes[procI];
+
+                forAll(curOldSizes, interI)
                 {
-                    if
-                    (
-                        cellToProc_[firstFaceCells[facei]]
-                     == cellToProc_[secondFaceCells[facei]]
-                    )
+                    label oldSz = curOldSizes[interI];
+                    if (interPatchFaces[procI][interI].size() > oldSz)
                     {
-                        // This cyclic face remains on the processor
-                        label ownerProc = cellToProc_[firstFaceCells[facei]];
-
-                        // add the second face
-                        procFaceList[ownerProc].append
-                            (patchStart + cycOffset + facei);
-
-                        // increment the number of faces for this patch
-                        procPatchSize_[ownerProc][patchi]++;
+                        // Added faces to this interface. Add an entry
+                        append(subPatchIDs[procI][interI], patchi);
+                        append(subPatchStarts[procI][interI], oldSz);
                     }
                 }
             }
-        }
 
-        // Convert linked lists into normal lists
-        // Add inter-processor boundaries and remember start indices
-        forAll(procFaceList, procI)
-        {
-            // Get internal and regular boundary processor faces
-            SLList<label>& curProcFaces = procFaceList[procI];
+            // 2. Any new interfaces
+            forAll(subPatchIDs, procI)
+            {
+                label nIntfcs = interPatchFaces[procI].size();
+                subPatchIDs[procI].setSize(nIntfcs, labelList(1, patchi));
+                subPatchStarts[procI].setSize(nIntfcs, labelList(1, 0));
+            }
+        }
+    }
 
-            // Get reference to processor face addressing
-            labelList& curProcFaceAddressing = procFaceAddressing_[procI];
 
-            labelList& curProcNeighbourProcessors =
-                procNeighbourProcessors_[procI];
+    // Shrink processor patch face addressing
+    forAll(interPatchFaces, procI)
+    {
+        DynamicList<DynamicList<label> >& curInterPatchFaces =
+            interPatchFaces[procI];
 
-            labelList& curProcProcessorPatchSize =
-                procProcessorPatchSize_[procI];
+        forAll(curInterPatchFaces, i)
+        {
+            curInterPatchFaces[i].shrink();
+        }
+        curInterPatchFaces.shrink();
+    }
 
-            labelList& curProcProcessorPatchStartIndex =
-                procProcessorPatchStartIndex_[procI];
 
-            // calculate the size
-            label nFacesOnProcessor = curProcFaces.size();
+    // Sort inter-proc patch by neighbour
+    labelList order;
+    forAll(procNbrToInterPatch, procI)
+    {
+        label nInterfaces = procNbrToInterPatch[procI].size();
 
-            for
-            (
-                SLList<SLList<label> >::iterator curInterProcBFacesIter =
-                    interProcBFaces[procI].begin();
-                curInterProcBFacesIter != interProcBFaces[procI].end();
-                ++curInterProcBFacesIter
-            )
-            {
-                nFacesOnProcessor += curInterProcBFacesIter().size();
-            }
+        procNeighbourProcessors_[procI].setSize(nInterfaces);
+        procProcessorPatchSize_[procI].setSize(nInterfaces);
+        procProcessorPatchStartIndex_[procI].setSize(nInterfaces);
+        procProcessorPatchSubPatchIDs_[procI].setSize(nInterfaces);
+        procProcessorPatchSubPatchStarts_[procI].setSize(nInterfaces);
 
-            curProcFaceAddressing.setSize(nFacesOnProcessor);
+        Info<< "Processor " << procI << endl;
 
-            // Fill in the list. Calculate turning index.
-            // Turning index will be -1 only for some faces on processor
-            // boundaries, i.e. the ones where the current processor ID
-            // is in the cell which is a face neighbour.
-            // Turning index is stored as the sign of the face addressing list
+        // Get sorted neighbour processors
+        const Map<label>& curNbrToInterPatch = procNbrToInterPatch[procI];
+        labelList nbrs = curNbrToInterPatch.toc();
+        sortedOrder(nbrs, order);
 
-            label nFaces = 0;
+        DynamicList<DynamicList<label> >& curInterPatchFaces =
+            interPatchFaces[procI];
 
-            // Add internal and boundary faces
-            // Remember to increment the index by one such that the
-            // turning index works properly.
-            forAllConstIter(SLList<label>, curProcFaces, curProcFacesIter)
-            {
-                curProcFaceAddressing[nFaces] = curProcFacesIter() + 1;
-                nFaces++;
-            }
+        forAll(order, i)
+        {
+            const label nbrProc = nbrs[i];
+            const label interPatch = curNbrToInterPatch[nbrProc];
 
-            // Add inter-processor boundary faces. At the beginning of each
-            // patch, grab the patch start index and size
+            procNeighbourProcessors_[procI][i] = nbrProc;
+            procProcessorPatchSize_[procI][i] = curInterPatchFaces[i].size();
+            procProcessorPatchStartIndex_[procI][i] =
+                procFaceAddressing_[procI].size();
 
-            curProcNeighbourProcessors.setSize
+            // Add size as last element to substarts and transfer
+            append
             (
-                interProcBoundaries[procI].size()
+                subPatchStarts[procI][interPatch],
+                curInterPatchFaces[interPatch].size()
             );
-
-            curProcProcessorPatchSize.setSize
+            procProcessorPatchSubPatchIDs_[procI][i].transfer
             (
-                interProcBoundaries[procI].size()
+                subPatchIDs[procI][interPatch]
             );
-
-            curProcProcessorPatchStartIndex.setSize
+            procProcessorPatchSubPatchStarts_[procI][i].transfer
             (
-                interProcBoundaries[procI].size()
+                subPatchStarts[procI][interPatch]
             );
 
-            label nProcPatches = 0;
-
-            SLList<label>::iterator curInterProcBdrsIter =
-                interProcBoundaries[procI].begin();
-
-            SLList<SLList<label> >::iterator curInterProcBFacesIter =
-                interProcBFaces[procI].begin();
-
-            for
-            (
-                ;
-                curInterProcBdrsIter != interProcBoundaries[procI].end()
-             && curInterProcBFacesIter != interProcBFaces[procI].end();
-                ++curInterProcBdrsIter, ++curInterProcBFacesIter
-            )
+            Info<< "    nbr:" << nbrProc << endl;
+            Info<< "    interpatch:" << interPatch << endl;
+            Info<< "    size:" << procProcessorPatchSize_[procI][i] << endl;
+            Info<< "    start:" << procProcessorPatchStartIndex_[procI][i]
+                << endl;
+            Info<< "    subPatches:" << procProcessorPatchSubPatchIDs_[procI][i]
+                << endl;
+            Info<< "    subStarts:"
+                << procProcessorPatchSubPatchStarts_[procI][i] << endl;
+
+            // And add all the face labels for interPatch
+            DynamicList<label>& interPatchFaces =
+                curInterPatchFaces[interPatch];
+
+            forAll(interPatchFaces, j)
             {
-                curProcNeighbourProcessors[nProcPatches] =
-                    curInterProcBdrsIter();
-
-                // Get start index for processor patch
-                curProcProcessorPatchStartIndex[nProcPatches] = nFaces;
-
-                label& curSize =
-                    curProcProcessorPatchSize[nProcPatches];
+                procFaceAddressing_[procI].append(interPatchFaces[j]);
+            }
+            interPatchFaces.clearStorage();
+        }
+        curInterPatchFaces.clearStorage();
+        procFaceAddressing_[procI].shrink();
+    }
 
-                curSize = 0;
 
-                // add faces for this processor boundary
+//XXXXXXX
+// Print a bit
+    forAll(procPatchStartIndex_, procI)
+    {
+        Info<< "Processor:" << procI << endl;
 
-                forAllConstIter
-                (
-                    SLList<label>,
-                    curInterProcBFacesIter(),
-                    curFacesIter
-                )
-                {
-                    // add the face
+        Info<< "    total faces:" << procFaceAddressing_[procI].size() << endl;
 
-                    // Remember to increment the index by one such that the
-                    // turning index works properly.
-                    if (cellToProc_[owner[curFacesIter()]] == procI)
-                    {
-                        curProcFaceAddressing[nFaces] = curFacesIter() + 1;
-                    }
-                    else
-                    {
-                        // turning face
-                        curProcFaceAddressing[nFaces] = -(curFacesIter() + 1);
-                    }
+        const labelList& curProcPatchStartIndex = procPatchStartIndex_[procI];
 
-                    // increment the size
-                    curSize++;
+        forAll(curProcPatchStartIndex, patchI)
+        {
+            Info<< "    patch:" << patchI
+                << "\tstart:" << curProcPatchStartIndex[patchI]
+                << "\tsize:" << procPatchSize_[procI][patchI]
+                << endl;
+        }
+    }
+    Info<< endl;
 
-                    nFaces++;
-                }
+    forAll(procNeighbourProcessors_, procI)
+    {
+        Info<< "Processor " << procI << endl;
 
-                nProcPatches++;
-            }
+        forAll(procNeighbourProcessors_[procI], i)
+        {
+            Info<< "    nbr:" << procNeighbourProcessors_[procI][i] << endl;
+            Info<< "    size:" << procProcessorPatchSize_[procI][i] << endl;
+            Info<< "    start:" << procProcessorPatchStartIndex_[procI][i]
+                << endl;
         }
     }
+    Info<< endl;
+
+//    forAll(procFaceAddressing_, procI)
+//    {
+//        Info<< "Processor:" << procI << endl;
+//
+//        Info<< "    faces:" << procFaceAddressing_[procI] << endl;
+//    }
+
+
 
     Info<< "\nDistributing points to processors" << endl;
     // For every processor, loop through the list of faces for the processor.
diff --git a/applications/utilities/parallelProcessing/decomposePar/fvFieldDecomposer.C b/applications/utilities/parallelProcessing/decomposePar/fvFieldDecomposer.C
index 25bcd3495fe38be562d223dd3c2f5a29a1cdbe7c..52582832cf650f76fc44469ca9f18671a0edf678 100644
--- a/applications/utilities/parallelProcessing/decomposePar/fvFieldDecomposer.C
+++ b/applications/utilities/parallelProcessing/decomposePar/fvFieldDecomposer.C
@@ -144,7 +144,11 @@ Foam::fvFieldDecomposer::fvFieldDecomposer
 {
     forAll(boundaryAddressing_, patchi)
     {
-        if (boundaryAddressing_[patchi] >= 0)
+        if
+        (
+            boundaryAddressing_[patchi] >= 0
+        && !isA<processorLduInterface>(procMesh.boundary()[patchi])
+        )
         {
             patchFieldDecomposerPtrs_[patchi] = new patchFieldDecomposer
             (
diff --git a/applications/utilities/parallelProcessing/decomposePar/fvFieldDecomposerDecomposeFields.C b/applications/utilities/parallelProcessing/decomposePar/fvFieldDecomposerDecomposeFields.C
index c70f724221ecaebbefb64bf19054426f68831b07..190e7f8e1cf35a1d81f1a60cc52b7a57dc976cc9 100644
--- a/applications/utilities/parallelProcessing/decomposePar/fvFieldDecomposerDecomposeFields.C
+++ b/applications/utilities/parallelProcessing/decomposePar/fvFieldDecomposerDecomposeFields.C
@@ -26,6 +26,8 @@ License
 #include "fvFieldDecomposer.H"
 #include "processorFvPatchField.H"
 #include "processorFvsPatchField.H"
+#include "processorCyclicFvPatchField.H"
+#include "processorCyclicFvsPatchField.H"
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
@@ -44,7 +46,7 @@ Foam::fvFieldDecomposer::decomposeField
 
     forAll(boundaryAddressing_, patchi)
     {
-        if (boundaryAddressing_[patchi] >= 0)
+        if (patchFieldDecomposerPtrs_[patchi])
         {
             patchFields.set
             (
@@ -58,7 +60,24 @@ Foam::fvFieldDecomposer::decomposeField
                 )
             );
         }
-        else
+        else if (isA<processorCyclicFvPatch>(procMesh_.boundary()[patchi]))
+        {
+            patchFields.set
+            (
+                patchi,
+                new processorCyclicFvPatchField<Type>
+                (
+                    procMesh_.boundary()[patchi],
+                    DimensionedField<Type, volMesh>::null(),
+                    Field<Type>
+                    (
+                        field.internalField(),
+                        *processorVolPatchFieldDecomposerPtrs_[patchi]
+                    )
+                )
+            );
+        }
+        else if (isA<processorFvPatch>(procMesh_.boundary()[patchi]))
         {
             patchFields.set
             (
@@ -75,6 +94,11 @@ Foam::fvFieldDecomposer::decomposeField
                 )
             );
         }
+        else
+        {
+            FatalErrorIn("fvFieldDecomposer::decomposeField()")
+                << "Unknown type." << abort(FatalError);
+        }
     }
 
     // Create the field for the processor
@@ -155,7 +179,7 @@ Foam::fvFieldDecomposer::decomposeField
 
     forAll(boundaryAddressing_, patchi)
     {
-        if (boundaryAddressing_[patchi] >= 0)
+        if (patchFieldDecomposerPtrs_[patchi])
         {
             patchFields.set
             (
@@ -169,7 +193,24 @@ Foam::fvFieldDecomposer::decomposeField
                 )
             );
         }
-        else
+        else if (isA<processorCyclicFvPatch>(procMesh_.boundary()[patchi]))
+        {
+            patchFields.set
+            (
+                patchi,
+                new processorCyclicFvsPatchField<Type>
+                (
+                    procMesh_.boundary()[patchi],
+                    DimensionedField<Type, surfaceMesh>::null(),
+                    Field<Type>
+                    (
+                        allFaceField,
+                        *processorSurfacePatchFieldDecomposerPtrs_[patchi]
+                    )
+                )
+            );
+        }
+        else if (isA<processorFvPatch>(procMesh_.boundary()[patchi]))
         {
             patchFields.set
             (
@@ -186,6 +227,11 @@ Foam::fvFieldDecomposer::decomposeField
                 )
             );
         }
+        else
+        {
+            FatalErrorIn("fvFieldDecomposer::decomposeField()")
+                << "Unknown type." << abort(FatalError);
+        }
     }
 
     // Create the field for the processor
diff --git a/applications/utilities/postProcessing/miscellaneous/postChannel/channelIndex.C b/applications/utilities/postProcessing/miscellaneous/postChannel/channelIndex.C
index 009e28329e39fb75517a2ba1c204285b44955904..26c8f4ed8af3922404b542abc9ca7d6e7910b862 100644
--- a/applications/utilities/postProcessing/miscellaneous/postChannel/channelIndex.C
+++ b/applications/utilities/postProcessing/miscellaneous/postChannel/channelIndex.C
@@ -79,7 +79,7 @@ void Foam::channelIndex::walkOppositeFaces
                 isFrontBndFace[faceI-mesh.nInternalFaces()] = true;
             }
         }
-        syncTools::swapBoundaryFaceList(mesh, isFrontBndFace, false);
+        syncTools::swapBoundaryFaceList(mesh, isFrontBndFace);
 
         // Add
         forAll(isFrontBndFace, i)
diff --git a/applications/utilities/postProcessing/patch/patchIntegrate/patchIntegrate.C b/applications/utilities/postProcessing/patch/patchIntegrate/patchIntegrate.C
index 9dbe43a8b3ec07e5069e92c26776908fa74a1081..5c735492c7aec989602d2e2bbd6844e91ebbcb6b 100644
--- a/applications/utilities/postProcessing/patch/patchIntegrate/patchIntegrate.C
+++ b/applications/utilities/postProcessing/patch/patchIntegrate/patchIntegrate.C
@@ -30,7 +30,6 @@ Description
 \*---------------------------------------------------------------------------*/
 
 #include "fvCFD.H"
-#include "cyclicPolyPatch.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 // Main program:
@@ -76,35 +75,12 @@ int main(int argc, char *argv[])
             }
 
             // Give patch area
-            if (isA<cyclicPolyPatch>(mesh.boundaryMesh()[patchI]))
-            {
-                Info<< "    Cyclic patch vector area: " << nl;
-                label nFaces = mesh.boundaryMesh()[patchI].size();
-                vector sum1 = vector::zero;
-                vector sum2 = vector::zero;
-                for (label i=0; i<nFaces/2; i++)
-                {
-                    sum1 += mesh.Sf().boundaryField()[patchI][i];
-                    sum2 += mesh.Sf().boundaryField()[patchI][i+nFaces/2];
-                }
-                reduce(sum1, sumOp<vector>());
-                reduce(sum2, sumOp<vector>());
-                Info<< "    - half 1 = " << sum1 << ", " << mag(sum1) << nl
-                    << "    - half 2 = " << sum2 << ", " << mag(sum2) << nl
-                    << "    - total  = " << (sum1 + sum2) << ", "
-                    << mag(sum1 + sum2) << endl;
-                Info<< "    Cyclic patch area magnitude = "
-                    << gSum(mesh.magSf().boundaryField()[patchI])/2.0 << endl;
-            }
-            else
-            {
-                Info<< "    Area vector of patch "
-                    << patchName << '[' << patchI << ']' << " = "
-                    << gSum(mesh.Sf().boundaryField()[patchI]) << endl;
-                Info<< "    Area magnitude of patch "
-                    << patchName << '[' << patchI << ']' << " = "
-                    << gSum(mesh.magSf().boundaryField()[patchI]) << endl;
-            }
+            Info<< "    Area vector of patch "
+                << patchName << '[' << patchI << ']' << " = "
+                << gSum(mesh.Sf().boundaryField()[patchI]) << endl;
+            Info<< "    Area magnitude of patch "
+                << patchName << '[' << patchI << ']' << " = "
+                << gSum(mesh.magSf().boundaryField()[patchI]) << endl;
 
             // Read field and calc integral
             if (fieldHeader.headerClassName() == volScalarField::typeName)
diff --git a/applications/utilities/preProcessing/foamUpgradeCyclics/Make/files b/applications/utilities/preProcessing/foamUpgradeCyclics/Make/files
new file mode 100644
index 0000000000000000000000000000000000000000..9b58821d1704ff46dbe851360bbafb8840ef068c
--- /dev/null
+++ b/applications/utilities/preProcessing/foamUpgradeCyclics/Make/files
@@ -0,0 +1,3 @@
+foamUpgradeCyclics.C
+
+EXE = $(FOAM_APPBIN)/foamUpgradeCyclics
diff --git a/applications/utilities/preProcessing/foamUpgradeCyclics/Make/options b/applications/utilities/preProcessing/foamUpgradeCyclics/Make/options
new file mode 100644
index 0000000000000000000000000000000000000000..93ae287538b0547faa2570f8f832561d6e06c149
--- /dev/null
+++ b/applications/utilities/preProcessing/foamUpgradeCyclics/Make/options
@@ -0,0 +1,6 @@
+EXE_INC = \
+    -I$(LIB_SRC)/finiteVolume/lnInclude 
+
+EXE_LIBS = \
+    -lfiniteVolume \
+    -lgenericPatchFields
diff --git a/applications/utilities/preProcessing/foamUpgradeCyclics/foamUpgradeCyclics.C b/applications/utilities/preProcessing/foamUpgradeCyclics/foamUpgradeCyclics.C
new file mode 100644
index 0000000000000000000000000000000000000000..cce68316c0c3870b2831dd38cd8a3063ee0ad8b4
--- /dev/null
+++ b/applications/utilities/preProcessing/foamUpgradeCyclics/foamUpgradeCyclics.C
@@ -0,0 +1,620 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
+     \\/     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 2 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, write to the Free Software Foundation,
+    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+Application
+    foamUpgradeCyclics
+
+Description
+    Tool to upgrade mesh and fields for split cyclics
+
+Usage
+
+    - foamUpgradeCyclics [OPTION]
+
+    @param -test \n
+    Suppress writing the updated files with split cyclics
+
+\*---------------------------------------------------------------------------*/
+
+#include "argList.H"
+#include "Time.H"
+#include "timeSelector.H"
+#include "IOdictionary.H"
+#include "polyMesh.H"
+#include "entry.H"
+#include "IOPtrList.H"
+#include "cyclicPolyPatch.H"
+#include "dictionaryEntry.H"
+#include "IOobjectList.H"
+#include "volFields.H"
+#include "pointFields.H"
+#include "surfaceFields.H"
+#include "string.H"
+
+using namespace Foam;
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+    defineTemplateTypeNameAndDebug(IOPtrList<entry>, 0);
+}
+
+
+// Read boundary file without reading mesh
+void rewriteBoundary
+(
+    const bool isTestRun,
+    const IOobject& io,
+    const fileName& regionPrefix,
+    HashTable<word>& thisNames,
+    HashTable<word>& nbrNames
+)
+{
+    Info<< "Reading boundary from " << io.filePath() << endl;
+
+    // Read PtrList of dictionary.
+    const word oldTypeName = IOPtrList<entry>::typeName;
+    const_cast<word&>(IOPtrList<entry>::typeName) = word::null;
+    IOPtrList<entry> patches(io);
+    const_cast<word&>(IOPtrList<entry>::typeName) = oldTypeName;
+    // Fake type back to what was in field
+    const_cast<word&>(patches.type()) = patches.headerClassName();
+
+
+    // Replace any 'cyclic'
+    label nOldCyclics = 0;
+    forAll(patches, patchI)
+    {
+        const dictionary& patchDict = patches[patchI].dict();
+
+        if (word(patchDict["type"]) == cyclicPolyPatch::typeName)
+        {
+            if (!patchDict.found("neighbourPatch"))
+            {
+                Info<< "Patch " << patches[patchI].keyword()
+                    << " does not have 'neighbourPatch' entry; assuming it"
+                    << " is of the old type." << endl;
+                nOldCyclics++;
+            }
+        }
+    }
+
+    Info<< "Detected " << nOldCyclics << " old cyclics." << nl << endl;
+
+
+    // Save old patches.
+    PtrList<entry> oldPatches(patches);
+
+    // Extend
+    label nOldPatches = patches.size();
+    patches.setSize(nOldPatches+nOldCyclics);
+
+    // Create reordering map
+    labelList oldToNew(patches.size());
+
+
+    // Add new entries
+    label addedPatchI = nOldPatches;
+    label newPatchI = 0;
+    forAll(oldPatches, patchI)
+    {
+        const dictionary& patchDict = oldPatches[patchI].dict();
+
+        if
+        (
+            word(patchDict["type"]) == cyclicPolyPatch::typeName
+        )
+        {
+            const word& name = oldPatches[patchI].keyword();
+
+            if (patchDict.found("neighbourPatch"))
+            {
+                patches.set(patchI, oldPatches.set(patchI, NULL));
+                oldToNew[patchI] = newPatchI++;
+
+                // Check if patches come from automatic conversion
+                word oldName;
+
+                string::size_type i = name.rfind("_half0");
+                if (i != string::npos)
+                {
+                    oldName = name.substr(0, i);
+                    thisNames.insert(oldName, name);
+                    Info<< "Detected converted cyclic patch " << name
+                        << " ; assuming it originates from " << oldName
+                        << endl;
+                }
+                else
+                {
+                    i = name.rfind("_half1");
+                    if (i != string::npos)
+                    {
+                        oldName = name.substr(0, i);
+                        nbrNames.insert(oldName, name);
+                        Info<< "Detected converted cyclic patch " << name
+                            << " ; assuming it originates from " << oldName
+                            << endl;
+                    }
+                }
+            }
+            else
+            {
+                label nFaces = readLabel(patchDict["nFaces"]);
+                label startFace = readLabel(patchDict["startFace"]);
+
+                Info<< "Detected old style " << word(patchDict["type"])
+                    << " patch " << name << " with" << nl
+                    << "    nFaces    : " << nFaces << nl
+                    << "    startFace : " << startFace << endl;
+
+                word thisName = name + "_half0";
+                word nbrName = name + "_half1";
+
+                thisNames.insert(name, thisName);
+                nbrNames.insert(name, nbrName);
+
+                // Save current dictionary
+                const dictionary patchDict(patches[patchI].dict());
+
+                // Change entry on this side
+                patches.set(patchI, oldPatches.set(patchI, NULL));
+                oldToNew[patchI] = newPatchI++;
+                dictionary& thisPatchDict = patches[patchI].dict();
+                thisPatchDict.add("neighbourPatch", nbrName);
+                thisPatchDict.set("nFaces", nFaces/2);
+                patches[patchI].keyword() = thisName;
+
+                // Add entry on other side
+                patches.set
+                (
+                    addedPatchI,
+                    new dictionaryEntry
+                    (
+                        nbrName,
+                        dictionary::null,
+                        patchDict
+                    )
+                );      
+                oldToNew[addedPatchI] = newPatchI++;
+                dictionary& nbrPatchDict = patches[addedPatchI].dict();
+                nbrPatchDict.set("neighbourPatch", thisName);
+                nbrPatchDict.set("nFaces", nFaces/2);
+                nbrPatchDict.set("startFace", startFace+nFaces/2);
+                patches[addedPatchI].keyword() = nbrName;
+
+                Info<< "Replaced with patches" << nl
+                    << patches[patchI].keyword() << " with" << nl
+                    << "    nFaces    : "
+                    << readLabel(thisPatchDict.lookup("nFaces"))
+                    << nl
+                    << "    startFace : "
+                    << readLabel(thisPatchDict.lookup("startFace")) << nl
+                    << patches[addedPatchI].keyword() << " with" << nl
+                    << "    nFaces    : "
+                    << readLabel(nbrPatchDict.lookup("nFaces"))
+                    << nl
+                    << "    startFace : "
+                    << readLabel(nbrPatchDict.lookup("startFace"))
+                    << nl << endl;
+
+                addedPatchI++;
+            }
+        }
+        else
+        {
+            patches.set(patchI, oldPatches.set(patchI, NULL));
+            oldToNew[patchI] = newPatchI++;
+        }
+    }
+
+    patches.reorder(oldToNew);
+
+    if (returnReduce(nOldCyclics, sumOp<label>()) > 0)
+    {
+        if (isTestRun)
+        {
+            //Info<< "-test option: no changes made" << nl << endl;
+        }
+        else
+        {
+            if (mvBak(patches.objectPath(), "old"))
+            {
+                Info<< "Backup to    "
+                    << (patches.objectPath() + ".old") << nl;
+            }
+
+            Info<< "Write  to    "
+                << patches.objectPath() << nl << endl;
+            patches.write();
+        }
+    }
+    else
+    {
+        Info<< "No changes made to boundary file." << nl << endl;
+    }
+}
+
+
+void rewriteField
+(
+    const bool isTestRun,
+    const Time& runTime,
+    const word& fieldName,
+    const HashTable<word>& thisNames,
+    const HashTable<word>& nbrNames
+)
+{
+    // Read dictionary. (disable class type checking so we can load
+    // field)
+    Info<< "Loading field " << fieldName << endl;
+    const word oldTypeName = IOdictionary::typeName;
+    const_cast<word&>(IOdictionary::typeName) = word::null;
+
+    IOdictionary fieldDict
+    (
+        IOobject
+        (
+            fieldName,
+            runTime.timeName(),
+            runTime,
+            IOobject::MUST_READ,
+            IOobject::NO_WRITE,
+            false
+        )
+    );
+    const_cast<word&>(IOdictionary::typeName) = oldTypeName;
+    // Fake type back to what was in field
+    const_cast<word&>(fieldDict.type()) = fieldDict.headerClassName();
+
+
+
+    dictionary& boundaryField = fieldDict.subDict("boundaryField");
+
+    label nChanged = 0;
+
+    forAllConstIter(HashTable<word>, thisNames, iter)
+    {
+        const word& patchName = iter.key();
+        const word& newName = iter();
+
+        Info<< "Looking for entry for patch " << patchName << endl;
+
+        if (boundaryField.found(patchName) && !boundaryField.found(newName))
+        {
+            Info<< "    Changing entry " << patchName << " to " << newName
+                << endl;
+
+            dictionary patchDict(boundaryField.subDict(patchName));
+
+            if (patchDict.found("value"))
+            {
+                IOWarningIn("rewriteField(..)", patchDict)
+                    << "Cyclic patch " << patchName
+                    << " has value entry. Please removed this and rerun."
+                    << endl;
+            }
+
+
+            boundaryField.changeKeyword(patchName, newName);
+            boundaryField.add
+            (
+                nbrNames[patchName],
+                patchDict
+            );
+            Info<< "    Adding entry " << nbrNames[patchName] << endl;
+
+            nChanged++;
+        }
+    }
+
+    //Info<< "New boundaryField:" << boundaryField << endl;
+
+    if (returnReduce(nChanged, sumOp<label>()) > 0)
+    {
+        if (isTestRun)
+        {
+            //Info<< "-test option: no changes made" << endl;
+        }
+        else
+        {
+            if (mvBak(fieldDict.objectPath(), "old"))
+            {
+                Info<< "Backup to    "
+                    << (fieldDict.objectPath() + ".old") << nl;
+            }
+
+            Info<< "Write  to    "
+                << fieldDict.objectPath() << endl;
+            fieldDict.regIOobject::write();
+        }
+    }
+    else
+    {
+        Info<< "No changes made to field " << fieldName << endl;
+    }
+    Info<< endl;
+}
+
+
+void rewriteFields
+(
+    const bool isTestRun,
+    const Time& runTime,
+    const wordList& fieldNames,
+    const HashTable<word>& thisNames,
+    const HashTable<word>& nbrNames
+)
+{
+    forAll(fieldNames, i)
+    {
+        rewriteField
+        (
+            isTestRun,
+            runTime,
+            fieldNames[i],
+            thisNames,
+            nbrNames
+        );
+    }
+}
+
+
+// Main program:
+
+int main(int argc, char *argv[])
+{
+    timeSelector::addOptions();
+
+    argList::addBoolOption("test");
+#   include "addRegionOption.H"
+
+#   include "setRootCase.H"
+#   include "createTime.H"
+
+    instantList timeDirs = timeSelector::select0(runTime, args);
+
+    const bool isTestRun = args.optionFound("test");
+    if (isTestRun)
+    {
+        Info<< "-test option: no changes made" << nl << endl;
+    }
+
+
+    Foam::word regionName = polyMesh::defaultRegion;
+    args.optionReadIfPresent("region", regionName);
+
+    fileName regionPrefix = "";
+    if (regionName != polyMesh::defaultRegion)
+    {
+        regionPrefix = regionName;
+    }
+
+
+    // Per cyclic patch the new name for this side and the other side
+    HashTable<word> thisNames;
+    HashTable<word> nbrNames;
+
+    // Rewrite constant boundary file. Return any patches that have been split.
+    IOobject io
+    (
+        "boundary",
+        runTime.constant(),
+        polyMesh::meshSubDir,
+        runTime,
+        IOobject::MUST_READ,
+        IOobject::NO_WRITE,
+        false
+    );
+
+    if (io.headerOk())
+    {
+        rewriteBoundary
+        (
+            isTestRun,
+            io,
+            regionPrefix,
+            thisNames,
+            nbrNames
+        );
+    }
+
+
+
+    // Convert any fields
+
+    forAll(timeDirs, timeI)
+    {
+        runTime.setTime(timeDirs[timeI], timeI);
+
+        Info<< "Time: " << runTime.timeName() << endl;
+
+        // See if mesh in time directory
+        IOobject io
+        (
+            "boundary",
+            runTime.timeName(),
+            polyMesh::meshSubDir,
+            runTime,
+            IOobject::MUST_READ,
+            IOobject::NO_WRITE,
+            false
+        );
+
+        if (io.headerOk())
+        {
+            rewriteBoundary
+            (
+                isTestRun,
+                io,
+                regionPrefix,
+                thisNames,
+                nbrNames
+            );
+        }
+
+
+        IOobjectList objects(runTime, runTime.timeName());
+
+
+        // volFields
+        // ~~~~~~~~~
+
+        rewriteFields
+        (
+            isTestRun,
+            runTime,
+            objects.names(volScalarField::typeName),
+            thisNames,
+            nbrNames
+        );
+        rewriteFields
+        (
+            isTestRun,
+            runTime,
+            objects.names(volVectorField::typeName),
+            thisNames,
+            nbrNames
+        );
+        rewriteFields
+        (
+            isTestRun,
+            runTime,
+            objects.names(volSphericalTensorField::typeName),
+            thisNames,
+            nbrNames
+        );
+        rewriteFields
+        (
+            isTestRun,
+            runTime,
+            objects.names(volSymmTensorField::typeName),
+            thisNames,
+            nbrNames
+        );
+        rewriteFields
+        (
+            isTestRun,
+            runTime,
+            objects.names(volTensorField::typeName),
+            thisNames,
+            nbrNames
+        );
+
+
+        // pointFields
+        // ~~~~~~~~~~~
+
+        rewriteFields
+        (
+            isTestRun,
+            runTime,
+            objects.names(pointScalarField::typeName),
+            thisNames,
+            nbrNames
+        );
+        rewriteFields
+        (
+            isTestRun,
+            runTime,
+            objects.names(pointVectorField::typeName),
+            thisNames,
+            nbrNames
+        );
+        rewriteFields
+        (
+            isTestRun,
+            runTime,
+            objects.names(pointSphericalTensorField::typeName),
+            thisNames,
+            nbrNames
+        );
+        rewriteFields
+        (
+            isTestRun,
+            runTime,
+            objects.names(pointSymmTensorField::typeName),
+            thisNames,
+            nbrNames
+        );
+        rewriteFields
+        (
+            isTestRun,
+            runTime,
+            objects.names(pointTensorField::typeName),
+            thisNames,
+            nbrNames
+        );
+
+
+        // surfaceFields
+        // ~~~~~~~~~~~
+
+        rewriteFields
+        (
+            isTestRun,
+            runTime,
+            objects.names(surfaceScalarField::typeName),
+            thisNames,
+            nbrNames
+        );
+        rewriteFields
+        (
+            isTestRun,
+            runTime,
+            objects.names(surfaceVectorField::typeName),
+            thisNames,
+            nbrNames
+        );
+        rewriteFields
+        (
+            isTestRun,
+            runTime,
+            objects.names(surfaceSphericalTensorField::typeName),
+            thisNames,
+            nbrNames
+        );
+        rewriteFields
+        (
+            isTestRun,
+            runTime,
+            objects.names(surfaceSymmTensorField::typeName),
+            thisNames,
+            nbrNames
+        );
+        rewriteFields
+        (
+            isTestRun,
+            runTime,
+            objects.names(surfaceTensorField::typeName),
+            thisNames,
+            nbrNames
+        );
+    }
+
+    return 0;
+}
+
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/Make/files b/src/OpenFOAM/Make/files
index aebfd27178b3199e1320a10f0d7cd815c5aa7457..bf28d148ddd2221be5ed0b8678c973824bd8ebf9 100644
--- a/src/OpenFOAM/Make/files
+++ b/src/OpenFOAM/Make/files
@@ -260,12 +260,14 @@ GAMGInterfaces = $(GAMG)/interfaces
 $(GAMGInterfaces)/GAMGInterface/GAMGInterface.C
 $(GAMGInterfaces)/GAMGInterface/GAMGInterfaceNew.C
 $(GAMGInterfaces)/processorGAMGInterface/processorGAMGInterface.C
+$(GAMGInterfaces)/processorCyclicGAMGInterface/processorCyclicGAMGInterface.C
 $(GAMGInterfaces)/cyclicGAMGInterface/cyclicGAMGInterface.C
 
 GAMGInterfaceFields = $(GAMG)/interfaceFields
 $(GAMGInterfaceFields)/GAMGInterfaceField/GAMGInterfaceField.C
 $(GAMGInterfaceFields)/GAMGInterfaceField/GAMGInterfaceFieldNew.C
 $(GAMGInterfaceFields)/processorGAMGInterfaceField/processorGAMGInterfaceField.C
+$(GAMGInterfaceFields)/processorCyclicGAMGInterfaceField/processorCyclicGAMGInterfaceField.C
 $(GAMGInterfaceFields)/cyclicGAMGInterfaceField/cyclicGAMGInterfaceField.C
 
 GAMGAgglomerations = $(GAMG)/GAMGAgglomerations
@@ -339,6 +341,7 @@ $(constraintPolyPatches)/empty/emptyPolyPatch.C
 $(constraintPolyPatches)/symmetry/symmetryPolyPatch.C
 $(constraintPolyPatches)/wedge/wedgePolyPatch.C
 $(constraintPolyPatches)/cyclic/cyclicPolyPatch.C
+$(constraintPolyPatches)/processorCyclic/processorCyclicPolyPatch.C
 $(constraintPolyPatches)/processor/processorPolyPatch.C
 
 derivedPolyPatches = $(polyPatches)/derived
@@ -450,6 +453,7 @@ $(constraintPointPatches)/symmetry/symmetryPointPatch.C
 $(constraintPointPatches)/wedge/wedgePointPatch.C
 $(constraintPointPatches)/cyclic/cyclicPointPatch.C
 $(constraintPointPatches)/processor/processorPointPatch.C
+$(constraintPointPatches)/processorCyclic/processorCyclicPointPatch.C
 
 derivedPointPatches = $(pointPatches)/derived
 $(derivedPointPatches)/coupled/coupledFacePointPatch.C
@@ -508,6 +512,7 @@ $(constraintPointPatchFields)/wedge/wedgePointPatchFields.C
 $(constraintPointPatchFields)/cyclic/cyclicPointPatchFields.C
 $(constraintPointPatchFields)/cyclicSlip/cyclicSlipPointPatchFields.C
 $(constraintPointPatchFields)/processor/processorPointPatchFields.C
+$(constraintPointPatchFields)/processorCyclic/processorCyclicPointPatchFields.C
 
 derivedPointPatchFields = $(pointPatchFields)/derived
 $(derivedPointPatchFields)/slip/slipPointPatchFields.C
diff --git a/src/OpenFOAM/algorithms/MeshWave/FaceCellWave.C b/src/OpenFOAM/algorithms/MeshWave/FaceCellWave.C
index 1d1ff5eec85dd741938c1f5f52e7b1752efe0cd2..a6a6afd430ea818e3d005c7bfd939d09e7640669 100644
--- a/src/OpenFOAM/algorithms/MeshWave/FaceCellWave.C
+++ b/src/OpenFOAM/algorithms/MeshWave/FaceCellWave.C
@@ -251,12 +251,13 @@ bool Foam::FaceCellWave<Type>::updateFace
 template <class Type>
 void Foam::FaceCellWave<Type>::checkCyclic(const polyPatch& patch) const
 {
-    label cycOffset = patch.size()/2;
+    const cyclicPolyPatch& nbrPatch =
+        refCast<const cyclicPolyPatch>(patch).neighbPatch();
 
-    for (label patchFaceI = 0; patchFaceI < cycOffset; patchFaceI++)
+    forAll(patch, patchFaceI)
     {
         label i1 = patch.start() + patchFaceI;
-        label i2 = i1 + cycOffset;
+        label i2 = nbrPatch.start() + patchFaceI;
 
         if (!allFaceInfo_[i1].sameGeometry(mesh_, allFaceInfo_[i2], geomTol_))
         {
@@ -334,8 +335,7 @@ void Foam::FaceCellWave<Type>::mergeFaceInfo
     const polyPatch& patch,
     const label nFaces,
     const labelList& changedFaces,
-    const List<Type>& changedFacesInfo,
-    const bool
+    const List<Type>& changedFacesInfo
 )
 {
     for (label changedFaceI = 0; changedFaceI < nFaces; changedFaceI++)
@@ -599,8 +599,7 @@ void Foam::FaceCellWave<Type>::handleProcPatches()
                 patch,
                 nReceiveFaces,
                 receiveFaces,
-                receiveFacesInfo,
-                procPatch.parallel()
+                receiveFacesInfo
             );
         }
     }
@@ -619,87 +618,42 @@ void Foam::FaceCellWave<Type>::handleCyclicPatches()
 
         if (isA<cyclicPolyPatch>(patch))
         {
-            label halfSize = patch.size()/2;
+            const cyclicPolyPatch& nbrPatch =
+                refCast<const cyclicPolyPatch>(patch).neighbPatch();
 
             // Allocate buffers
-            label nSendFaces;
-            labelList sendFaces(halfSize);
-            List<Type> sendFacesInfo(halfSize);
-
             label nReceiveFaces;
-            labelList receiveFaces(halfSize);
-            List<Type> receiveFacesInfo(halfSize);
-
-            // Half1: Determine which faces changed. Use sendFaces for storage
-            nSendFaces = getChangedPatchFaces
-            (
-                patch,
-                0,
-                halfSize,
-                sendFaces,
-                sendFacesInfo
-            );
+            labelList receiveFaces(patch.size());
+            List<Type> receiveFacesInfo(patch.size());
 
-            // Half2: Determine which faces changed. Use receiveFaces_  ,,
+            // Determine which faces changed
             nReceiveFaces = getChangedPatchFaces
             (
-                patch,
-                halfSize,
-                halfSize,
+                nbrPatch,
+                0,
+                nbrPatch.size(),
                 receiveFaces,
                 receiveFacesInfo
             );
 
-            //Info<< "Half1:" << endl;
-            //writeFaces(nSendFaces, sendFaces, sendFacesInfo, Info);
-            //Info<< endl;
-            //
-            //Info<< "Half2:" << endl;
-            //writeFaces(nReceiveFaces, receiveFaces, receiveFacesInfo, Info);
-            //Info<< endl;
-
-
-            // Half1: Adapt wallInfo for leaving domain
-            leaveDomain
-            (
-                patch,
-                nSendFaces,
-                sendFaces,
-                sendFacesInfo
-            );
-            // Half2: Adapt wallInfo for leaving domain
+            // Adapt wallInfo for leaving domain
             leaveDomain
             (
-                patch,
+                nbrPatch,
                 nReceiveFaces,
                 receiveFaces,
                 receiveFacesInfo
             );
 
-            // Half1: 'transfer' to other side by offsetting patchFaceI
-            offset(patch, halfSize, nSendFaces, sendFaces);
-
-            // Half2: 'transfer' to other side
-            offset(patch, -halfSize, nReceiveFaces, receiveFaces);
-
-            // Apply rotation for non-parallel planes
             const cyclicPolyPatch& cycPatch =
                 refCast<const cyclicPolyPatch>(patch);
 
             if (!cycPatch.parallel())
             {
-                // sendFaces = received data from half1
+                // received data from other half
                 transform
                 (
                     cycPatch.forwardT(),
-                    nSendFaces,
-                    sendFacesInfo
-                );
-
-                // receiveFaces = received data from half2
-                transform
-                (
-                    cycPatch.reverseT(),
                     nReceiveFaces,
                     receiveFacesInfo
                 );
@@ -707,25 +661,15 @@ void Foam::FaceCellWave<Type>::handleCyclicPatches()
 
             if (debug)
             {
-                Pout<< " Cyclic patch " << patchI << ' ' << patch.name()
-                    << "  Changed on first half : " << nSendFaces
-                    << "  Changed on second half : " << nReceiveFaces
+                Pout<< " Cyclic patch " << patchI << ' ' << cycPatch.name()
+                    << "  Changed : " << nReceiveFaces
                     << endl;
             }
 
-            // Half1: Adapt wallInfo for entering domain
-            enterDomain
-            (
-                patch,
-                nSendFaces,
-                sendFaces,
-                sendFacesInfo
-            );
-
             // Half2: Adapt wallInfo for entering domain
             enterDomain
             (
-                patch,
+                cycPatch,
                 nReceiveFaces,
                 receiveFaces,
                 receiveFacesInfo
@@ -734,25 +678,15 @@ void Foam::FaceCellWave<Type>::handleCyclicPatches()
             // Merge into global storage
             mergeFaceInfo
             (
-                patch,
-                nSendFaces,
-                sendFaces,
-                sendFacesInfo,
-                cycPatch.parallel()
-            );
-            // Merge into global storage
-            mergeFaceInfo
-            (
-                patch,
+                cycPatch,
                 nReceiveFaces,
                 receiveFaces,
-                receiveFacesInfo,
-                cycPatch.parallel()
+                receiveFacesInfo
             );
 
             if (debug)
             {
-                checkCyclic(patch);
+                checkCyclic(cycPatch);
             }
         }
     }
diff --git a/src/OpenFOAM/algorithms/MeshWave/FaceCellWave.H b/src/OpenFOAM/algorithms/MeshWave/FaceCellWave.H
index 9361c10f23f6f3f681908593b9c7084d2c852dd7..149f0badc4214bcfeb100e4fc8237d1eca3677e8 100644
--- a/src/OpenFOAM/algorithms/MeshWave/FaceCellWave.H
+++ b/src/OpenFOAM/algorithms/MeshWave/FaceCellWave.H
@@ -192,8 +192,7 @@ class FaceCellWave
                 const polyPatch& patch,
                 const label nFaces,
                 const labelList&,
-                const List<Type>&,
-                const bool isParallel
+                const List<Type>&
             );
 
             //- Extract info for single patch only
diff --git a/src/OpenFOAM/db/IOstreams/Pstreams/UPstream.C b/src/OpenFOAM/db/IOstreams/Pstreams/UPstream.C
index fbe757576341de9c2a69adce0dc7dcb7b1562dc1..e0ef1bf8eb0f23b920d2253713e150e10fa36599 100644
--- a/src/OpenFOAM/db/IOstreams/Pstreams/UPstream.C
+++ b/src/OpenFOAM/db/IOstreams/Pstreams/UPstream.C
@@ -219,6 +219,30 @@ Foam::List<int> Foam::UPstream::procIDs_(1, 0);
 // Standard transfer message type
 int Foam::UPstream::msgType_(1);
 
+// New message type 
+int Foam::UPstream::freeTag_(msgType()+1);
+
+// Free'd message types
+Foam::LIFOStack<int> Foam::UPstream::freedTags_;
+
+int Foam::UPstream::allocateTag()
+{
+    if (freedTags_.empty())
+    {
+        return freeTag_++;
+    }
+    else
+    {
+        return freedTags_.pop();
+    }
+}
+
+void Foam::UPstream::freeTag(const int tag)
+{
+    freedTags_.push(tag);
+}
+
+
 // Linear communication schedule
 Foam::List<Foam::UPstream::commsStruct> Foam::UPstream::linearCommunication_(0);
 
diff --git a/src/OpenFOAM/db/IOstreams/Pstreams/UPstream.H b/src/OpenFOAM/db/IOstreams/Pstreams/UPstream.H
index a0b0e44b8798198645bafe3d9d8acf25e815737f..57f6c263bc82e88170355cfef49d59287c8b393b 100644
--- a/src/OpenFOAM/db/IOstreams/Pstreams/UPstream.H
+++ b/src/OpenFOAM/db/IOstreams/Pstreams/UPstream.H
@@ -45,6 +45,7 @@ SourceFiles
 #include "HashTable.H"
 #include "string.H"
 #include "NamedEnum.H"
+#include "LIFOStack.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -190,6 +191,12 @@ private:
         static List<commsStruct> treeCommunication_;
 
 
+        //- Current free tag
+        static int freeTag_;
+
+        //- Freed tags
+        static LIFOStack<int> freedTags_;
+
     // Private Member Functions
 
         //- Set data for parallel running
@@ -339,6 +346,11 @@ public:
         {
             return msgType_;
         }
+        //- Allocate new tag
+        static int allocateTag();
+
+        //- Release allocated tag
+        static void freeTag(const int tag);
 
 
             //- Get the communications type of the stream
diff --git a/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricBoundaryField.C b/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricBoundaryField.C
index 7fa8d4b8bc19ed7586dcbaae22ea111cfaf075ff..ea652841b00090da0c126b69913a49f506390058 100644
--- a/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricBoundaryField.C
+++ b/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricBoundaryField.C
@@ -26,6 +26,7 @@ License
 #include "emptyPolyPatch.H"
 #include "commSchedule.H"
 #include "globalMeshData.H"
+#include "cyclicPolyPatch.H"
 
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
@@ -251,6 +252,29 @@ GeometricBoundaryField
     {
         if (bmesh_[patchi].type() != emptyPolyPatch::typeName)
         {
+            if
+            (
+                bmesh_[patchi].type() == cyclicPolyPatch::typeName
+             && !dict.found(bmesh_[patchi].name())
+            )
+            {
+                FatalIOErrorIn
+                (
+                    "GeometricField<Type, PatchField, GeoMesh>::\n"
+                    "GeometricBoundaryField::GeometricBoundaryField\n"
+                    "(\n"
+                    "    const BoundaryMesh&,\n"
+                    "    const DimensionedField<Type, GeoMesh>&,\n"
+                    "    const dictionary&\n"
+                    ")",
+                    dict
+                )   << "Cannot find patchField entry for cyclic "
+                    << bmesh_[patchi].name() << endl
+                    << "Is your field uptodate with split cyclics?" << endl
+                    << "Run foamUpgradeCyclics to convert mesh and fields"
+                    << " to split cyclics." << exit(FatalIOError);
+            }
+
             set
             (
                 patchi,
@@ -322,7 +346,11 @@ evaluate()
         }
 
         // Block for any outstanding requests
-        if (Pstream::defaultCommsType == Pstream::nonBlocking)
+        if
+        (
+            Pstream::parRun()
+         && Pstream::defaultCommsType == Pstream::nonBlocking
+        )
         {
             Pstream::waitRequests();
         }
diff --git a/src/OpenFOAM/fields/pointPatchFields/constraint/cyclic/cyclicPointPatchField.C b/src/OpenFOAM/fields/pointPatchFields/constraint/cyclic/cyclicPointPatchField.C
index a5f1b4a761b049b1e75dd7c539734fb9f8837f09..e23e5a8948b5362c01f9ec98dc70647b03ef4b22 100644
--- a/src/OpenFOAM/fields/pointPatchFields/constraint/cyclic/cyclicPointPatchField.C
+++ b/src/OpenFOAM/fields/pointPatchFields/constraint/cyclic/cyclicPointPatchField.C
@@ -25,6 +25,8 @@ License
 
 #include "cyclicPointPatchField.H"
 #include "Swap.H"
+#include "transformField.H"
+#include "pointFields.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -127,28 +129,57 @@ void cyclicPointPatchField<Type>::swapAddSeparated
     Field<Type>& pField
 ) const
 {
-    Field<Type> pf(this->patchInternalField(pField));
+    // Get neighbouring pointPatch
+    const cyclicPointPatch& nbrPatch = cyclicPatch_.neighbPatch();
 
-    const edgeList& pairs = cyclicPatch_.transformPairs();
-
-    if (doTransform())
+    if (cyclicPatch_.cyclicPatch().owner())
     {
-        forAll(pairs, pairi)
+        // We inplace modify pField. To prevent the other side (which gets
+        // evaluated at a later date) using already changed values we do
+        // all swaps on the side that gets evaluated first.
+
+        // Get neighbouring pointPatchField
+        const GeometricField<Type, pointPatchField, pointMesh>& fld =
+            refCast<const GeometricField<Type, pointPatchField, pointMesh> >
+            (
+                this->dimensionedInternalField()
+            );
+
+        const cyclicPointPatchField<Type>& nbr =
+            refCast<const cyclicPointPatchField<Type> >
+            (
+                fld.boundaryField()[nbrPatch.index()]
+            );
+
+
+        Field<Type> pf(this->patchInternalField(pField));
+        Field<Type> nbrPf(nbr.patchInternalField(pField));
+
+        const edgeList& pairs = cyclicPatch_.transformPairs();
+
+        if (doTransform())
         {
-            Type tmp = pf[pairs[pairi][0]];
-            pf[pairs[pairi][0]] = transform(forwardT()[0], pf[pairs[pairi][1]]);
-            pf[pairs[pairi][1]] = transform(reverseT()[0], tmp);
+            // Transform both sides.
+            forAll(pairs, pairi)
+            {
+                label pointi = pairs[pairi][0];
+                label nbrPointi = pairs[pairi][1];
+
+                Type tmp = pf[pointi];
+                pf[pointi] = transform(forwardT()[0], nbrPf[nbrPointi]);
+                nbrPf[nbrPointi] = transform(reverseT()[0], tmp);
+            }
         }
-    }
-    else
-    {
-        forAll(pairs, pairi)
+        else
         {
-            Swap(pf[pairs[pairi][0]], pf[pairs[pairi][1]]);
+            forAll(pairs, pairi)
+            {
+                Swap(pf[pairs[pairi][0]], nbrPf[pairs[pairi][1]]);
+            }
         }
+        addToInternalField(pField, pf);
+        nbr.addToInternalField(pField, nbrPf);
     }
-
-    addToInternalField(pField, pf, cyclicPatch_.separatedPoints());
 }
 
 
diff --git a/src/OpenFOAM/fields/pointPatchFields/constraint/processor/processorPointPatchField.C b/src/OpenFOAM/fields/pointPatchFields/constraint/processor/processorPointPatchField.C
index 876c27723f53f6501ba3a100cd28429604c87285..11753c397e012a88aed360ebec64ac5a761784d3 100644
--- a/src/OpenFOAM/fields/pointPatchFields/constraint/processor/processorPointPatchField.C
+++ b/src/OpenFOAM/fields/pointPatchFields/constraint/processor/processorPointPatchField.C
@@ -24,7 +24,7 @@ License
 \*---------------------------------------------------------------------------*/
 
 #include "processorPointPatchField.H"
-#include "transformField.H"
+//#include "transformField.H"
 #include "processorPolyPatch.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@@ -102,26 +102,27 @@ void processorPointPatchField<Type>::initSwapAddSeparated
 )
 const
 {
-    if (Pstream::parRun())
-    {
-        // Get internal field into correct order for opposite side
-        Field<Type> pf
-        (
-            this->patchInternalField
-            (
-                pField,
-                procPatch_.reverseMeshPoints()
-            )
-        );
-
-        OPstream::write
-        (
-            commsType,
-            procPatch_.neighbProcNo(),
-            reinterpret_cast<const char*>(pf.begin()),
-            pf.byteSize()
-        );
-    }
+//    if (Pstream::parRun())
+//    {
+//        // Get internal field into correct order for opposite side
+//        Field<Type> pf
+//        (
+//            this->patchInternalField
+//            (
+//                pField,
+//                procPatch_.reverseMeshPoints()
+//            )
+//        );
+//
+//        OPstream::write
+//        (
+//            commsType,
+//            procPatch_.neighbProcNo(),
+//            reinterpret_cast<const char*>(pf.begin()),
+//            pf.byteSize(),
+//            procPatch_.tag()
+//        );
+//    }
 }
 
 
@@ -132,44 +133,29 @@ void processorPointPatchField<Type>::swapAddSeparated
     Field<Type>& pField
 ) const
 {
-    if (Pstream::parRun())
-    {
-        Field<Type> pnf(this->size());
-
-        IPstream::read
-        (
-            commsType,
-            procPatch_.neighbProcNo(),
-            reinterpret_cast<char*>(pnf.begin()),
-            pnf.byteSize()
-        );
-
-        if (doTransform())
-        {
-            const processorPolyPatch& ppp = procPatch_.procPolyPatch();
-            const tensorField& forwardT = ppp.forwardT();
-
-            if (forwardT.size() == 1)
-            {
-                transform(pnf, forwardT[0], pnf);
-            }
-            else
-            {
-                const labelListList& pointFaces = ppp.pointFaces();
-
-                forAll(pointFaces, pfi)
-                {
-                    pnf[pfi] = transform
-                    (
-                        forwardT[pointFaces[pfi][0]],
-                        pnf[pfi]
-                    );
-                }
-            }
-        }
-
-        addToInternalField(pField, pnf, procPatch_.separatedPoints());
-    }
+//    if (Pstream::parRun())
+//    {
+//        Field<Type> pnf(this->size());
+//
+//        IPstream::read
+//        (
+//            commsType,
+//            procPatch_.neighbProcNo(),
+//            reinterpret_cast<char*>(pnf.begin()),
+//            pnf.byteSize(),
+//            procPatch_.tag()
+//        );
+//
+//        if (doTransform())
+//        {
+//            const processorPolyPatch& ppp = procPatch_.procPolyPatch();
+//            const tensor& forwardT = ppp.forwardT();
+//
+//            transform(pnf, forwardT, pnf);
+//        }
+//
+//        addToInternalField(pField, pnf, procPatch_.separatedPoints());
+//    }
 }
 
 
diff --git a/src/OpenFOAM/fields/pointPatchFields/constraint/processor/processorPointPatchField.H b/src/OpenFOAM/fields/pointPatchFields/constraint/processor/processorPointPatchField.H
index cc1760a7b2b1d3c2cd1540670d796e48425b2a8b..4aeda6700b4ccb2fbe66a5f7c5931657512b5488 100644
--- a/src/OpenFOAM/fields/pointPatchFields/constraint/processor/processorPointPatchField.H
+++ b/src/OpenFOAM/fields/pointPatchFields/constraint/processor/processorPointPatchField.H
@@ -147,7 +147,7 @@ public:
                 }
             }
 
-            //- Does the patch field perform the transfromation
+            //- Does the patch field perform the transformation
             virtual bool doTransform() const
             {
                 return
diff --git a/src/OpenFOAM/fields/pointPatchFields/constraint/processorCyclic/processorCyclicPointPatchField.C b/src/OpenFOAM/fields/pointPatchFields/constraint/processorCyclic/processorCyclicPointPatchField.C
new file mode 100644
index 0000000000000000000000000000000000000000..3fd5606453b26f80508b2d8bd7266e87b91ab608
--- /dev/null
+++ b/src/OpenFOAM/fields/pointPatchFields/constraint/processorCyclic/processorCyclicPointPatchField.C
@@ -0,0 +1,168 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
+     \\/     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 2 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, write to the Free Software Foundation,
+    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+\*---------------------------------------------------------------------------*/
+
+#include "processorCyclicPointPatchField.H"
+#include "transformField.H"
+#include "processorPolyPatch.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
+
+template<class Type>
+processorCyclicPointPatchField<Type>::processorCyclicPointPatchField
+(
+    const pointPatch& p,
+    const DimensionedField<Type, pointMesh>& iF
+)
+:
+    coupledPointPatchField<Type>(p, iF),
+    procPatch_(refCast<const processorCyclicPointPatch>(p))
+{}
+
+
+template<class Type>
+processorCyclicPointPatchField<Type>::processorCyclicPointPatchField
+(
+    const pointPatch& p,
+    const DimensionedField<Type, pointMesh>& iF,
+    const dictionary& dict
+)
+:
+    coupledPointPatchField<Type>(p, iF, dict),
+    procPatch_(refCast<const processorCyclicPointPatch>(p))
+{}
+
+
+template<class Type>
+processorCyclicPointPatchField<Type>::processorCyclicPointPatchField
+(
+    const processorCyclicPointPatchField<Type>& ptf,
+    const pointPatch& p,
+    const DimensionedField<Type, pointMesh>& iF,
+    const pointPatchFieldMapper& mapper
+)
+:
+    coupledPointPatchField<Type>(ptf, p, iF, mapper),
+    procPatch_(refCast<const processorCyclicPointPatch>(ptf.patch()))
+{}
+
+
+template<class Type>
+processorCyclicPointPatchField<Type>::processorCyclicPointPatchField
+(
+    const processorCyclicPointPatchField<Type>& ptf,
+    const DimensionedField<Type, pointMesh>& iF
+)
+:
+    coupledPointPatchField<Type>(ptf, iF),
+    procPatch_(refCast<const processorCyclicPointPatch>(ptf.patch()))
+{}
+
+
+// * * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * //
+
+template<class Type>
+processorCyclicPointPatchField<Type>::~processorCyclicPointPatchField()
+{}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+template<class Type>
+void processorCyclicPointPatchField<Type>::initSwapAddSeparated
+(
+    const Pstream::commsTypes commsType,
+    Field<Type>& pField
+) const
+{
+    if (Pstream::parRun())
+    {
+        // Get internal field into correct order for opposite side
+        Field<Type> pf
+        (
+            this->patchInternalField
+            (
+                pField,
+                procPatch_.reverseMeshPoints()
+            )
+        );
+
+        OPstream::write
+        (
+            commsType,
+            procPatch_.neighbProcNo(),
+            reinterpret_cast<const char*>(pf.begin()),
+            pf.byteSize(),
+            procPatch_.tag()
+        );
+    }
+}
+
+
+template<class Type>
+void processorCyclicPointPatchField<Type>::swapAddSeparated
+(
+    const Pstream::commsTypes commsType,
+    Field<Type>& pField
+) const
+{
+    if (Pstream::parRun())
+    {
+        Field<Type> pnf(this->size());
+
+        IPstream::read
+        (
+            commsType,
+            procPatch_.neighbProcNo(),
+            reinterpret_cast<char*>(pnf.begin()),
+            pnf.byteSize(),
+            procPatch_.tag()
+        );
+
+        if (doTransform())
+        {
+            const processorCyclicPolyPatch& ppp =
+                procPatch_.procCyclicPolyPatch();
+            const tensor& forwardT = ppp.forwardT()[0];
+
+            transform(pnf, forwardT, pnf);
+        }
+
+        // All points are separated
+        addToInternalField(pField, pnf);
+    }
+}
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/fields/pointPatchFields/constraint/processorCyclic/processorCyclicPointPatchField.H b/src/OpenFOAM/fields/pointPatchFields/constraint/processorCyclic/processorCyclicPointPatchField.H
new file mode 100644
index 0000000000000000000000000000000000000000..6b5f9b3377f49f84d72ef440198b87397944ed36
--- /dev/null
+++ b/src/OpenFOAM/fields/pointPatchFields/constraint/processorCyclic/processorCyclicPointPatchField.H
@@ -0,0 +1,202 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
+     \\/     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 2 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, write to the Free Software Foundation,
+    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+Class
+    Foam::processorCyclicPointPatchField
+
+Description
+    Foam::processorCyclicPointPatchField
+
+SourceFiles
+    processorCyclicPointPatchField.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef processorCyclicPointPatchField_H
+#define processorCyclicPointPatchField_H
+
+#include "coupledPointPatchField.H"
+#include "processorCyclicPointPatch.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+                 Class processorCyclicPointPatchField Declaration
+\*---------------------------------------------------------------------------*/
+
+template<class Type>
+class processorCyclicPointPatchField
+:
+    public coupledPointPatchField<Type>
+{
+    // Private data
+
+        //- Local reference to processor patch
+        const processorCyclicPointPatch& procPatch_;
+
+
+public:
+
+    //- Runtime type information
+    TypeName(processorCyclicPointPatch::typeName_());
+
+
+    // Constructors
+
+        //- Construct from patch and internal field
+        processorCyclicPointPatchField
+        (
+            const pointPatch&,
+            const DimensionedField<Type, pointMesh>&
+        );
+
+        //- Construct from patch, internal field and dictionary
+        processorCyclicPointPatchField
+        (
+            const pointPatch&,
+            const DimensionedField<Type, pointMesh>&,
+            const dictionary&
+        );
+
+        //- Construct by mapping given patchField<Type> onto a new patch
+        processorCyclicPointPatchField
+        (
+            const processorCyclicPointPatchField<Type>&,
+            const pointPatch&,
+            const DimensionedField<Type, pointMesh>&,
+            const pointPatchFieldMapper&
+        );
+
+        //- Construct and return a clone
+        virtual autoPtr<pointPatchField<Type> > clone() const
+        {
+            return autoPtr<pointPatchField<Type> >
+            (
+                new processorCyclicPointPatchField<Type>
+                (
+                    *this
+                )
+            );
+        }
+
+        //- Construct as copy setting internal field reference
+        processorCyclicPointPatchField
+        (
+            const processorCyclicPointPatchField<Type>&,
+            const DimensionedField<Type, pointMesh>&
+        );
+
+        //- Construct and return a clone setting internal field reference
+        virtual autoPtr<pointPatchField<Type> > clone
+        (
+            const DimensionedField<Type, pointMesh>& iF
+        ) const
+        {
+            return autoPtr<pointPatchField<Type> >
+            (
+                new processorCyclicPointPatchField<Type>
+                (
+                    *this,
+                    iF
+                )
+            );
+        }
+
+
+    // Destructor
+
+        ~processorCyclicPointPatchField();
+
+
+    // Member functions
+
+        // Access
+
+            //- Return true if running parallel
+            virtual bool coupled() const
+            {
+                if (Pstream::parRun())
+                {
+                    return true;
+                }
+                else
+                {
+                    return false;
+                }
+            }
+
+            //- Does the patch field perform the transfromation
+            virtual bool doTransform() const
+            {
+                return
+                   !(
+                        pTraits<Type>::rank == 0
+                     || procPatch_.procPolyPatch().parallel()
+                    );
+            }
+
+
+        // Evaluation functions
+
+            //- Evaluate the patch field
+            virtual void evaluate
+            (
+                const Pstream::commsTypes commsType=Pstream::blocking
+            )
+            {}
+
+            //- Initialise swap of non-collocated patch point values
+            virtual void initSwapAddSeparated
+            (
+                const Pstream::commsTypes commsType,
+                Field<Type>&
+            ) const;
+
+            //- Complete swap of patch point values and add to local values
+            virtual void swapAddSeparated
+            (
+                const Pstream::commsTypes commsType,
+                Field<Type>&
+            ) const;
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#ifdef NoRepository
+#    include "processorCyclicPointPatchField.C"
+#endif
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/fields/pointPatchFields/constraint/processorCyclic/processorCyclicPointPatchFields.C b/src/OpenFOAM/fields/pointPatchFields/constraint/processorCyclic/processorCyclicPointPatchFields.C
new file mode 100644
index 0000000000000000000000000000000000000000..5708849d87ddc8722340b34ecfda42bf900ab130
--- /dev/null
+++ b/src/OpenFOAM/fields/pointPatchFields/constraint/processorCyclic/processorCyclicPointPatchFields.C
@@ -0,0 +1,44 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
+     \\/     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 2 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, write to the Free Software Foundation,
+    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+\*---------------------------------------------------------------------------*/
+
+#include "processorCyclicPointPatchFields.H"
+#include "pointPatchFields.H"
+#include "addToRunTimeSelectionTable.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+makePointPatchFields(processorCyclic);
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/fields/pointPatchFields/constraint/processorCyclic/processorCyclicPointPatchFields.H b/src/OpenFOAM/fields/pointPatchFields/constraint/processorCyclic/processorCyclicPointPatchFields.H
new file mode 100644
index 0000000000000000000000000000000000000000..697cf9adff9a6f6d6bacfc0e4c3ef0ccc75a4dcc
--- /dev/null
+++ b/src/OpenFOAM/fields/pointPatchFields/constraint/processorCyclic/processorCyclicPointPatchFields.H
@@ -0,0 +1,50 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
+     \\/     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 2 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, write to the Free Software Foundation,
+    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef processorCyclicPointPatchFields_H
+#define processorCyclicPointPatchFields_H
+
+#include "processorCyclicPointPatchField.H"
+#include "fieldTypes.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+makePointPatchFieldTypedefs(processorCyclic);
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/fields/pointPatchFields/pointPatchField/pointPatchField.C b/src/OpenFOAM/fields/pointPatchFields/pointPatchField/pointPatchField.C
index 764fa5b31b319c84bec901167bcda4037bd0171d..03dbf43fd431628d7f9541236e2f7ed20de6148d 100644
--- a/src/OpenFOAM/fields/pointPatchFields/pointPatchField/pointPatchField.C
+++ b/src/OpenFOAM/fields/pointPatchFields/pointPatchField/pointPatchField.C
@@ -141,15 +141,7 @@ tmp<Field<Type1> > pointPatchField<Type>::patchInternalField
             << abort(FatalError);
     }
 
-    tmp<Field<Type1> > tvalues(new Field<Type1>(meshPoints.size()));
-    Field<Type1>& values = tvalues();
-
-    forAll(meshPoints, pointI)
-    {
-        values[pointI] = iF[meshPoints[pointI]];
-    }
-
-    return tvalues;
+    return tmp<Field<Type1> >(new Field<Type1>(iF, meshPoints));
 }
 
 
diff --git a/src/OpenFOAM/global/argList/parRun.H b/src/OpenFOAM/global/argList/parRun.H
index 6ec30f2249c3813ce8c976dae3b04a05d79ecc94..23db4ee9bc4d5ccfd03392a27f38749af66f9197 100644
--- a/src/OpenFOAM/global/argList/parRun.H
+++ b/src/OpenFOAM/global/argList/parRun.H
@@ -32,8 +32,7 @@ Description
 #ifndef parRun_H
 #define parRun_H
 
-#include "OPstream.H"
-#include "IPstream.H"
+#include "Pstream.H"
 #include "IOstreams.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
diff --git a/src/OpenFOAM/matrices/LUscalarMatrix/LUscalarMatrix.C b/src/OpenFOAM/matrices/LUscalarMatrix/LUscalarMatrix.C
index 05b26179b47d405b084d1047e45b14cfbec81c2b..30a632ae36c967e41edf47c14922a96f11eac661 100644
--- a/src/OpenFOAM/matrices/LUscalarMatrix/LUscalarMatrix.C
+++ b/src/OpenFOAM/matrices/LUscalarMatrix/LUscalarMatrix.C
@@ -27,6 +27,7 @@ License
 #include "lduMatrix.H"
 #include "procLduMatrix.H"
 #include "procLduInterface.H"
+#include "cyclicLduInterface.H"
 
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
@@ -160,19 +161,27 @@ void Foam::LUscalarMatrix::convert
         {
             const lduInterface& interface = interfaces[inti].interface();
 
-            const label* __restrict__ ulPtr = interface.faceCells().begin();
-            const scalar* __restrict__ upperLowerPtr =
-                interfaceCoeffs[inti].begin();
+            // Assume any interfaces are cyclic ones
 
-            register label inFaces = interface.faceCells().size()/2;
+            const label* __restrict__ lPtr = interface.faceCells().begin();
+
+            const cyclicLduInterface& cycInterface =
+                refCast<const cyclicLduInterface>(interface);
+            label nbrInt = cycInterface.neighbPatchID();
+            const label* __restrict__ uPtr =
+                interfaces[nbrInt].interface().faceCells().begin();
+
+            const scalar* __restrict__ nbrUpperLowerPtr =
+                interfaceCoeffs[nbrInt].begin();
+
+            register label inFaces = interface.faceCells().size();
 
             for (register label face=0; face<inFaces; face++)
             {
-                label uCell = ulPtr[face];
-                label lCell = ulPtr[face + inFaces];
+                label uCell = lPtr[face];
+                label lCell = uPtr[face];
 
-                operator[](uCell)[lCell] -= upperLowerPtr[face + inFaces];
-                operator[](lCell)[uCell] -= upperLowerPtr[face];
+                operator[](uCell)[lCell] -= nbrUpperLowerPtr[face];
             }
         }
     }
diff --git a/src/OpenFOAM/matrices/lduMatrix/lduAddressing/lduInterface/cyclicLduInterface.H b/src/OpenFOAM/matrices/lduMatrix/lduAddressing/lduInterface/cyclicLduInterface.H
index 1010c17f9822d969fdd3b0844d3f8f19f6a152f2..7d7cbff30954edc721b9a18abaf1a93ed4f4bc44 100644
--- a/src/OpenFOAM/matrices/lduMatrix/lduAddressing/lduInterface/cyclicLduInterface.H
+++ b/src/OpenFOAM/matrices/lduMatrix/lduAddressing/lduInterface/cyclicLduInterface.H
@@ -65,6 +65,14 @@ public:
 
         // Access
 
+            //- Return neighbour
+            virtual label neighbPatchID() const = 0;
+
+            virtual bool owner() const = 0;
+
+            //- Return processor number
+            virtual const cyclicLduInterface& neighbPatch() const = 0;
+
             //- Return face transformation tensor
             virtual const tensorField& forwardT() const = 0;
 
diff --git a/src/OpenFOAM/matrices/lduMatrix/lduAddressing/lduInterface/lduInterface.H b/src/OpenFOAM/matrices/lduMatrix/lduAddressing/lduInterface/lduInterface.H
index 2b65bedf8d772e52191c55293a6895aa69f385fc..60ca7372d01aeb3abd7aaecaf3323cc3e0d6b52a 100644
--- a/src/OpenFOAM/matrices/lduMatrix/lduAddressing/lduInterface/lduInterface.H
+++ b/src/OpenFOAM/matrices/lduMatrix/lduAddressing/lduInterface/lduInterface.H
@@ -96,21 +96,6 @@ public:
                 const unallocLabelList& internalData
             ) const = 0;
 
-            //- Initialise interface data transfer
-            virtual void initTransfer
-            (
-                const Pstream::commsTypes commsType,
-                const unallocLabelList& interfaceData
-            ) const
-            {}
-
-            //- Transfer and return neighbour field
-            virtual tmp<labelField> transfer
-            (
-                const Pstream::commsTypes commsType,
-                const unallocLabelList& interfaceData
-            ) const = 0;
-
             //- Initialise transfer of internal field adjacent to the interface
             virtual void initInternalFieldTransfer
             (
diff --git a/src/OpenFOAM/matrices/lduMatrix/lduAddressing/lduInterface/processorLduInterface.H b/src/OpenFOAM/matrices/lduMatrix/lduAddressing/lduInterface/processorLduInterface.H
index be3d050d7ada66367b2f24a85d2834ca13e215e2..324ccc1ad4cff433ee288b48f2a4c8d0b2f2581b 100644
--- a/src/OpenFOAM/matrices/lduMatrix/lduAddressing/lduInterface/processorLduInterface.H
+++ b/src/OpenFOAM/matrices/lduMatrix/lduAddressing/lduInterface/processorLduInterface.H
@@ -93,6 +93,8 @@ public:
             //- Return face transformation tensor
             virtual const tensorField& forwardT() const = 0;
 
+            //- Return message tag used for sending
+            virtual int tag() const = 0;
 
         // Transfer functions
 
diff --git a/src/OpenFOAM/matrices/lduMatrix/lduAddressing/lduInterface/processorLduInterfaceTemplates.C b/src/OpenFOAM/matrices/lduMatrix/lduAddressing/lduInterface/processorLduInterfaceTemplates.C
index cd42ba976722b9355436c98d8ddcd303746bcc0e..450c30f884693e02e8c8461bd9d7e171aebeef3f 100644
--- a/src/OpenFOAM/matrices/lduMatrix/lduAddressing/lduInterface/processorLduInterfaceTemplates.C
+++ b/src/OpenFOAM/matrices/lduMatrix/lduAddressing/lduInterface/processorLduInterfaceTemplates.C
@@ -43,7 +43,8 @@ void Foam::processorLduInterface::send
             commsType,
             neighbProcNo(),
             reinterpret_cast<const char*>(f.begin()),
-            f.byteSize()
+            f.byteSize(),
+            tag()
         );
     }
     else if (commsType == Pstream::nonBlocking)
@@ -55,7 +56,8 @@ void Foam::processorLduInterface::send
             commsType,
             neighbProcNo(),
             receiveBuf_.begin(),
-            receiveBuf_.size()
+            receiveBuf_.size(),
+            tag()
         );
 
         resizeBuf(sendBuf_, f.byteSize());
@@ -66,7 +68,8 @@ void Foam::processorLduInterface::send
             commsType,
             neighbProcNo(),
             sendBuf_.begin(),
-            f.byteSize()
+            f.byteSize(),
+            tag()
         );
     }
     else
@@ -92,7 +95,8 @@ void Foam::processorLduInterface::receive
             commsType,
             neighbProcNo(),
             reinterpret_cast<char*>(f.begin()),
-            f.byteSize()
+            f.byteSize(),
+            tag()
         );
     }
     else if (commsType == Pstream::nonBlocking)
@@ -155,7 +159,8 @@ void Foam::processorLduInterface::compressedSend
                 commsType,
                 neighbProcNo(),
                 sendBuf_.begin(),
-                nBytes
+                nBytes,
+                tag()
             );
         }
         else if (commsType == Pstream::nonBlocking)
@@ -167,7 +172,8 @@ void Foam::processorLduInterface::compressedSend
                 commsType,
                 neighbProcNo(),
                 receiveBuf_.begin(),
-                receiveBuf_.size()
+                receiveBuf_.size(),
+                tag()
             );
 
             OPstream::write
@@ -175,7 +181,8 @@ void Foam::processorLduInterface::compressedSend
                 commsType,
                 neighbProcNo(),
                 sendBuf_.begin(),
-                nBytes
+                nBytes,
+                tag()
             );
         }
         else
@@ -215,7 +222,8 @@ void Foam::processorLduInterface::compressedReceive
                 commsType,
                 neighbProcNo(),
                 receiveBuf_.begin(),
-                nBytes
+                nBytes,
+                tag()
             );
         }
         else if (commsType != Pstream::nonBlocking)
diff --git a/src/OpenFOAM/matrices/lduMatrix/lduAddressing/lduInterfaceFields/cyclicLduInterfaceField/cyclicLduInterfaceField.C b/src/OpenFOAM/matrices/lduMatrix/lduAddressing/lduInterfaceFields/cyclicLduInterfaceField/cyclicLduInterfaceField.C
index 472cec83f231156373e7073ec82e2e947632dbfd..460a9fa06d2619e7dae25e1891729d9f9cab6397 100644
--- a/src/OpenFOAM/matrices/lduMatrix/lduAddressing/lduInterfaceFields/cyclicLduInterfaceField/cyclicLduInterfaceField.C
+++ b/src/OpenFOAM/matrices/lduMatrix/lduAddressing/lduInterfaceFields/cyclicLduInterfaceField/cyclicLduInterfaceField.C
@@ -47,19 +47,10 @@ void Foam::cyclicLduInterfaceField::transformCoupleField
 {
     if (doTransform())
     {
-        label sizeby2 = pnf.size()/2;
-
         scalar forwardScale =
             pow(diag(forwardT()[0]).component(cmpt), rank());
 
-        scalar reverseScale =
-            pow(diag(reverseT()[0]).component(cmpt), rank());
-
-        for (label facei=0; facei<sizeby2; facei++)
-        {
-            pnf[facei] *= forwardScale;
-            pnf[facei + sizeby2] *= reverseScale;
-        }
+        pnf *= forwardScale;
     }
 }
 
diff --git a/src/OpenFOAM/matrices/lduMatrix/lduMatrix/lduMatrixUpdateMatrixInterfaces.C b/src/OpenFOAM/matrices/lduMatrix/lduMatrix/lduMatrixUpdateMatrixInterfaces.C
index 2d1ff23a596ac7b91e9a52a57ee1e885bc022537..2e7ebe16f179f8c02c929af42c3b46506cf59156 100644
--- a/src/OpenFOAM/matrices/lduMatrix/lduMatrix/lduMatrixUpdateMatrixInterfaces.C
+++ b/src/OpenFOAM/matrices/lduMatrix/lduMatrix/lduMatrixUpdateMatrixInterfaces.C
@@ -111,10 +111,13 @@ void Foam::lduMatrix::updateMatrixInterfaces
     )
     {
         // Block until all sends/receives have been finished
-        if (Pstream::defaultCommsType == Pstream::nonBlocking)
+        if
+        (
+            Pstream::parRun()
+         && Pstream::defaultCommsType == Pstream::nonBlocking
+        )
         {
-            IPstream::waitRequests();
-            OPstream::waitRequests();
+            UPstream::waitRequests();
         }
 
         forAll(interfaces, interfaceI)
diff --git a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGAgglomerations/GAMGAgglomeration/GAMGAgglomerateLduAddressing.C b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGAgglomerations/GAMGAgglomeration/GAMGAgglomerateLduAddressing.C
index e39bb19b5a23edd683d1c77be2f44f3f3fd727b7..a71bb298f5ee343a74cee3eda014afda8d839ebc 100644
--- a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGAgglomerations/GAMGAgglomeration/GAMGAgglomerateLduAddressing.C
+++ b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGAgglomerations/GAMGAgglomeration/GAMGAgglomerateLduAddressing.C
@@ -229,12 +229,17 @@ void Foam::GAMGAgglomeration::agglomerateLduAddressing
         {
             fineInterfaces[inti].initInternalFieldTransfer
             (
-                Pstream::blocking,
+                Pstream::nonBlocking,
                 restrictMap
             );
         }
     }
 
+    if (Pstream::parRun())
+    {
+        Pstream::waitRequests();
+    }
+
     // Add the coarse level
     forAll(fineInterfaces, inti)
     {
@@ -245,11 +250,13 @@ void Foam::GAMGAgglomeration::agglomerateLduAddressing
                 inti,
                 GAMGInterface::New
                 (
+                    inti,
+                    coarseInterfaces,
                     fineInterfaces[inti],
                     fineInterfaces[inti].interfaceInternalField(restrictMap),
                     fineInterfaces[inti].internalFieldTransfer
                     (
-                        Pstream::blocking,
+                        Pstream::nonBlocking,
                         restrictMap
                     )
                 ).ptr()
diff --git a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaceFields/cyclicGAMGInterfaceField/cyclicGAMGInterfaceField.C b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaceFields/cyclicGAMGInterfaceField/cyclicGAMGInterfaceField.C
index 4d67b7fa60a9ffed9d3a8a0d65abad642c1bbe17..45b5ce97bbba521f4bafb0952563ceb10a0a932e 100644
--- a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaceFields/cyclicGAMGInterfaceField/cyclicGAMGInterfaceField.C
+++ b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaceFields/cyclicGAMGInterfaceField/cyclicGAMGInterfaceField.C
@@ -80,20 +80,16 @@ void Foam::cyclicGAMGInterfaceField::updateInterfaceMatrix
     const Pstream::commsTypes
 ) const
 {
-    scalarField pnf(size());
+    // Get neighbouring field
+    scalarField pnf
+    (
+        cyclicInterface_.neighbPatch().interfaceInternalField(psiInternal)
+    );
 
-    label sizeby2 = size()/2;
+    transformCoupleField(pnf, cmpt);
 
     const unallocLabelList& faceCells = cyclicInterface_.faceCells();
 
-    for (label facei=0; facei<sizeby2; facei++)
-    {
-        pnf[facei] = psiInternal[faceCells[facei + sizeby2]];
-        pnf[facei + sizeby2] = psiInternal[faceCells[facei]];
-    }
-
-    transformCoupleField(pnf, cmpt);
-
     forAll(faceCells, elemI)
     {
         result[faceCells[elemI]] -= coeffs[elemI]*pnf[elemI];
diff --git a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaceFields/processorCyclicGAMGInterfaceField/processorCyclicGAMGInterfaceField.C b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaceFields/processorCyclicGAMGInterfaceField/processorCyclicGAMGInterfaceField.C
new file mode 100644
index 0000000000000000000000000000000000000000..c5bd1bb04d201edeb2a049ff1b844a9176bf06e0
--- /dev/null
+++ b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaceFields/processorCyclicGAMGInterfaceField/processorCyclicGAMGInterfaceField.C
@@ -0,0 +1,108 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
+     \\/     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 2 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, write to the Free Software Foundation,
+    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+\*---------------------------------------------------------------------------*/
+
+#include "processorCyclicGAMGInterfaceField.H"
+#include "addToRunTimeSelectionTable.H"
+#include "lduMatrix.H"
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+namespace Foam
+{
+    defineTypeNameAndDebug(processorCyclicGAMGInterfaceField, 0);
+    addToRunTimeSelectionTable
+    (
+        GAMGInterfaceField,
+        processorCyclicGAMGInterfaceField,
+        lduInterface
+    );
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::processorCyclicGAMGInterfaceField::processorCyclicGAMGInterfaceField
+(
+    const GAMGInterface& GAMGCp,
+    const lduInterfaceField& fineInterface
+)
+:
+    processorGAMGInterfaceField(GAMGCp, fineInterface)
+{}
+
+
+// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
+
+Foam::processorCyclicGAMGInterfaceField::~processorCyclicGAMGInterfaceField()
+{}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+//void Foam::processorCyclicGAMGInterfaceField::initInterfaceMatrixUpdate
+//(
+//    const scalarField& psiInternal,
+//    scalarField&,
+//    const lduMatrix&,
+//    const scalarField&,
+//    const direction,
+//    const Pstream::commsTypes commsType
+//) const
+//{
+//    procInterface_.compressedSend
+//    (
+//        commsType,
+//        procInterface_.interfaceInternalField(psiInternal)()
+//    );
+//}
+//
+//
+//void Foam::processorCyclicGAMGInterfaceField::updateInterfaceMatrix
+//(
+//    const scalarField&,
+//    scalarField& result,
+//    const lduMatrix&,
+//    const scalarField& coeffs,
+//    const direction cmpt,
+//    const Pstream::commsTypes commsType
+//) const
+//{
+//    scalarField pnf
+//    (
+//        procInterface_.compressedReceive<scalar>(commsType, coeffs.size())
+//    );
+//    transformCoupleField(pnf, cmpt);
+//
+//    const unallocLabelList& faceCells = procInterface_.faceCells();
+//
+//    forAll(faceCells, elemI)
+//    {
+//        result[faceCells[elemI]] -= coeffs[elemI]*pnf[elemI];
+//    }
+//}
+
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaceFields/processorCyclicGAMGInterfaceField/processorCyclicGAMGInterfaceField.H b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaceFields/processorCyclicGAMGInterfaceField/processorCyclicGAMGInterfaceField.H
new file mode 100644
index 0000000000000000000000000000000000000000..b47d9699bc5a9fc6c307834fa713e7ba35c09e3f
--- /dev/null
+++ b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaceFields/processorCyclicGAMGInterfaceField/processorCyclicGAMGInterfaceField.H
@@ -0,0 +1,174 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
+     \\/     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 2 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, write to the Free Software Foundation,
+    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+Class
+    Foam::processorCyclicGAMGInterfaceField
+
+Description
+    GAMG agglomerated processor interface field.
+
+SourceFiles
+    processorCyclicGAMGInterfaceField.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef processorCyclicGAMGInterfaceField_H
+#define processorCyclicGAMGInterfaceField_H
+
+#include "processorGAMGInterfaceField.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+                  Class processorCyclicGAMGInterfaceField Declaration
+\*---------------------------------------------------------------------------*/
+
+class processorCyclicGAMGInterfaceField
+:
+    public processorGAMGInterfaceField
+{
+    // Private data
+
+//        //- Local reference cast into the processor interface
+//        const processorCyclicGAMGInterface& procInterface_;
+//
+//        //- Is the transform required
+//        bool doTransform_;
+//
+//        //- Rank of component for transformation
+//        int rank_;
+//
+
+    // Private Member Functions
+
+        //- Disallow default bitwise copy construct
+        processorCyclicGAMGInterfaceField(const processorCyclicGAMGInterfaceField&);
+
+        //- Disallow default bitwise assignment
+        void operator=(const processorCyclicGAMGInterfaceField&);
+
+
+public:
+
+    //- Runtime type information
+    TypeName("processorCyclic");
+
+
+    // Constructors
+
+        //- Construct from GAMG interface and fine level interface field
+        processorCyclicGAMGInterfaceField
+        (
+            const GAMGInterface& GAMGCp,
+            const lduInterfaceField& fineInterface
+        );
+
+
+    // Destructor
+
+        virtual ~processorCyclicGAMGInterfaceField();
+
+
+    // Member Functions
+
+//        // Access
+//
+//            //- Return size
+//            label size() const
+//            {
+//                return procInterface_.size();
+//            }
+//
+//
+//        // Interface matrix update
+//
+//            //- Initialise neighbour matrix update
+//            virtual void initInterfaceMatrixUpdate
+//            (
+//                const scalarField& psiInternal,
+//                scalarField& result,
+//                const lduMatrix& m,
+//                const scalarField& coeffs,
+//                const direction cmpt,
+//                const Pstream::commsTypes commsType
+//            ) const;
+//
+//            //- Update result field based on interface functionality
+//            virtual void updateInterfaceMatrix
+//            (
+//                const scalarField& psiInternal,
+//                scalarField& result,
+//                const lduMatrix&,
+//                const scalarField& coeffs,
+//                const direction cmpt,
+//                const Pstream::commsTypes commsType
+//            ) const;
+//
+//
+//        //- Processor interface functions
+//
+//            //- Return processor number
+//            virtual int myProcNo() const
+//            {
+//                return procInterface_.myProcNo();
+//            }
+//
+//            //- Return neigbour processor number
+//            virtual int neighbProcNo() const
+//            {
+//                return procInterface_.neighbProcNo();
+//            }
+//
+//            //- Does the interface field perform the transfromation
+//            virtual bool doTransform() const
+//            {
+//                return doTransform_;
+//            }
+//
+//            //- Return face transformation tensor
+//            virtual const tensorField& forwardT() const
+//            {
+//                return procInterface_.forwardT();
+//            }
+//
+//            //- Return rank of component for transform
+//            virtual int rank() const
+//            {
+//                return rank_;
+//            }
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaces/GAMGInterface/GAMGInterface.H b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaces/GAMGInterface/GAMGInterface.H
index 7a156edc383fdb6d39d34654b5641bf7aa64ed73..baad87d6d83eb9fd3c46e6ae3858c83abe3810da 100644
--- a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaces/GAMGInterface/GAMGInterface.H
+++ b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaces/GAMGInterface/GAMGInterface.H
@@ -36,8 +36,8 @@ SourceFiles
 #ifndef GAMGInterface_H
 #define GAMGInterface_H
 
-#include "lduInterface.H"
 #include "autoPtr.H"
+#include "lduInterfacePtrsList.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -57,6 +57,12 @@ protected:
 
     // Protected data
 
+        //- My index in coarseInterfaces
+        const label index_;
+
+        //- All interfaces
+        const lduInterfacePtrsList& coarseInterfaces_;
+
         //- Face-cell addressing
         labelField faceCells_;
 
@@ -89,11 +95,15 @@ public:
             GAMGInterface,
             lduInterface,
             (
+                const label index,
+                const lduInterfacePtrsList& coarseInterfaces,
                 const lduInterface& fineInterface,
                 const labelField& localRestrictAddressing,
                 const labelField& neighbourRestrictAddressing
             ),
             (
+                index,
+                coarseInterfaces,
                 fineInterface,
                 localRestrictAddressing,
                 neighbourRestrictAddressing
@@ -107,6 +117,8 @@ public:
         //  the fine interface
         static autoPtr<GAMGInterface> New
         (
+            const label index,
+            const lduInterfacePtrsList& coarseInterfaces,
             const lduInterface& fineInterface,
             const labelField& localRestrictAddressing,
             const labelField& neighbourRestrictAddressing
@@ -119,10 +131,15 @@ public:
         //  local and neighbour restrict addressing
         GAMGInterface
         (
+            const label index,
+            const lduInterfacePtrsList& coarseInterfaces,
             const lduInterface&,
             const labelField&,
             const labelField&
         )
+        :
+            index_(index),
+            coarseInterfaces_(coarseInterfaces)
         {}
 
 
@@ -136,6 +153,16 @@ public:
                 return faceCells_.size();
             }
 
+            virtual label index() const
+            {
+                return index_;
+            }
+
+            virtual const lduInterfacePtrsList& coarseInterfaces() const
+            {
+                return coarseInterfaces_;
+            }
+
             //- Return faceCell addressing
             virtual const unallocLabelList& faceCells() const
             {
diff --git a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaces/GAMGInterface/GAMGInterfaceNew.C b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaces/GAMGInterface/GAMGInterfaceNew.C
index 6c4bed75238f752851edfd53bfee87d1d867dd8a..28f6e0481afbfa8be14fc085fc1160df63204822 100644
--- a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaces/GAMGInterface/GAMGInterfaceNew.C
+++ b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaces/GAMGInterface/GAMGInterfaceNew.C
@@ -31,6 +31,8 @@ License
 
 Foam::autoPtr<Foam::GAMGInterface> Foam::GAMGInterface::New
 (
+    const label index,
+    const lduInterfacePtrsList& coarseInterfaces,
     const lduInterface& fineInterface,
     const labelField& localRestrictAddressing,
     const labelField& neighbourRestrictAddressing
@@ -59,6 +61,8 @@ Foam::autoPtr<Foam::GAMGInterface> Foam::GAMGInterface::New
     (
         cstrIter()
         (
+            index,
+            coarseInterfaces,
             fineInterface,
             localRestrictAddressing,
             neighbourRestrictAddressing
diff --git a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaces/cyclicGAMGInterface/cyclicGAMGInterface.C b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaces/cyclicGAMGInterface/cyclicGAMGInterface.C
index fa55f71e7289a85dcd4fa40f4f0df065dc345c9f..2aac532ce1665084f5c9d0d44a9a28447874ce7c 100644
--- a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaces/cyclicGAMGInterface/cyclicGAMGInterface.C
+++ b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaces/cyclicGAMGInterface/cyclicGAMGInterface.C
@@ -25,6 +25,7 @@ License
 
 #include "cyclicGAMGInterface.H"
 #include "addToRunTimeSelectionTable.H"
+#include "Map.H"
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
@@ -44,6 +45,8 @@ namespace Foam
 
 Foam::cyclicGAMGInterface::cyclicGAMGInterface
 (
+    const label index,
+    const lduInterfacePtrsList& coarseInterfaces,
     const lduInterface& fineInterface,
     const labelField& localRestrictAddressing,
     const labelField& neighbourRestrictAddressing
@@ -51,6 +54,8 @@ Foam::cyclicGAMGInterface::cyclicGAMGInterface
 :
     GAMGInterface
     (
+        index,
+        coarseInterfaces,
         fineInterface,
         localRestrictAddressing,
         neighbourRestrictAddressing
@@ -58,33 +63,45 @@ Foam::cyclicGAMGInterface::cyclicGAMGInterface
     fineCyclicInterface_(refCast<const cyclicLduInterface>(fineInterface))
 {
     // Make a lookup table of entries for owner/neighbour
-    HashTable<SLList<label>, label, Hash<label> > neighboursTable
+    Map<SLList<label> > neighboursTable
     (
         localRestrictAddressing.size()
     );
 
     // Table of face-sets to be agglomerated
-    HashTable<SLList<SLList<label> >, label, Hash<label> > faceFaceTable
+    Map<SLList<SLList<label> > > faceFaceTable
     (
         localRestrictAddressing.size()
     );
 
     label nCoarseFaces = 0;
 
-    label sizeBy2 = localRestrictAddressing.size()/2;
-
-    for (label ffi=0; ffi<sizeBy2; ffi++)
+    forAll (localRestrictAddressing, ffi)
     {
-        label curMaster = localRestrictAddressing[ffi];
-        label curSlave = localRestrictAddressing[ffi + sizeBy2];
+        label curMaster = -1;
+        label curSlave = -1;
+
+        // Do switching on master/slave indexes based on the owner/neighbour of
+        // the processor index such that both sides get the same answer.
+        if (owner())
+        {
+            // Master side
+            curMaster = localRestrictAddressing[ffi];
+            curSlave = neighbourRestrictAddressing[ffi];
+        }
+        else
+        {
+            // Slave side
+            curMaster = neighbourRestrictAddressing[ffi];
+            curSlave = localRestrictAddressing[ffi];
+        }
 
         // Look for the master cell.  If it has already got a face,
-        // add the coefficient to the face.  If not, create a new
-        // face.
+        // add the coefficient to the face.  If not, create a new face.
         if (neighboursTable.found(curMaster))
         {
-            // Check all current neighbours to see if the current
-            // slave already exists.  If so, add the coefficient.
+            // Check all current neighbours to see if the current slave already
+            // exists and if so, add the fine face to the agglomeration.
 
             SLList<label>& curNbrs = neighboursTable.find(curMaster)();
 
@@ -135,69 +152,86 @@ Foam::cyclicGAMGInterface::cyclicGAMGInterface
     } // end for all fine faces
 
 
-    faceCells_.setSize(2*nCoarseFaces, -1);
-    faceRestrictAddressing_.setSize(localRestrictAddressing.size(), -1);
+
+    faceCells_.setSize(nCoarseFaces, -1);
+    faceRestrictAddressing_.setSize(localRestrictAddressing.size());
 
     labelList contents = neighboursTable.toc();
 
     // Reset face counter for re-use
     nCoarseFaces = 0;
 
-    // On master side, the owner addressing is stored in table of contents
-    forAll(contents, masterI)
+    if (owner())
     {
-        SLList<label>& curNbrs = neighboursTable.find(contents[masterI])();
-
-        SLList<SLList<label> >& curFaceFaces =
-            faceFaceTable.find(contents[masterI])();
+        // On master side, the owner addressing is stored in table of contents
+        forAll (contents, masterI)
+        {
+            SLList<label>& curNbrs = neighboursTable.find(contents[masterI])();
 
-        SLList<label>::iterator nbrsIter = curNbrs.begin();
-        SLList<SLList<label> >::iterator faceFacesIter = curFaceFaces.begin();
+            SLList<SLList<label> >& curFaceFaces =
+                faceFaceTable.find(contents[masterI])();
 
-        for
-        (
-            ;
-            nbrsIter != curNbrs.end(), faceFacesIter != curFaceFaces.end();
-            ++nbrsIter, ++faceFacesIter
-        )
-        {
-            faceCells_[nCoarseFaces] = contents[masterI];
+            SLList<label>::iterator nbrsIter = curNbrs.begin();
+            SLList<SLList<label> >::iterator faceFacesIter = curFaceFaces.begin();
 
-            forAllConstIter(SLList<label>, faceFacesIter(), facesIter)
+            for
+            (
+                ;
+                nbrsIter != curNbrs.end(), faceFacesIter != curFaceFaces.end();
+                ++nbrsIter, ++faceFacesIter
+            )
             {
-                faceRestrictAddressing_[facesIter()] = nCoarseFaces;
-            }
+                faceCells_[nCoarseFaces] = contents[masterI];
+
+                for
+                (
+                    SLList<label>::iterator facesIter = faceFacesIter().begin();
+                    facesIter != faceFacesIter().end();
+                    ++facesIter
+                )
+                {
+                    faceRestrictAddressing_[facesIter()] = nCoarseFaces;
+                }
 
-            nCoarseFaces++;
+                nCoarseFaces++;
+            }
         }
     }
-
-    // On slave side, the owner addressing is stored in linked lists
-    forAll(contents, masterI)
+    else
     {
-        SLList<label>& curNbrs = neighboursTable.find(contents[masterI])();
+        // On slave side, the owner addressing is stored in linked lists
+        forAll (contents, masterI)
+        {
+            SLList<label>& curNbrs = neighboursTable.find(contents[masterI])();
 
-        SLList<SLList<label> >& curFaceFaces =
-            faceFaceTable.find(contents[masterI])();
+            SLList<SLList<label> >& curFaceFaces =
+                faceFaceTable.find(contents[masterI])();
 
-        SLList<label>::iterator nbrsIter = curNbrs.begin();
-        SLList<SLList<label> >::iterator faceFacesIter = curFaceFaces.begin();
+            SLList<label>::iterator nbrsIter = curNbrs.begin();
 
-        for
-        (
-            ;
-            nbrsIter != curNbrs.end(), faceFacesIter != curFaceFaces.end();
-            ++nbrsIter, ++faceFacesIter
-        )
-        {
-            faceCells_[nCoarseFaces] = nbrsIter();
+            SLList<SLList<label> >::iterator faceFacesIter = curFaceFaces.begin();
 
-            forAllConstIter(SLList<label>, faceFacesIter(), facesIter)
+            for
+            (
+                ;
+                nbrsIter != curNbrs.end(), faceFacesIter != curFaceFaces.end();
+                ++nbrsIter, ++faceFacesIter
+            )
             {
-                faceRestrictAddressing_[facesIter() + sizeBy2] = nCoarseFaces;
-            }
+                faceCells_[nCoarseFaces] = nbrsIter();
+
+                for
+                (
+                    SLList<label>::iterator facesIter = faceFacesIter().begin();
+                    facesIter != faceFacesIter().end();
+                    ++facesIter
+                )
+                {
+                    faceRestrictAddressing_[facesIter()] = nCoarseFaces;
+                }
 
-            nCoarseFaces++;
+                nCoarseFaces++;
+            }
         }
     }
 }
@@ -211,42 +245,24 @@ Foam::cyclicGAMGInterface::~cyclicGAMGInterface()
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
-Foam::tmp<Foam::labelField> Foam::cyclicGAMGInterface::transfer
-(
-    const Pstream::commsTypes,
-    const unallocLabelList& interfaceData
-) const
-{
-    tmp<labelField> tpnf(new labelField(size()));
-    labelField& pnf = tpnf();
-
-    label sizeby2 = size()/2;
-
-    for (label facei=0; facei<sizeby2; facei++)
-    {
-        pnf[facei] = interfaceData[facei + sizeby2];
-        pnf[facei + sizeby2] = interfaceData[facei];
-    }
-
-    return tpnf;
-}
-
-
 Foam::tmp<Foam::labelField> Foam::cyclicGAMGInterface::internalFieldTransfer
 (
     const Pstream::commsTypes,
     const unallocLabelList& iF
 ) const
 {
+    const cyclicGAMGInterface& nbr = dynamic_cast<const cyclicGAMGInterface&>
+    (
+        neighbPatch()
+    );
+    const unallocLabelList& nbrFaceCells = nbr.faceCells();
+
     tmp<labelField> tpnf(new labelField(size()));
     labelField& pnf = tpnf();
 
-    label sizeby2 = size()/2;
-
-    for (label facei=0; facei<sizeby2; facei++)
+    forAll(pnf, facei)
     {
-        pnf[facei] = iF[faceCells_[facei + sizeby2]];
-        pnf[facei + sizeby2] = iF[faceCells_[facei]];
+        pnf[facei] = iF[nbrFaceCells[facei]];
     }
 
     return tpnf;
diff --git a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaces/cyclicGAMGInterface/cyclicGAMGInterface.H b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaces/cyclicGAMGInterface/cyclicGAMGInterface.H
index d912cb313cf5591d3d417b59de77511b015a77c7..c24d5fdca70360b24a2001e8c526a8e63e799023 100644
--- a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaces/cyclicGAMGInterface/cyclicGAMGInterface.H
+++ b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaces/cyclicGAMGInterface/cyclicGAMGInterface.H
@@ -80,6 +80,8 @@ public:
         //  local and neighbour restrict addressing
         cyclicGAMGInterface
         (
+            const label index,
+            const lduInterfacePtrsList& coarseInterfaces,
             const lduInterface& fineInterface,
             const labelField& restrictAddressing,
             const labelField& neighbourRestrictAddressing
@@ -94,13 +96,6 @@ public:
 
         // Interface transfer functions
 
-            //- Transfer and return neighbour field
-            virtual tmp<labelField> transfer
-            (
-                const Pstream::commsTypes commsType,
-                const unallocLabelList& interfaceData
-            ) const;
-
             //- Transfer and return internal field adjacent to the interface
             virtual tmp<labelField> internalFieldTransfer
             (
@@ -111,6 +106,25 @@ public:
 
         //- Cyclic interface functions
 
+            //- Return neigbour processor number
+            virtual label neighbPatchID() const
+            {
+                return fineCyclicInterface_.neighbPatchID();
+            }
+
+            virtual bool owner() const
+            {
+                return fineCyclicInterface_.owner();
+            }
+
+            virtual const cyclicGAMGInterface& neighbPatch() const
+            {
+                return dynamic_cast<const cyclicGAMGInterface&>
+                (
+                    coarseInterfaces_[neighbPatchID()]
+                );
+            }
+
             //- Return face transformation tensor
             virtual const tensorField& forwardT() const
             {
diff --git a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaces/processorCyclicGAMGInterface/processorCyclicGAMGInterface.C b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaces/processorCyclicGAMGInterface/processorCyclicGAMGInterface.C
new file mode 100644
index 0000000000000000000000000000000000000000..04559980585acdb4b9d1004ac015a111d52d25c4
--- /dev/null
+++ b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaces/processorCyclicGAMGInterface/processorCyclicGAMGInterface.C
@@ -0,0 +1,73 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
+     \\/     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 2 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, write to the Free Software Foundation,
+    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+\*---------------------------------------------------------------------------*/
+
+#include "processorCyclicGAMGInterface.H"
+#include "addToRunTimeSelectionTable.H"
+#include "Map.H"
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+namespace Foam
+{
+    defineTypeNameAndDebug(processorCyclicGAMGInterface, 0);
+    addToRunTimeSelectionTable
+    (
+        GAMGInterface,
+        processorCyclicGAMGInterface,
+        lduInterface
+    );
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::processorCyclicGAMGInterface::processorCyclicGAMGInterface
+(
+    const label index,
+    const lduInterfacePtrsList& coarseInterfaces,
+    const lduInterface& fineInterface,
+    const labelField& localRestrictAddressing,
+    const labelField& neighbourRestrictAddressing
+)
+:
+    processorGAMGInterface
+    (
+        index,
+        coarseInterfaces,
+        fineInterface,
+        localRestrictAddressing,
+        neighbourRestrictAddressing
+    )
+{}
+
+
+// * * * * * * * * * * * * * * * * Desstructor * * * * * * * * * * * * * * * //
+
+Foam::processorCyclicGAMGInterface::~processorCyclicGAMGInterface()
+{}
+
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaces/processorCyclicGAMGInterface/processorCyclicGAMGInterface.H b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaces/processorCyclicGAMGInterface/processorCyclicGAMGInterface.H
new file mode 100644
index 0000000000000000000000000000000000000000..59d5b99c0e02f82bc2751ef0f0f2430180d467b9
--- /dev/null
+++ b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaces/processorCyclicGAMGInterface/processorCyclicGAMGInterface.H
@@ -0,0 +1,98 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
+     \\/     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 2 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, write to the Free Software Foundation,
+    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+Class
+    Foam::processorCyclicGAMGInterface
+
+Description
+    GAMG agglomerated processor interface.
+
+SourceFiles
+    processorCyclicGAMGInterface.C
+    processorCyclicGAMGInterfaceTemplates.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef processorCyclicGAMGInterface_H
+#define processorCyclicGAMGInterface_H
+
+#include "processorGAMGInterface.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+                  Class processorCyclicGAMGInterface Declaration
+\*---------------------------------------------------------------------------*/
+
+class processorCyclicGAMGInterface
+:
+    public processorGAMGInterface
+{
+    // Private Member Functions
+
+        //- Disallow default bitwise copy construct
+        processorCyclicGAMGInterface(const processorCyclicGAMGInterface&);
+
+        //- Disallow default bitwise assignment
+        void operator=(const processorCyclicGAMGInterface&);
+
+
+public:
+
+    //- Runtime type information
+    TypeName("processorCyclic");
+
+    // Constructors
+
+        //- Construct from fine-level interface,
+        //  local and neighbour restrict addressing
+        processorCyclicGAMGInterface
+        (
+            const label index,
+            const lduInterfacePtrsList& coarseInterfaces,
+            const lduInterface& fineInterface,
+            const labelField& restrictAddressing,
+            const labelField& neighbourRestrictAddressing
+        );
+
+
+    // Destructor
+
+        virtual ~processorCyclicGAMGInterface();
+
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaces/processorGAMGInterface/processorGAMGInterface.C b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaces/processorGAMGInterface/processorGAMGInterface.C
index 1d79ac018efaabb66ca822a1135cbe91b95da472..dc6aaed58920c15d18c6469a15f8b5ec8aa40996 100644
--- a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaces/processorGAMGInterface/processorGAMGInterface.C
+++ b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaces/processorGAMGInterface/processorGAMGInterface.C
@@ -25,6 +25,7 @@ License
 
 #include "processorGAMGInterface.H"
 #include "addToRunTimeSelectionTable.H"
+#include "Map.H"
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
@@ -44,6 +45,8 @@ namespace Foam
 
 Foam::processorGAMGInterface::processorGAMGInterface
 (
+    const label index,
+    const lduInterfacePtrsList& coarseInterfaces,
     const lduInterface& fineInterface,
     const labelField& localRestrictAddressing,
     const labelField& neighbourRestrictAddressing
@@ -51,6 +54,8 @@ Foam::processorGAMGInterface::processorGAMGInterface
 :
     GAMGInterface
     (
+        index,
+        coarseInterfaces,
         fineInterface,
         localRestrictAddressing,
         neighbourRestrictAddressing
@@ -58,13 +63,13 @@ Foam::processorGAMGInterface::processorGAMGInterface
     fineProcInterface_(refCast<const processorLduInterface>(fineInterface))
 {
     // Make a lookup table of entries for owner/neighbour
-    HashTable<SLList<label>, label, Hash<label> > neighboursTable
+    Map<SLList<label> > neighboursTable
     (
         localRestrictAddressing.size()
     );
 
     // Table of face-sets to be agglomerated
-    HashTable<SLList<SLList<label> >, label, Hash<label> > faceFaceTable
+    Map<SLList<SLList<label> > > faceFaceTable
     (
         localRestrictAddressing.size()
     );
@@ -233,26 +238,6 @@ Foam::processorGAMGInterface::~processorGAMGInterface()
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
-void Foam::processorGAMGInterface::initTransfer
-(
-    const Pstream::commsTypes commsType,
-    const unallocLabelList& interfaceData
-) const
-{
-    send(commsType, interfaceData);
-}
-
-
-Foam::tmp<Foam::labelField> Foam::processorGAMGInterface::transfer
-(
-    const Pstream::commsTypes commsType,
-    const unallocLabelList& interfaceData
-) const
-{
-    return receive<label>(commsType, this->size());
-}
-
-
 void Foam::processorGAMGInterface::initInternalFieldTransfer
 (
     const Pstream::commsTypes commsType,
diff --git a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaces/processorGAMGInterface/processorGAMGInterface.H b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaces/processorGAMGInterface/processorGAMGInterface.H
index 6d24e82db0da11d57d8438ae5cd345fd7a7aa1ae..be738700e6ea89bdce98d5548ba1e898ffb9f9e5 100644
--- a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaces/processorGAMGInterface/processorGAMGInterface.H
+++ b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaces/processorGAMGInterface/processorGAMGInterface.H
@@ -80,6 +80,8 @@ public:
         //  local and neighbour restrict addressing
         processorGAMGInterface
         (
+            const label index,
+            const lduInterfacePtrsList& coarseInterfaces,
             const lduInterface& fineInterface,
             const labelField& restrictAddressing,
             const labelField& neighbourRestrictAddressing
@@ -94,20 +96,6 @@ public:
 
         // Interface transfer functions
 
-            //- Initialise interface data transfer
-            virtual void initTransfer
-            (
-                const Pstream::commsTypes commsType,
-                const unallocLabelList& interfaceData
-            ) const;
-
-            //- Transfer and return neighbour field
-            virtual tmp<labelField> transfer
-            (
-                const Pstream::commsTypes commsType,
-                const unallocLabelList& interfaceData
-            ) const;
-
             //- Initialise neighbour field transfer
             virtual void initInternalFieldTransfer
             (
@@ -142,6 +130,12 @@ public:
             {
                 return fineProcInterface_.forwardT();
             }
+
+            //- Return message tag used for sending
+            virtual int tag() const
+            {
+                return fineProcInterface_.tag();
+            }   
 };
 
 
diff --git a/src/OpenFOAM/meshes/pointMesh/pointPatches/constraint/cyclic/cyclicPointPatch.C b/src/OpenFOAM/meshes/pointMesh/pointPatches/constraint/cyclic/cyclicPointPatch.C
index 58078a615ca0c4ebf5720d415b085f34691d2de0..7a703c260762ff5cce205998023b835b92b89396 100644
--- a/src/OpenFOAM/meshes/pointMesh/pointPatches/constraint/cyclic/cyclicPointPatch.C
+++ b/src/OpenFOAM/meshes/pointMesh/pointPatches/constraint/cyclic/cyclicPointPatch.C
@@ -51,28 +51,7 @@ void Foam::cyclicPointPatch::initGeometry(PstreamBuffers&)
 
 
 void Foam::cyclicPointPatch::calcGeometry(PstreamBuffers&)
-{
-    const edgeList& cp = cyclicPolyPatch_.coupledPoints();
-    const labelList& mp = cyclicPolyPatch_.meshPoints();
-
-    DynamicList<label> separated;
-    forAll(cp, i)
-    {
-        const edge& coupledSet = cp[i];
-
-        // Assume all points are separated.
-        separated.append(coupledSet[0]);
-        separated.append(coupledSet[1]);
-    }
-    separatedPoints_.transfer(separated);
-
-    if (debug)
-    {
-        Pout<< "cyclic:" << cyclicPolyPatch_.name()
-            << " separated:" << separatedPoints_.size()
-            << " out of points:" << mp.size() << endl;
-    }
-}
+{}
 
 
 void Foam::cyclicPointPatch::initMovePoints(PstreamBuffers&, const pointField&)
@@ -124,10 +103,4 @@ const Foam::edgeList& Foam::cyclicPointPatch::transformPairs() const
 }
 
 
-const Foam::labelList& Foam::cyclicPointPatch::separatedPoints() const
-{
-    return separatedPoints_;
-}
-
-
 // ************************************************************************* //
diff --git a/src/OpenFOAM/meshes/pointMesh/pointPatches/constraint/cyclic/cyclicPointPatch.H b/src/OpenFOAM/meshes/pointMesh/pointPatches/constraint/cyclic/cyclicPointPatch.H
index 2682c194c8ecb921db0ba971ba5e97025435b74c..8e1849a52c01aea614a820c439f92774490aecd2 100644
--- a/src/OpenFOAM/meshes/pointMesh/pointPatches/constraint/cyclic/cyclicPointPatch.H
+++ b/src/OpenFOAM/meshes/pointMesh/pointPatches/constraint/cyclic/cyclicPointPatch.H
@@ -37,6 +37,7 @@ SourceFiles
 
 #include "coupledFacePointPatch.H"
 #include "cyclicPolyPatch.H"
+#include "pointBoundaryMesh.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -56,8 +57,6 @@ class cyclicPointPatch
         //- Local reference cast into the cyclic patch
         const cyclicPolyPatch& cyclicPolyPatch_;
 
-        //- List of local points that are not collocated
-        mutable labelList separatedPoints_;
 
     // Private Member Functions
 
@@ -125,6 +124,14 @@ public:
                 return cyclicPolyPatch_;
             }
 
+            //- Return neighbour point patch
+            const cyclicPointPatch& neighbPatch() const
+            {
+                label patchI = cyclicPolyPatch_.neighbPatchID();
+                const pointPatch& pp = this->boundaryMesh()[patchI];
+                return refCast<const cyclicPointPatch>(pp);
+            }
+
             //- Are the cyclic planes parallel
             bool parallel() const
             {
@@ -147,11 +154,10 @@ public:
         // Access functions for demand driven data
 
             //- Return the set of pairs of points that require transformation
-            //  and/or mapping
+            //  and/or mapping. First index is on this patch, second on the
+            //  neighbour patch.
             virtual const edgeList& transformPairs() const;
 
-            //- List of separated coupled points
-            virtual const labelList& separatedPoints() const;
 };
 
 
diff --git a/src/OpenFOAM/meshes/pointMesh/pointPatches/constraint/processor/processorPointPatch.C b/src/OpenFOAM/meshes/pointMesh/pointPatches/constraint/processor/processorPointPatch.C
index 79faa898cb5dea58bd12aed855b035782486ca89..da6fa3822fcfbdca1025533fb23321ae25ae6939 100644
--- a/src/OpenFOAM/meshes/pointMesh/pointPatches/constraint/processor/processorPointPatch.C
+++ b/src/OpenFOAM/meshes/pointMesh/pointPatches/constraint/processor/processorPointPatch.C
@@ -73,51 +73,7 @@ void Foam::processorPointPatch::initGeometry(PstreamBuffers& pBufs)
 
 
 void Foam::processorPointPatch::calcGeometry(PstreamBuffers& pBufs)
-{
-    if (Pstream::parRun())
-    {
-        const boolList& collocated = procPolyPatch_.collocated();
-
-        if (collocated.size() == 0)
-        {
-            separatedPoints_.setSize(0);
-        }
-        else if (collocated.size() == 1)
-        {
-            // Uniformly
-            if (collocated[0])
-            {
-                separatedPoints_.setSize(0);
-            }
-            else
-            {
-                separatedPoints_ = identity(size());
-            }
-        }
-        else
-        {
-            // Per face collocated or not.
-            const labelListList& pointFaces = procPolyPatch_.pointFaces();
-
-            DynamicList<label> separated;
-            forAll(pointFaces, pfi)
-            {
-                if (!collocated[pointFaces[pfi][0]])
-                {
-                    separated.append(pfi);
-                }
-            }
-            separatedPoints_.transfer(separated);
-        }
-    }
-
-    if (debug)
-    {
-        Pout<< "processor:" << name()
-            << " separated:" << separatedPoints_.size()
-            << " out of points:" << size() << endl;
-    }
-}
+{}
 
 
 void Foam::processorPointPatch::initMovePoints
@@ -173,10 +129,4 @@ const Foam::labelList& Foam::processorPointPatch::reverseMeshPoints() const
 }
 
 
-const Foam::labelList& Foam::processorPointPatch::separatedPoints() const
-{
-    return separatedPoints_;
-}
-
-
 // ************************************************************************* //
diff --git a/src/OpenFOAM/meshes/pointMesh/pointPatches/constraint/processor/processorPointPatch.H b/src/OpenFOAM/meshes/pointMesh/pointPatches/constraint/processor/processorPointPatch.H
index 1654b58d4bf03582abfbaad1bd47aaa9cf0408a8..97faee107b18eb96787641dcc2866f2893beb227 100644
--- a/src/OpenFOAM/meshes/pointMesh/pointPatches/constraint/processor/processorPointPatch.H
+++ b/src/OpenFOAM/meshes/pointMesh/pointPatches/constraint/processor/processorPointPatch.H
@@ -65,7 +65,6 @@ class processorPointPatch
 
         mutable labelList reverseMeshPoints_;
 
-        mutable labelList separatedPoints_;
 
     // Private Member Functions
 
@@ -129,6 +128,12 @@ public:
             }
         }
 
+        //- Return message tag to use for communication
+        virtual int tag() const
+        {
+            return procPolyPatch_.tag();
+        }
+
         //- Return the constraint type this pointPatch implements.
         virtual const word& constraintType() const
         {
@@ -168,9 +173,6 @@ public:
         //- Return mesh points in the correct order for the receiving side
         const labelList& reverseMeshPoints() const;
 
-        //- List of separated coupled points
-        virtual const labelList& separatedPoints() const;
-
 };
 
 
diff --git a/src/OpenFOAM/meshes/pointMesh/pointPatches/constraint/processorCyclic/processorCyclicPointPatch.C b/src/OpenFOAM/meshes/pointMesh/pointPatches/constraint/processorCyclic/processorCyclicPointPatch.C
new file mode 100644
index 0000000000000000000000000000000000000000..97fd1611db6579f40d2cc18d319fb58512c933b3
--- /dev/null
+++ b/src/OpenFOAM/meshes/pointMesh/pointPatches/constraint/processorCyclic/processorCyclicPointPatch.C
@@ -0,0 +1,400 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
+     \\/     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 2 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, write to the Free Software Foundation,
+    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+\*---------------------------------------------------------------------------*/
+
+#include "processorCyclicPointPatch.H"
+#include "pointBoundaryMesh.H"
+#include "addToRunTimeSelectionTable.H"
+//#include "pointMesh.H"
+//#include "globalPointPatch.H"
+//#include "faceList.H"
+//#include "primitiveFacePatch.H"
+//#include "emptyPolyPatch.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+defineTypeNameAndDebug(processorCyclicPointPatch, 0);
+
+addToRunTimeSelectionTable
+(
+    facePointPatch,
+    processorCyclicPointPatch,
+    polyPatch
+);
+
+
+// * * * * * * * * * * * * * Protected Member Functions  * * * * * * * * * * //
+
+//void Foam::processorCyclicPointPatch::initGeometry(PstreamBuffers& pBufs)
+//{
+//    // Algorithm:
+//    // Depending on whether the patch is a master or a slave, get the primitive
+//    // patch points and filter away the points from the global patch.
+//
+//    if (isMaster())
+//    {
+//        meshPoints_ = procPolyPatch_.meshPoints();
+//    }
+//    else
+//    {
+//        // Slave side. Create the reversed patch and pick up its points
+//        // so that the order is correct
+//        const polyPatch& pp = patch();
+//
+//        faceList masterFaces(pp.size());
+//
+//        forAll (pp, faceI)
+//        {
+//            masterFaces[faceI] = pp[faceI].reverseFace();
+//        }
+//
+//        meshPoints_ = primitiveFacePatch
+//        (
+//            masterFaces,
+//            pp.points()
+//        ).meshPoints();
+//    }
+//
+//    if (Pstream::parRun())
+//    {
+//        initPatchPatchPoints(pBufs);
+//    }
+//}
+//
+//
+//void Foam::processorCyclicPointPatch::calcGeometry(PstreamBuffers& pBufs)
+//{
+//    if (Pstream::parRun())
+//    {
+//        calcPatchPatchPoints(pBufs);
+//    }
+//
+//    // If it is not runing parallel or there are no global points
+//    // create a 1->1 map
+//    if
+//    (
+//        !Pstream::parRun()
+//     || !boundaryMesh().mesh().globalData().nGlobalPoints()
+//    )
+//    {
+//        nonGlobalPatchPoints_.setSize(meshPoints_.size());
+//        forAll(nonGlobalPatchPoints_, i)
+//        {
+//            nonGlobalPatchPoints_[i] = i;
+//        }
+//    }
+//    else
+//    {
+//        // Get reference to shared points
+//        const labelList& sharedPoints =
+//            boundaryMesh().globalPatch().meshPoints();
+//
+//        nonGlobalPatchPoints_.setSize(meshPoints_.size());
+//
+//        label noFiltPoints = 0;
+//
+//        forAll (meshPoints_, pointI)
+//        {
+//            label curP = meshPoints_[pointI];
+//
+//            bool found = false;
+//
+//            forAll (sharedPoints, sharedI)
+//            {
+//                if (sharedPoints[sharedI] == curP)
+//                {
+//                    found = true;
+//                    break;
+//                }
+//            }
+//
+//            if (!found)
+//            {
+//                nonGlobalPatchPoints_[noFiltPoints] = pointI;
+//                meshPoints_[noFiltPoints] = curP;
+//                noFiltPoints++;
+//            }
+//        }
+//
+//        nonGlobalPatchPoints_.setSize(noFiltPoints);
+//        meshPoints_.setSize(noFiltPoints);
+//    }
+//}
+//
+//
+//void processorCyclicPointPatch::initPatchPatchPoints(PstreamBuffers& pBufs)
+//{
+//    if (debug)
+//    {
+//        Info<< "processorCyclicPointPatch::initPatchPatchPoints(PstreamBuffers&) : "
+//            << "constructing patch-patch points"
+//            << endl;
+//    }
+//
+//    const polyBoundaryMesh& bm = boundaryMesh().mesh()().boundaryMesh();
+//
+//    // Get the mesh points for this patch corresponding to the faces
+//    const labelList& ppmp = meshPoints();
+//
+//    // Create a HashSet of the point labels for this patch
+//    Map<label> patchPointSet(2*ppmp.size());
+//
+//    forAll (ppmp, ppi)
+//    {
+//        patchPointSet.insert(ppmp[ppi], ppi);
+//    }
+//
+//
+//    // Create the lists of patch-patch points
+//    labelListList patchPatchPoints(bm.size());
+//
+//    // Create the lists of patch-patch point normals
+//    List<List<vector> > patchPatchPointNormals(bm.size());
+//
+//    // Loop over all patches looking for other patches that share points
+//    forAll(bm, patchi)
+//    {
+//        if
+//        (
+//            patchi != index()                 // Ignore self-self
+//         && !isA<emptyPolyPatch>(bm[patchi])  // Ignore empty
+//         && !bm[patchi].coupled()             // Ignore other couples
+//        )
+//        {
+//            // Get the meshPoints for the other patch
+//            const labelList& meshPoints = bm[patchi].meshPoints();
+//
+//            // Get the normals for the other patch
+//            const vectorField& normals = bm[patchi].pointNormals();
+//
+//            label pppi = 0;
+//            forAll(meshPoints, pointi)
+//            {
+//                label ppp = meshPoints[pointi];
+//
+//                // Check to see if the point of the other patch is shared with
+//                // this patch
+//                Map<label>::iterator iter = patchPointSet.find(ppp);
+//
+//                if (iter != patchPointSet.end())
+//                {
+//                    // If it is shared initialise the patchPatchPoints for this
+//                    // patch
+//                    if (!patchPatchPoints[patchi].size())
+//                    {
+//                        patchPatchPoints[patchi].setSize(ppmp.size());
+//                        patchPatchPointNormals[patchi].setSize(ppmp.size());
+//                    }
+//
+//                    // and add the entry
+//                    patchPatchPoints[patchi][pppi] = iter();
+//                    patchPatchPointNormals[patchi][pppi] = normals[pointi];
+//                    pppi++;
+//                }
+//            }
+//
+//            // Resise the list of shared points and normals for the patch
+//            // being considerd
+//            patchPatchPoints[patchi].setSize(pppi);
+//            patchPatchPointNormals[patchi].setSize(pppi);
+//        }
+//    }
+//
+//    // Send the patchPatchPoints to the neighbouring processor
+//
+//    UOPstream toNeighbProc(neighbProcNo(), pBufs);
+//
+//    toNeighbProc
+//        << ppmp.size()              // number of points for checking
+//        << patchPatchPoints
+//        << patchPatchPointNormals;
+//
+//    if (debug)
+//    {
+//        Info<< "processorCyclicPointPatch::initPatchPatchPoints() : "
+//            << "constructed patch-patch points"
+//            << endl;
+//    }
+//}
+//
+//
+//void Foam::processorCyclicPointPatch::calcPatchPatchPoints(PstreamBuffers& pBufs)
+//{
+//    // Get the patchPatchPoints from the neighbouring processor
+//    UIPstream fromNeighbProc(neighbProcNo(), pBufs);
+//
+//    label nbrNPoints(readLabel(fromNeighbProc));
+//    labelListList patchPatchPoints(fromNeighbProc);
+//    List<List<vector> > patchPatchPointNormals(fromNeighbProc);
+//
+//    pointBoundaryMesh& pbm = const_cast<pointBoundaryMesh&>(boundaryMesh());
+//    const labelList& ppmp = meshPoints();
+//
+//    // Simple check for the very rare situation when not the same number
+//    // of points on both sides. This can happen with decomposed cyclics.
+//    // If on one side the cyclic shares a point with proc faces coming from
+//    // internal faces it will have a different number of points from
+//    // the situation where the cyclic and the 'normal' proc faces are fully
+//    // separate.
+//    if (nbrNPoints != ppmp.size())
+//    {
+//        WarningIn("processorCyclicPointPatch::calcPatchPatchPoints(PstreamBuffers&)")
+//            << "Processor patch " << name()
+//            << " has " << ppmp.size() << " points; coupled patch has "
+//            << nbrNPoints << " points." << endl
+//            << "   (usually due to decomposed cyclics)."
+//            << " This might give problems" << endl
+//            << "    when using point fields (interpolation, mesh motion)."
+//            << endl;
+//    }
+//
+//
+//
+//    // Loop over the patches looking for other patches that share points
+//    forAll(patchPatchPoints, patchi)
+//    {
+//        const labelList& patchPoints = patchPatchPoints[patchi];
+//        const List<vector>& patchPointNormals = patchPatchPointNormals[patchi];
+//
+//        // If there are potentially shared points for the patch being considered
+//        if (patchPoints.size())
+//        {
+//            // Get the current meshPoints list for the patch
+//            facePointPatch& fpp = refCast<facePointPatch>(pbm[patchi]);
+//            const labelList& fmp = fpp.meshPoints();
+//            labelList& mp = fpp.meshPoints_;
+//
+//            const vectorField& fnormals = fpp.pointNormals();
+//            vectorField& normals = fpp.pointNormals_;
+//
+//            // Create a HashSet of the point labels for the patch
+//            Map<label> patchPointSet(2*fmp.size());
+//
+//            forAll (fmp, ppi)
+//            {
+//                patchPointSet.insert(fmp[ppi], ppi);
+//            }
+//
+//            label nPoints = mp.size();
+//            label lpi = 0;
+//            bool resized = false;
+//
+//            // For each potentially shared point...
+//            forAll(patchPoints, ppi)
+//            {
+//                // Check if it is not already in the patch,
+//                // i.e. not part of a face of the patch
+//                if (!patchPointSet.found(ppmp[patchPoints[ppi]]))
+//                {
+//                    // If it isn't already in the patch check if the local
+//                    // meshPoints is already set and if not initialise the
+//                    // meshPoints_ and pointNormals_
+//                    if (!resized)
+//                    {
+//                        if (!mp.size() && fmp.size())
+//                        {
+//                            mp = fmp;
+//                            normals = fnormals;
+//
+//                            nPoints = mp.size();
+//                        }
+//
+//                        mp.setSize(nPoints + patchPoints.size());
+//                        loneMeshPoints_.setSize(patchPoints.size());
+//                        normals.setSize(nPoints + patchPoints.size());
+//                        resized = true;
+//                    }
+//
+//                    // Add the new point to the patch
+//                    mp[nPoints] = ppmp[patchPoints[ppi]];
+//                    loneMeshPoints_[lpi++] = ppmp[patchPoints[ppi]];
+//                    normals[nPoints++] = patchPointNormals[ppi];
+//                }
+//            }
+//
+//            // If the lists have been resized points have been added.
+//            // Shrink the lists to the current size.
+//            if (resized)
+//            {
+//                mp.setSize(nPoints);
+//                loneMeshPoints_.setSize(lpi);
+//                normals.setSize(nPoints);
+//            }
+//        }
+//    }
+//}
+
+
+//void processorCyclicPointPatch::initMovePoints(PstreamBuffers&, const pointField&)
+//{}
+//
+//
+//void processorCyclicPointPatch::movePoints(PstreamBuffers&, const pointField&)
+//{}
+//
+//
+//void processorCyclicPointPatch::initUpdateMesh(PstreamBuffers& pBufs)
+//{
+//    facePointPatch::initUpdateMesh(pBufs);
+//    processorCyclicPointPatch::initGeometry(pBufs);
+//}
+//
+//
+//void processorCyclicPointPatch::updateMesh(PstreamBuffers& pBufs)
+//{
+//    facePointPatch::updateMesh(pBufs);
+//    processorCyclicPointPatch::calcGeometry(pBufs);
+//}
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+processorCyclicPointPatch::processorCyclicPointPatch
+(
+    const polyPatch& patch,
+    const pointBoundaryMesh& bm
+)
+:
+    processorPointPatch(patch, bm),
+    procCycPolyPatch_(refCast<const processorCyclicPolyPatch>(patch))
+{}
+
+
+// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
+
+processorCyclicPointPatch::~processorCyclicPointPatch()
+{}
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/meshes/pointMesh/pointPatches/constraint/processorCyclic/processorCyclicPointPatch.H b/src/OpenFOAM/meshes/pointMesh/pointPatches/constraint/processorCyclic/processorCyclicPointPatch.H
new file mode 100644
index 0000000000000000000000000000000000000000..9363e5096c94406d9b00d068e276be4cb3439f38
--- /dev/null
+++ b/src/OpenFOAM/meshes/pointMesh/pointPatches/constraint/processorCyclic/processorCyclicPointPatch.H
@@ -0,0 +1,156 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
+     \\/     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 2 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, write to the Free Software Foundation,
+    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+Class
+    Foam::processorCyclicPointPatch
+
+Description
+    Processor patch boundary needs to be such that the ordering of
+    points in the patch is the same on both sides.
+
+    Looking at the creation of the faces on both sides of the processor
+    patch they need to be identical on both sides with the normals pointing
+    in opposite directions.  This is achieved by calling the reverseFace
+    function in the decomposition.  It is therefore possible to re-create
+    the ordering of patch points on the slave side by reversing all the
+    patch faces of the owner.
+
+SourceFiles
+    processorCyclicPointPatch.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef processorCyclicPointPatch_H
+#define processorCyclicPointPatch_H
+
+#include "processorPointPatch.H"
+#include "processorCyclicPolyPatch.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+                      Class processorCyclicPointPatch Declaration
+\*---------------------------------------------------------------------------*/
+
+class processorCyclicPointPatch
+:
+    public processorPointPatch
+{
+    // Private data
+
+        const processorCyclicPolyPatch& procCycPolyPatch_;
+
+        //- Disallow default construct as copy
+        processorCyclicPointPatch(const processorCyclicPointPatch&);
+
+        //- Disallow default assignment
+        void operator=(const processorCyclicPointPatch&);
+
+public:
+
+    //- Runtime type information
+    TypeName(processorCyclicPolyPatch::typeName_());
+
+
+    // Constructors
+
+        //- Construct from components
+        processorCyclicPointPatch
+        (
+            const polyPatch& patch,
+            const pointBoundaryMesh& bm
+        );
+
+
+    // Destructor
+
+        virtual ~processorCyclicPointPatch();
+
+
+    // Member functions
+
+
+        //- Return message tag to use for communication
+        virtual int tag() const
+        {
+            return procCycPolyPatch_.tag();
+        }
+
+//        //- Return true if running parallel
+//        virtual bool coupled() const
+//        {
+//            if (Pstream::parRun())
+//            {
+//                return true;
+//            }
+//            else
+//            {
+//                return false;
+//            }
+//        }
+//
+//        //- Return processor number
+//        int myProcNo() const
+//        {
+//            return procPolyPatch_.myProcNo();
+//        }
+//
+//        //- Return neigbour processor number
+//        int neighbProcNo() const
+//        {
+//            return procPolyPatch_.neighbProcNo();
+//        }
+//
+//        //- Is this a master patch
+//        bool isMaster() const
+//        {
+//            return myProcNo() < neighbProcNo();
+//        }
+//
+//        //- Is this a slave patch
+//        bool isSlave() const
+//        {
+//            return !isMaster();
+//        }
+//
+        //- Return the underlying processorCyclicPolyPatch
+        const processorCyclicPolyPatch& procCyclicPolyPatch() const
+        {
+            return procCycPolyPatch_;
+        }
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/meshes/pointMesh/pointPatches/derived/coupled/coupledFacePointPatch.H b/src/OpenFOAM/meshes/pointMesh/pointPatches/derived/coupled/coupledFacePointPatch.H
index 7237290e0409fec51dfb40d8f71aac9ed14b5a21..278b56c07711431ed24ee680f13dc75da72633b7 100644
--- a/src/OpenFOAM/meshes/pointMesh/pointPatches/derived/coupled/coupledFacePointPatch.H
+++ b/src/OpenFOAM/meshes/pointMesh/pointPatches/derived/coupled/coupledFacePointPatch.H
@@ -108,8 +108,6 @@ public:
                 return true;
             }
 
-            //- List of separated coupled points
-            virtual const labelList& separatedPoints() const = 0;
 };
 
 
diff --git a/src/OpenFOAM/meshes/polyMesh/globalMeshData/globalMeshData.C b/src/OpenFOAM/meshes/polyMesh/globalMeshData/globalMeshData.C
index 3931db5b6a9ce0b2619f6041271cb539df069ddb..3daa288e74cf70b59c2117373b5cec2d6e5a20e0 100644
--- a/src/OpenFOAM/meshes/polyMesh/globalMeshData/globalMeshData.C
+++ b/src/OpenFOAM/meshes/polyMesh/globalMeshData/globalMeshData.C
@@ -77,34 +77,38 @@ void Foam::globalMeshData::initProcAddr()
 
     if (Pstream::parRun())
     {
+        PstreamBuffers pBufs(Pstream::nonBlocking);
+
         // Send indices of my processor patches to my neighbours
         forAll(processorPatches_, i)
         {
             label patchi = processorPatches_[i];
 
-            OPstream toNeighbour
+            UOPstream toNeighbour
             (
-                Pstream::blocking,
                 refCast<const processorPolyPatch>
                 (
                     mesh_.boundaryMesh()[patchi]
-                ).neighbProcNo()
+                ).neighbProcNo(),
+                pBufs
             );
 
             toNeighbour << processorPatchIndices_[patchi];
         }
 
+        pBufs.finishedSends();
+
         forAll(processorPatches_, i)
         {
             label patchi = processorPatches_[i];
 
-            IPstream fromNeighbour
+            UIPstream fromNeighbour
             (
-                Pstream::blocking,
                 refCast<const processorPolyPatch>
                 (
                     mesh_.boundaryMesh()[patchi]
-                ).neighbProcNo()
+                ).neighbProcNo(),
+                pBufs
             );
 
             fromNeighbour >> processorPatchNeighbours_[patchi];
@@ -2000,24 +2004,10 @@ void Foam::globalMeshData::updateMesh()
     {
         label patchI = processorPatches_[i];
 
-        const processorPolyPatch& procPatch =
-            refCast<const processorPolyPatch>(mesh_.boundaryMesh()[patchI]);
-
-        if (Pstream::myProcNo() > procPatch.neighbProcNo())
+        if (isType<processorPolyPatch>(mesh_.boundaryMesh()[patchI]))
         {
-            // Uncount my faces. Handle cyclics separately.
-
-            if (procPatch.separated())
-            {
-                const vectorField& separationDist = procPatch.separation();
-
-                nTotalFaces_ -= countCoincidentFaces(tolDim, separationDist);
-            }
-            else
-            {
-                // Normal, unseparated processor patch. Remove duplicates.
-                nTotalFaces_ -= procPatch.size();
-            }
+            // Normal, unseparated processor patch. Remove duplicates.
+            nTotalFaces_ -= mesh_.boundaryMesh()[patchI].size();
         }
     }
     reduce(nTotalFaces_, sumOp<label>());
@@ -2060,6 +2050,8 @@ void Foam::globalMeshData::updateMesh()
             pointStatus.set(meshPointI, SHARED);
         }
 
+        PstreamBuffers pBufs(Pstream::nonBlocking);
+
         // Send patch local points
         forAll(processorPatches_, i)
         {
@@ -2068,11 +2060,13 @@ void Foam::globalMeshData::updateMesh()
             const processorPolyPatch& procPatch =
                 refCast<const processorPolyPatch>(mesh_.boundaryMesh()[patchI]);
 
-            OPstream toNeighbour(Pstream::blocking, procPatch.neighbProcNo());
+            UOPstream toNeighbour(procPatch.neighbProcNo(), pBufs);
 
             toNeighbour << procPatch.localPoints();
         }
 
+        pBufs.finishedSends();
+
         // Receive patch local points and uncount if coincident (and not shared)
         forAll(processorPatches_, i)
         {
@@ -2081,7 +2075,7 @@ void Foam::globalMeshData::updateMesh()
             const processorPolyPatch& procPatch =
                 refCast<const processorPolyPatch>(mesh_.boundaryMesh()[patchI]);
 
-            IPstream fromNeighbour(Pstream::blocking, procPatch.neighbProcNo());
+            UIPstream fromNeighbour(procPatch.neighbProcNo(), pBufs);
 
             pointField nbrPoints(fromNeighbour);
 
diff --git a/src/OpenFOAM/meshes/polyMesh/globalMeshData/globalPoints.C b/src/OpenFOAM/meshes/polyMesh/globalMeshData/globalPoints.C
index 270be1dd77db4eee18ea8181061d1656602ac185..03070256454ae90fbeb3ae719b399b3ddb3e166e 100644
--- a/src/OpenFOAM/meshes/polyMesh/globalMeshData/globalPoints.C
+++ b/src/OpenFOAM/meshes/polyMesh/globalMeshData/globalPoints.C
@@ -25,6 +25,7 @@ License
 
 #include "globalPoints.H"
 #include "processorPolyPatch.H"
+#include "processorCyclicPolyPatch.H"
 #include "cyclicPolyPatch.H"
 #include "polyMesh.H"
 
@@ -40,45 +41,6 @@ const Foam::label Foam::globalPoints::fromCollocated = labelMax/2;
 // Routines to handle global indices
 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-Foam::PackedBoolList Foam::globalPoints::collocatedPoints
-(
-    const coupledPolyPatch& pp
-)
-{
-    // Initialise to false
-    PackedBoolList isCollocated(pp.nPoints());
-
-    const boolList& collocated = pp.collocated();
-
-    if (collocated.size() == 0)
-    {
-        isCollocated = 1;
-    }
-    else if (collocated.size() == 1)
-    {
-        // Uniform.
-        if (collocated[0])
-        {
-            isCollocated = 1;
-        }
-    }
-    else
-    {
-        // Per face collocated or not.
-        const labelListList& pointFaces = pp.pointFaces();
-
-        forAll(pointFaces, pfi)
-        {
-            if (collocated[pointFaces[pfi][0]])
-            {
-                isCollocated[pfi] = 1;
-            }
-        }
-    }
-    return isCollocated;
-}
-    
-
 Foam::label Foam::globalPoints::toGlobal
 (
     const label localPointI,
@@ -369,16 +331,9 @@ void Foam::globalPoints::initOwnPoints
          || isA<cyclicPolyPatch>(pp)
         )
         {
-            // Find points with transforms
-
-            PackedBoolList isCollocatedPoint
-            (
-                collocatedPoints
-                (
-                    refCast<const coupledPolyPatch>(pp)
-                )
-            );
-
+            // Assume all processor points are collocated and all
+            // processorCyclic and cyclic are separated.
+            bool isCollocatedPoint = isType<processorPolyPatch>(pp);
 
             const labelList& meshPoints = pp.meshPoints();
 
@@ -396,7 +351,7 @@ void Foam::globalPoints::initOwnPoints
                     labelList knownInfo
                     (
                         1,
-                        toGlobal(localPointI, isCollocatedPoint[patchPointI])
+                        toGlobal(localPointI, isCollocatedPoint)
                     );
 
                     // Update addressing from point to index in procPoints
@@ -425,11 +380,7 @@ void Foam::globalPoints::initOwnPoints
                     labelList knownInfo
                     (
                         1,
-                        toGlobal
-                        (
-                            localPointI,
-                            isCollocatedPoint[boundaryPoints[i]]
-                        )
+                        toGlobal(localPointI, isCollocatedPoint)
                     );
 
                     // Update addressing from point to index in procPoints
@@ -461,20 +412,21 @@ void Foam::globalPoints::sendPatchPoints
     {
         const polyPatch& pp = patches[patchI];
 
-        if (Pstream::parRun() && isA<processorPolyPatch>(pp))
+        if
+        (
+            Pstream::parRun()
+         && (
+                isType<processorPolyPatch>(pp)
+             || (mergeSeparated && isA<processorCyclicPolyPatch>(pp))
+            )
+        )
         {
+            // processor cyclics are considered separated, pure processor
+            // always collocated.
+
             const processorPolyPatch& procPatch =
                 refCast<const processorPolyPatch>(pp);
 
-            PackedBoolList isCollocatedPoint
-            (
-                collocatedPoints
-                (
-                    procPatch
-                )
-            );
-
-
             // Information to send:
             // patch face
             DynamicList<label> patchFaces(pp.nPoints());
@@ -492,34 +444,31 @@ void Foam::globalPoints::sendPatchPoints
 
             forAll(meshPoints, patchPointI)
             {
-                if (mergeSeparated || isCollocatedPoint[patchPointI])
+                label meshPointI = meshPoints[patchPointI];
+                label localPointI = meshToLocalPoint
+                (
+                    meshToPatchPoint,
+                    meshPointI
+                );
+
+                if (changedPoints.found(localPointI))
                 {
-                    label meshPointI = meshPoints[patchPointI];
-                    label localPointI = meshToLocalPoint
-                    (
-                        meshToPatchPoint,
-                        meshPointI
-                    );
+                    label index = meshToProcPoint_[localPointI];
 
-                    if (changedPoints.found(localPointI))
-                    {
-                        label index = meshToProcPoint_[localPointI];
+                    const labelList& knownInfo = procPoints_[index];
 
-                        const labelList& knownInfo = procPoints_[index];
+                    // Add my information about localPointI to the
+                    // send buffers
+                    addToSend
+                    (
+                        pp,
+                        patchPointI,
+                        knownInfo,
 
-                        // Add my information about localPointI to the
-                        // send buffers
-                        addToSend
-                        (
-                            pp,
-                            patchPointI,
-                            knownInfo,
-
-                            patchFaces,
-                            indexInFace,
-                            allInfo
-                        );
-                    }
+                        patchFaces,
+                        indexInFace,
+                        allInfo
+                    );
                 }
             }
 
@@ -560,18 +509,20 @@ void Foam::globalPoints::receivePatchPoints
     {
         const polyPatch& pp = patches[patchI];
 
-        if (Pstream::parRun() && isA<processorPolyPatch>(pp))
+        if
+        (
+            Pstream::parRun()
+         && (
+                isType<processorPolyPatch>(pp)
+             || (mergeSeparated && isA<processorCyclicPolyPatch>(pp))
+            )
+        )
         {
             const processorPolyPatch& procPatch =
                 refCast<const processorPolyPatch>(pp);
 
-            PackedBoolList isCollocatedPoint
-            (
-                collocatedPoints
-                (
-                    procPatch
-                )
-            );
+            // Processor patch is always collocated, processorCyclic is not.
+            bool isCollocatedPoint = isType<processorPolyPatch>(pp);
 
             labelList patchFaces;
             labelList indexInFace;
@@ -605,21 +556,13 @@ void Foam::globalPoints::receivePatchPoints
                     meshPointI
                 );
 
-                if
-                (
-                    storeInfo
-                    (
-                        nbrInfo[i],
-                        localPointI,
-                        isCollocatedPoint[pp.meshPointMap()[meshPointI]]
-                    )
-                )
+                if (storeInfo(nbrInfo[i], localPointI, isCollocatedPoint))
                 {
                     changedPoints.insert(localPointI);
                 }
             }
         }
-        else if (isA<cyclicPolyPatch>(pp))
+        else if (mergeSeparated && isA<cyclicPolyPatch>(pp))
         {
             // Handle cyclics: send lower half to upper half and vice versa.
             // Or since they both are in memory just do it point by point.
@@ -627,80 +570,49 @@ void Foam::globalPoints::receivePatchPoints
             const cyclicPolyPatch& cycPatch =
                 refCast<const cyclicPolyPatch>(pp);
 
-            PackedBoolList isCollocatedPoint
-            (
-                collocatedPoints
-                (
-                    cycPatch
-                )
-            );
-
             const labelList& meshPoints = pp.meshPoints();
+            const labelList coupledMeshPoints(reverseMeshPoints(cycPatch));
 
-            //const edgeList& connections = cycPatch.coupledPoints();
-            const edgeList connections(coupledPoints(cycPatch));
-
-            forAll(connections, i)
+            forAll(meshPoints, i)
             {
-                const edge& e = connections[i];
+                label meshPointA = meshPoints[i];
+                label meshPointB = coupledMeshPoints[i];
 
-                if (mergeSeparated || isCollocatedPoint[e[0]])
-                {
-                    label meshPointA = meshPoints[e[0]];
-                    label meshPointB = meshPoints[e[1]];
-
-                    label localA = meshToLocalPoint
-                    (
-                        meshToPatchPoint,
-                        meshPointA
-                    );
-                    label localB = meshToLocalPoint
-                    (
-                        meshToPatchPoint,
-                        meshPointB
-                    );
+                label localA = meshToLocalPoint
+                (
+                    meshToPatchPoint,
+                    meshPointA
+                );
+                label localB = meshToLocalPoint
+                (
+                    meshToPatchPoint,
+                    meshPointB
+                );
 
 
-                    // Do we have information on pointA?
-                    Map<label>::iterator procPointA =
-                        meshToProcPoint_.find(localA);
+                // Do we have information on pointA?
+                Map<label>::iterator procPointA =
+                    meshToProcPoint_.find(localA);
 
-                    if (procPointA != meshToProcPoint_.end())
+                if (procPointA != meshToProcPoint_.end())
+                {
+                    // Store A info onto pointB
+                    if (storeInfo(procPoints_[procPointA()], localB, false))
                     {
-                        // Store A info onto pointB
-                        if
-                        (
-                            storeInfo
-                            (
-                                procPoints_[procPointA()],
-                                localB,
-                                isCollocatedPoint[e[1]]
-                            )
-                        )
-                        {
-                            changedPoints.insert(localB);
-                        }
+                        changedPoints.insert(localB);
                     }
+                }
 
-                    // Same for info on pointB
-                    Map<label>::iterator procPointB =
-                        meshToProcPoint_.find(localB);
+                // Same for info on pointB
+                Map<label>::iterator procPointB =
+                    meshToProcPoint_.find(localB);
 
-                    if (procPointB != meshToProcPoint_.end())
+                if (procPointB != meshToProcPoint_.end())
+                {
+                    // Store B info onto pointA
+                    if (storeInfo(procPoints_[procPointB()], localA, false))
                     {
-                        // Store B info onto pointA
-                        if
-                        (
-                            storeInfo
-                            (
-                                procPoints_[procPointB()],
-                                localA,
-                                isCollocatedPoint[e[0]]
-                            )
-                        )
-                        {
-                            changedPoints.insert(localA);
-                        }
+                        changedPoints.insert(localA);
                     }
                 }
             }
@@ -970,7 +882,14 @@ void Foam::globalPoints::sendSharedPoints
     {
         const polyPatch& pp = patches[patchI];
 
-        if (Pstream::parRun() && isA<processorPolyPatch>(pp))
+        if
+        (
+            Pstream::parRun()
+         && (
+                isType<processorPolyPatch>(pp)
+             || (mergeSeparated && isA<processorCyclicPolyPatch>(pp))
+            )
+        )
         {
             const processorPolyPatch& procPatch =
                 refCast<const processorPolyPatch>(pp);
@@ -1057,7 +976,14 @@ void Foam::globalPoints::receiveSharedPoints
     {
         const polyPatch& pp = patches[patchI];
 
-        if (Pstream::parRun() && isA<processorPolyPatch>(pp))
+        if
+        (
+            Pstream::parRun()
+         && (
+                isType<processorPolyPatch>(pp)
+             || (mergeSeparated && isA<processorCyclicPolyPatch>(pp))
+            )
+        )
         {
             const processorPolyPatch& procPatch =
                 refCast<const processorPolyPatch>(pp);
@@ -1128,19 +1054,11 @@ void Foam::globalPoints::receiveSharedPoints
                 }
             }
         }
-        else if (isA<cyclicPolyPatch>(pp))
+        else if (mergeSeparated && isA<cyclicPolyPatch>(pp))
         {
             const cyclicPolyPatch& cycPatch =
                 refCast<const cyclicPolyPatch>(pp);
 
-            PackedBoolList isCollocatedPoint
-            (
-                collocatedPoints
-                (
-                    cycPatch
-                )
-            );
-
             // Build map from mesh or patch point to sharedPoint.
             Map<label> localToSharedPoint(sharedPointAddr_.size());
             forAll(sharedPointLabels_, i)
@@ -1156,80 +1074,76 @@ void Foam::globalPoints::receiveSharedPoints
             }
 
             // Sync all info.
-            //const edgeList& connections = cycPatch.coupledPoints();
-            const edgeList connections(coupledPoints(cycPatch));
 
-            forAll(connections, i)
-            {
-                const edge& e = connections[i];
+            const labelList& meshPoints = cycPatch.meshPoints();
+            const labelList coupledMeshPoints(reverseMeshPoints(cycPatch));
 
-                if (mergeSeparated || isCollocatedPoint[e[0]])
-                {
-                    label meshPointA = pp.meshPoints()[e[0]];
-                    label meshPointB = pp.meshPoints()[e[1]];
+            forAll(meshPoints, i)
+            {
+                label meshPointA = meshPoints[i];
+                label meshPointB = coupledMeshPoints[i];
 
-                    label localA = meshToLocalPoint
-                    (
-                        meshToPatchPoint,
-                        meshPointA
-                    );
-                    label localB = meshToLocalPoint
-                    (
-                        meshToPatchPoint,
-                        meshPointB
-                    );
+                label localA = meshToLocalPoint
+                (
+                    meshToPatchPoint,
+                    meshPointA
+                );
+                label localB = meshToLocalPoint
+                (
+                    meshToPatchPoint,
+                    meshPointB
+                );
 
-                    // Do we already have shared point for pointA?
-                    Map<label>::iterator fndA = localToSharedPoint.find(localA);
-                    Map<label>::iterator fndB = localToSharedPoint.find(localB);
+                // Do we already have shared point for pointA?
+                Map<label>::iterator fndA = localToSharedPoint.find(localA);
+                Map<label>::iterator fndB = localToSharedPoint.find(localB);
 
-                    if (fndA != localToSharedPoint.end())
+                if (fndA != localToSharedPoint.end())
+                {
+                    if (fndB != localToSharedPoint.end())
                     {
-                        if (fndB != localToSharedPoint.end())
+                        if (fndA() != fndB())
                         {
-                            if (fndA() != fndB())
-                            {
-                                FatalErrorIn
-                                (
-                                    "globalPoints::receiveSharedPoints(..)"
-                                )   << "On patch " << pp.name()
-                                    << " connected points " << meshPointA
-                                    << ' ' << mesh_.points()[meshPointA]
-                                    << " and " << meshPointB
-                                    << ' ' << mesh_.points()[meshPointB]
-                                    << " are mapped to different shared"
-                                    << " points: "
-                                    << fndA() << " and " << fndB()
-                                    << abort(FatalError);
-                            }
+                            FatalErrorIn
+                            (
+                                "globalPoints::receiveSharedPoints(..)"
+                            )   << "On patch " << pp.name()
+                                << " connected points " << meshPointA
+                                << ' ' << mesh_.points()[meshPointA]
+                                << " and " << meshPointB
+                                << ' ' << mesh_.points()[meshPointB]
+                                << " are mapped to different shared"
+                                << " points: "
+                                << fndA() << " and " << fndB()
+                                << abort(FatalError);
                         }
-                        else
-                        {
-                            // No shared point yet for B.
-                            label sharedPointI = fndA();
+                    }
+                    else
+                    {
+                        // No shared point yet for B.
+                        label sharedPointI = fndA();
 
-                            // Store shared point for pointB
-                            label sharedI = meshToShared[localB];
+                        // Store shared point for pointB
+                        label sharedI = meshToShared[localB];
 
-                            sharedPointAddr_[sharedI] = sharedPointI;
-                            sharedPointLabels_[sharedI] = localB;
-                            changedIndices.append(sharedI);
-                        }
+                        sharedPointAddr_[sharedI] = sharedPointI;
+                        sharedPointLabels_[sharedI] = localB;
+                        changedIndices.append(sharedI);
                     }
-                    else
+                }
+                else
+                {
+                    // No shared point yet for A.
+                    if (fndB != localToSharedPoint.end())
                     {
-                        // No shared point yet for A.
-                        if (fndB != localToSharedPoint.end())
-                        {
-                            label sharedPointI = fndB();
+                        label sharedPointI = fndB();
 
-                            // Store shared point for pointA
-                            label sharedI = meshToShared[localA];
+                        // Store shared point for pointA
+                        label sharedI = meshToShared[localA];
 
-                            sharedPointAddr_[sharedI] = sharedPointI;
-                            sharedPointLabels_[sharedI] = localA;
-                            changedIndices.append(sharedI);
-                        }
+                        sharedPointAddr_[sharedI] = sharedPointI;
+                        sharedPointLabels_[sharedI] = localA;
+                        changedIndices.append(sharedI);
                     }
                 }
             }
@@ -1241,51 +1155,25 @@ void Foam::globalPoints::receiveSharedPoints
 }
 
 
-Foam::edgeList Foam::globalPoints::coupledPoints(const cyclicPolyPatch& pp)
+Foam::labelList Foam::globalPoints::reverseMeshPoints
+(
+    const cyclicPolyPatch& pp
+)
 {
-    // Look at cyclic patch as two halves, A and B.
-    // Now all we know is that relative face index in halfA is same
-    // as coupled face in halfB and also that the 0th vertex
-    // corresponds.
+    const cyclicPolyPatch& nbrPatch = pp.neighbPatch();
 
-    // From halfA point to halfB or -1.
-    labelList coupledPoint(pp.nPoints(), -1);
+    faceList masterFaces(nbrPatch.size());
 
-    for (label patchFaceA = 0; patchFaceA < pp.size()/2; patchFaceA++)
+    forAll (nbrPatch, faceI)
     {
-        const face& fA = pp.localFaces()[patchFaceA];
-
-        forAll(fA, indexA)
-        {
-            label patchPointA = fA[indexA];
-
-            if (coupledPoint[patchPointA] == -1)
-            {
-                const face& fB = pp.localFaces()[patchFaceA + pp.size()/2];
-
-                label indexB = (fB.size() - indexA) % fB.size();
-
-                coupledPoint[patchPointA] = fB[indexB];
-            }
-        }
-    }
-
-    edgeList connected(pp.nPoints());
-
-    // Extract coupled points.
-    label connectedI = 0;
-
-    forAll(coupledPoint, i)
-    {
-        if (coupledPoint[i] != -1)
-        {
-            connected[connectedI++] = edge(i, coupledPoint[i]);
-        }
+        masterFaces[faceI] = nbrPatch[faceI].reverseFace();
     }
 
-    connected.setSize(connectedI);
-
-    return connected;
+    return primitiveFacePatch
+    (
+        masterFaces,
+        nbrPatch.points()
+    ).meshPoints();
 }
 
 
diff --git a/src/OpenFOAM/meshes/polyMesh/globalMeshData/globalPoints.H b/src/OpenFOAM/meshes/polyMesh/globalMeshData/globalPoints.H
index fcf7144a90ee7512b0a9de0495798833badaaafd..32012334b77c3398b6706c4da3d73425f4db0b0d 100644
--- a/src/OpenFOAM/meshes/polyMesh/globalMeshData/globalPoints.H
+++ b/src/OpenFOAM/meshes/polyMesh/globalMeshData/globalPoints.H
@@ -158,10 +158,6 @@ class globalPoints
 
     // Private Member Functions
 
-        //- Return per point collocated status
-        static PackedBoolList collocatedPoints(const coupledPolyPatch&);
-
-
         // Wrappers around global point numbering to add collocated bit
 
             //- Convert into globalIndices and add collocated bit
@@ -300,9 +296,8 @@ class globalPoints
             DynamicList<label>&
         );
 
-        //- Should move into cyclicPolyPatch ordering problem
-        //  keeps on giving problems.
-        static edgeList coupledPoints(const cyclicPolyPatch&);
+        //- Return mesh points of other side in same order as my meshPoints.
+        static labelList reverseMeshPoints(const cyclicPolyPatch&);
 
         //- Do all calculations.
         void calculateSharedPoints
diff --git a/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistribute.C b/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistribute.C
index b0ecac822b56ebbab5e0e8601fcfe43104b6542e..fa9ad13f930806b602b22eff0bbfcfb47c000874 100644
--- a/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistribute.C
+++ b/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistribute.C
@@ -74,7 +74,7 @@ Foam::List<Foam::labelPair> Foam::mapDistribute::schedule
             slave++
         )
         {
-            IPstream fromSlave(Pstream::blocking, slave);
+            IPstream fromSlave(Pstream::scheduled, slave);
             List<labelPair> nbrData(fromSlave);
 
             forAll(nbrData, i)
@@ -95,18 +95,18 @@ Foam::List<Foam::labelPair> Foam::mapDistribute::schedule
             slave++
         )
         {
-            OPstream toSlave(Pstream::blocking, slave);
+            OPstream toSlave(Pstream::scheduled, slave);
             toSlave << allComms;
         }
     }
     else
     {
         {
-            OPstream toMaster(Pstream::blocking, Pstream::masterNo());
+            OPstream toMaster(Pstream::scheduled, Pstream::masterNo());
             toMaster << allComms;
         }
         {
-            IPstream fromMaster(Pstream::blocking, Pstream::masterNo());
+            IPstream fromMaster(Pstream::scheduled, Pstream::masterNo());
             fromMaster >> allComms;
         }
     }
@@ -595,6 +595,7 @@ void Foam::mapDistribute::compact(const boolList& elemIsUsed)
 
     // Send elemIsUsed field to neighbour. Use nonblocking code from
     // mapDistribute but in reverse order.
+    if (Pstream::parRun())
     {
         List<boolList> sendFields(Pstream::nProcs());
 
diff --git a/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistributeTemplates.C b/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistributeTemplates.C
index 8797519d4dfc239511dd3b5c5351d86e0071e543..8fb074488de78a922d4735e8f4e79ad8ffaa75ac 100644
--- a/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistributeTemplates.C
+++ b/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistributeTemplates.C
@@ -41,6 +41,30 @@ void Foam::mapDistribute::distribute
     List<T>& field
 )
 {
+    if (!Pstream::parRun())
+    {
+        // Do only me to me.
+
+        const labelList& mySubMap = subMap[Pstream::myProcNo()];
+
+        List<T> subField(mySubMap.size());
+        forAll(mySubMap, i)
+        {
+            subField[i] = field[mySubMap[i]];
+        }
+        
+        // Receive sub field from myself (subField)
+        const labelList& map = constructMap[Pstream::myProcNo()];
+
+        field.setSize(constructSize);
+
+        forAll(map, i)
+        {
+            field[map[i]] = subField[i];
+        }
+        return;
+    }
+
     if (commsType == Pstream::blocking)
     {
         // Since buffered sending can reuse the field to collect the
@@ -406,6 +430,30 @@ void Foam::mapDistribute::distribute
     const T& nullValue
 )
 {
+    if (!Pstream::parRun())
+    {
+        // Do only me to me.
+
+        const labelList& mySubMap = subMap[Pstream::myProcNo()];
+
+        List<T> subField(mySubMap.size());
+        forAll(mySubMap, i)
+        {
+            subField[i] = field[mySubMap[i]];
+        }
+        
+        // Receive sub field from myself (subField)
+        const labelList& map = constructMap[Pstream::myProcNo()];
+
+        field.setSize(constructSize);
+
+        forAll(map, i)
+        {
+            field[map[i]] = subField[i];
+        }
+        return;
+    }
+
     if (commsType == Pstream::blocking)
     {
         // Since buffered sending can reuse the field to collect the
diff --git a/src/OpenFOAM/meshes/polyMesh/polyMesh.C b/src/OpenFOAM/meshes/polyMesh/polyMesh.C
index 9bb7f27fa5ceda97a012d7189d58c39a02a10903..d0b3a7fa6642fcbc1f765ec90814e79c56ee659e 100644
--- a/src/OpenFOAM/meshes/polyMesh/polyMesh.C
+++ b/src/OpenFOAM/meshes/polyMesh/polyMesh.C
@@ -717,6 +717,7 @@ void Foam::polyMesh::resetPrimitives
                 "    const Xfer<labelList>& neighbour,\n"
                 "    const labelList& patchSizes,\n"
                 "    const labelList& patchStarts\n"
+                "    const bool validBoundary\n"
                 ")\n"
             )   << "Face " << faceI << " contains vertex labels out of range: "
                 << curFace << " Max point index = " << points_.size()
@@ -759,9 +760,9 @@ void Foam::polyMesh::resetPrimitives
                 "    const Xfer<labelList>& neighbour,\n"
                 "    const labelList& patchSizes,\n"
                 "    const labelList& patchStarts\n"
+                "    const bool validBoundary\n"
                 ")\n"
-            )
-                << "no points or no cells in mesh" << endl;
+            )   << "no points or no cells in mesh" << endl;
         }
     }
 }
diff --git a/src/OpenFOAM/meshes/polyMesh/polyMesh.H b/src/OpenFOAM/meshes/polyMesh/polyMesh.H
index ce82d36de7487d904b5bf46a87d9f4cfc4c9336c..d82006b2df3ef42f12f63f252010c674a44c7d4b 100644
--- a/src/OpenFOAM/meshes/polyMesh/polyMesh.H
+++ b/src/OpenFOAM/meshes/polyMesh/polyMesh.H
@@ -193,6 +193,19 @@ private:
                 const label patchID
             ) const;
 
+            void setTopology
+            (
+                const cellShapeList& cellsAsShapes,
+                const faceListList& boundaryFaces,
+                const wordList& boundaryPatchNames,
+                labelList& patchSizes,
+                labelList& patchStarts,
+                label& defaultPatchStart,
+                label& nFaces,
+                cellList& cells
+            );
+
+
 
 public:
 
@@ -255,6 +268,20 @@ public:
             const bool syncPar = true
         );
 
+        //- Construct from cell shapes with patch information in dictionary
+        //  format.
+        polyMesh
+        (
+            const IOobject& io,
+            const Xfer<pointField>& points,
+            const cellShapeList& shapes,
+            const faceListList& boundaryFaces,
+            const PtrList<dictionary>& boundaryDicts,
+            const word& defaultBoundaryPatchName,
+            const word& defaultBoundaryPatchType,
+            const bool syncPar = true
+        );
+
 
     //- Destructor
     virtual ~polyMesh();
@@ -442,8 +469,6 @@ public:
             //- Reset mesh primitive data. Assumes all patch info correct
             //  (so does e.g. parallel communication). If not use
             //  validBoundary=false
-            //  (still assumes patchStarts[0] = nInternalFaces and last
-            //  patch ends at nActiveFaces) and change patches with addPatches.
             void resetPrimitives
             (
                 const Xfer<pointField>& points,
diff --git a/src/OpenFOAM/meshes/polyMesh/polyMeshFromShapeMesh.C b/src/OpenFOAM/meshes/polyMesh/polyMeshFromShapeMesh.C
index fe9b8e45a4b92e789c70ffd37aef24e0eee9f18c..3898cd43f094e243c74db795c6536c172f5f5461 100644
--- a/src/OpenFOAM/meshes/polyMesh/polyMeshFromShapeMesh.C
+++ b/src/OpenFOAM/meshes/polyMesh/polyMeshFromShapeMesh.C
@@ -132,154 +132,26 @@ Foam::labelList Foam::polyMesh::facePatchFaceCells
 }
 
 
-Foam::polyMesh::polyMesh
+//- Set faces_, calculate cells and patchStarts.
+void Foam::polyMesh::setTopology
 (
-    const IOobject& io,
-    const Xfer<pointField>& points,
     const cellShapeList& cellsAsShapes,
     const faceListList& boundaryFaces,
     const wordList& boundaryPatchNames,
-    const wordList& boundaryPatchTypes,
-    const word& defaultBoundaryPatchName,
-    const word& defaultBoundaryPatchType,
-    const wordList& boundaryPatchPhysicalTypes,
-    const bool syncPar
+    labelList& patchSizes,
+    labelList& patchStarts,
+    label& defaultPatchStart,
+    label& nFaces,
+    cellList& cells
 )
-:
-    objectRegistry(io),
-    primitiveMesh(),
-    points_
-    (
-        IOobject
-        (
-            "points",
-            instance(),
-            meshSubDir,
-            *this,
-            IOobject::NO_READ,
-            IOobject::AUTO_WRITE
-        ),
-        points
-    ),
-    faces_
-    (
-        IOobject
-        (
-            "faces",
-            instance(),
-            meshSubDir,
-            *this,
-            IOobject::NO_READ,
-            IOobject::AUTO_WRITE
-        ),
-        0
-    ),
-    owner_
-    (
-        IOobject
-        (
-            "owner",
-            instance(),
-            meshSubDir,
-            *this,
-            IOobject::NO_READ,
-            IOobject::AUTO_WRITE
-        ),
-        0
-    ),
-    neighbour_
-    (
-        IOobject
-        (
-            "neighbour",
-            instance(),
-            meshSubDir,
-            *this,
-            IOobject::NO_READ,
-            IOobject::AUTO_WRITE
-        ),
-        0
-    ),
-    clearedPrimitives_(false),
-    boundary_
-    (
-        IOobject
-        (
-            "boundary",
-            instance(),
-            meshSubDir,
-            *this,
-            IOobject::NO_READ,
-            IOobject::AUTO_WRITE
-        ),
-        *this,
-        boundaryFaces.size() + 1    // add room for a default patch
-    ),
-    bounds_(points_, syncPar),
-    geometricD_(Vector<label>::zero),
-    solutionD_(Vector<label>::zero),
-    pointZones_
-    (
-        IOobject
-        (
-            "pointZones",
-            instance(),
-            meshSubDir,
-            *this,
-            IOobject::NO_READ,
-            IOobject::NO_WRITE
-        ),
-        *this,
-        0
-    ),
-    faceZones_
-    (
-        IOobject
-        (
-            "faceZones",
-            instance(),
-            meshSubDir,
-            *this,
-            IOobject::NO_READ,
-            IOobject::NO_WRITE
-        ),
-        *this,
-        0
-    ),
-    cellZones_
-    (
-        IOobject
-        (
-            "cellZones",
-            instance(),
-            meshSubDir,
-            *this,
-            IOobject::NO_READ,
-            IOobject::NO_WRITE
-        ),
-        *this,
-        0
-    ),
-    globalMeshDataPtr_(NULL),
-    moving_(false),
-    curMotionTimeIndex_(time().timeIndex()),
-    oldPointsPtr_(NULL)
 {
-    if (debug)
-    {
-        Info<<"Constructing polyMesh from cell and boundary shapes." << endl;
-    }
-
-    // Remove all of the old mesh files if they exist
-    removeFiles(instance());
-
     // Calculate the faces of all cells
     // Initialise maximum possible numer of mesh faces to 0
     label maxFaces = 0;
 
     // Set up a list of face shapes for each cell
     faceListList cellsFaceShapes(cellsAsShapes.size());
-    cellList cells(cellsAsShapes.size());
+    cells.setSize(cellsAsShapes.size());
 
     forAll(cellsFaceShapes, cellI)
     {
@@ -298,7 +170,7 @@ Foam::polyMesh::polyMesh
     faces_.setSize(maxFaces);
 
     // Initialise number of faces to 0
-    label nFaces = 0;
+    nFaces = 0;
 
     // set reference to point-cell addressing
     labelListList PointCells = cellShapePointCells(cellsAsShapes);
@@ -412,15 +284,16 @@ Foam::polyMesh::polyMesh
             {
                 FatalErrorIn
                 (
-                    "polyMesh::polyMesh\n"
+                    "polyMesh::setTopology\n"
                     "(\n"
-                    "    const IOobject&,\n"
-                    "    const Xfer<pointField>&,\n"
                     "    const cellShapeList& cellsAsShapes,\n"
                     "    const faceListList& boundaryFaces,\n"
-                    "    const wordList& boundaryPatchTypes,\n"
                     "    const wordList& boundaryPatchNames,\n"
-                    "    const word& defaultBoundaryPatchType\n"
+                    "    labelList& patchSizes,\n"
+                    "    labelList& patchStarts,\n"
+                    "    label& defaultPatchStart,\n"
+                    "    label& nFaces,\n"
+                    "    cellList& cells\n"
                     ")"
                 )   << "Error in internal face insertion"
                     << abort(FatalError);
@@ -430,8 +303,8 @@ Foam::polyMesh::polyMesh
 
     // Do boundary faces
 
-    labelList patchSizes(boundaryFaces.size(), -1);
-    labelList patchStarts(boundaryFaces.size(), -1);
+    patchSizes.setSize(boundaryFaces.size(), -1);
+    patchStarts.setSize(boundaryFaces.size(), -1);
 
     forAll(boundaryFaces, patchI)
     {
@@ -470,15 +343,16 @@ Foam::polyMesh::polyMesh
                     {
                         FatalErrorIn
                         (
-                            "polyMesh::polyMesh\n"
+                            "polyMesh::setTopology\n"
                             "(\n"
-                            "    const IOobject&,\n"
-                            "    const Xfer<pointField>&,\n"
                             "    const cellShapeList& cellsAsShapes,\n"
                             "    const faceListList& boundaryFaces,\n"
-                            "    const wordList& boundaryPatchTypes,\n"
                             "    const wordList& boundaryPatchNames,\n"
-                            "    const word& defaultBoundaryPatchType\n"
+                            "    labelList& patchSizes,\n"
+                            "    labelList& patchStarts,\n"
+                            "    label& defaultPatchStart,\n"
+                            "    label& nFaces,\n"
+                            "    cellList& cells\n"
                             ")"
                         )   << "Trying to specify a boundary face " << curFace
                             << " on the face on cell " << cellInside
@@ -518,7 +392,7 @@ Foam::polyMesh::polyMesh
 
     // Grab "non-existing" faces and put them into a default patch
 
-    label defaultPatchStart = nFaces;
+    defaultPatchStart = nFaces;
 
     forAll(cells, cellI)
     {
@@ -539,116 +413,550 @@ Foam::polyMesh::polyMesh
     // Reset the size of the face list
     faces_.setSize(nFaces);
 
-    // Warning: Patches can only be added once the face list is
-    // completed, as they hold a subList of the face list
-    forAll(boundaryFaces, patchI)
-    {
-        // add the patch to the list
-        boundary_.set
-        (
-            patchI,
-            polyPatch::New
-            (
-                boundaryPatchTypes[patchI],
-                boundaryPatchNames[patchI],
-                patchSizes[patchI],
-                patchStarts[patchI],
-                patchI,
-                boundary_
-            )
-        );
-
-        if
-        (
-            boundaryPatchPhysicalTypes.size()
-         && boundaryPatchPhysicalTypes[patchI].size()
-        )
-        {
-            boundary_[patchI].physicalType() =
-                boundaryPatchPhysicalTypes[patchI];
-        }
-    }
-
-    label nAllPatches = boundaryFaces.size();
-
-    if (nFaces > defaultPatchStart)
-    {
-        WarningIn("polyMesh::polyMesh(... construct from shapes...)")
-            << "Found " << nFaces - defaultPatchStart
-            << " undefined faces in mesh; adding to default patch." << endl;
-
-        // Check if there already exists a defaultFaces patch as last patch
-        // and reuse it.
-        label patchI = findIndex(boundaryPatchNames, defaultBoundaryPatchName);
-
-        if (patchI != -1)
-        {
-            if (patchI != boundaryFaces.size()-1 || boundary_[patchI].size())
-            {
-                FatalErrorIn("polyMesh::polyMesh(... construct from shapes...)")
-                    << "Default patch " << boundary_[patchI].name()
-                    << " already has faces in it or is not"
-                    << " last in list of patches." << exit(FatalError);
-            }
-
-            WarningIn("polyMesh::polyMesh(... construct from shapes...)")
-                << "Reusing existing patch " << patchI
-                << " for undefined faces." << endl;
-
-            boundary_.set
-            (
-                patchI,
-                polyPatch::New
-                (
-                    boundaryPatchTypes[patchI],
-                    boundaryPatchNames[patchI],
-                    nFaces - defaultPatchStart,
-                    defaultPatchStart,
-                    patchI,
-                    boundary_
-                )
-            );
-        }
-        else
-        {
-            boundary_.set
-            (
-                nAllPatches,
-                polyPatch::New
-                (
-                    defaultBoundaryPatchType,
-                    defaultBoundaryPatchName,
-                    nFaces - defaultPatchStart,
-                    defaultPatchStart,
-                    boundary_.size() - 1,
-                    boundary_
-                )
-            );
-
-            nAllPatches++;
-        }
-    }
-
-    // Reset the size of the boundary
-    boundary_.setSize(nAllPatches);
-
-    // Set the primitive mesh
-    initMesh(cells);
-
-    if (syncPar)
-    {
-        // Calculate topology for the patches (processor-processor comms etc.)
-        boundary_.updateMesh();
+    return ;
+}
 
-        // Calculate the geometry for the patches (transformation tensors etc.)
-        boundary_.calcGeometry();
-    }
 
-    if (debug)
-    {
-        if (checkMesh())
-        {
-            Info<< "Mesh OK" << endl;
+Foam::polyMesh::polyMesh
+(
+    const IOobject& io,
+    const Xfer<pointField>& points,
+    const cellShapeList& cellsAsShapes,
+    const faceListList& boundaryFaces,
+    const wordList& boundaryPatchNames,
+    const wordList& boundaryPatchTypes,
+    const word& defaultBoundaryPatchName,
+    const word& defaultBoundaryPatchType,
+    const wordList& boundaryPatchPhysicalTypes,
+    const bool syncPar
+)
+:
+    objectRegistry(io),
+    primitiveMesh(),
+    points_
+    (
+        IOobject
+        (
+            "points",
+            instance(),
+            meshSubDir,
+            *this,
+            IOobject::NO_READ,
+            IOobject::AUTO_WRITE
+        ),
+        points
+    ),
+    faces_
+    (
+        IOobject
+        (
+            "faces",
+            instance(),
+            meshSubDir,
+            *this,
+            IOobject::NO_READ,
+            IOobject::AUTO_WRITE
+        ),
+        0
+    ),
+    owner_
+    (
+        IOobject
+        (
+            "owner",
+            instance(),
+            meshSubDir,
+            *this,
+            IOobject::NO_READ,
+            IOobject::AUTO_WRITE
+        ),
+        0
+    ),
+    neighbour_
+    (
+        IOobject
+        (
+            "neighbour",
+            instance(),
+            meshSubDir,
+            *this,
+            IOobject::NO_READ,
+            IOobject::AUTO_WRITE
+        ),
+        0
+    ),
+    clearedPrimitives_(false),
+    boundary_
+    (
+        IOobject
+        (
+            "boundary",
+            instance(),
+            meshSubDir,
+            *this,
+            IOobject::NO_READ,
+            IOobject::AUTO_WRITE
+        ),
+        *this,
+        boundaryFaces.size() + 1    // add room for a default patch
+    ),
+    bounds_(points_, syncPar),
+    geometricD_(Vector<label>::zero),
+    solutionD_(Vector<label>::zero),
+    pointZones_
+    (
+        IOobject
+        (
+            "pointZones",
+            instance(),
+            meshSubDir,
+            *this,
+            IOobject::NO_READ,
+            IOobject::NO_WRITE
+        ),
+        *this,
+        0
+    ),
+    faceZones_
+    (
+        IOobject
+        (
+            "faceZones",
+            instance(),
+            meshSubDir,
+            *this,
+            IOobject::NO_READ,
+            IOobject::NO_WRITE
+        ),
+        *this,
+        0
+    ),
+    cellZones_
+    (
+        IOobject
+        (
+            "cellZones",
+            instance(),
+            meshSubDir,
+            *this,
+            IOobject::NO_READ,
+            IOobject::NO_WRITE
+        ),
+        *this,
+        0
+    ),
+    globalMeshDataPtr_(NULL),
+    moving_(false),
+    curMotionTimeIndex_(time().timeIndex()),
+    oldPointsPtr_(NULL)
+{
+    if (debug)
+    {
+        Info<<"Constructing polyMesh from cell and boundary shapes." << endl;
+    }
+
+    // Remove all of the old mesh files if they exist
+    removeFiles(instance());
+
+    // Calculate faces and cells
+    labelList patchSizes;
+    labelList patchStarts;
+    label defaultPatchStart;
+    label nFaces;
+    cellList cells;
+    setTopology
+    (
+        cellsAsShapes,
+        boundaryFaces,
+        boundaryPatchNames,
+        patchSizes,
+        patchStarts,
+        defaultPatchStart,
+        nFaces,
+        cells
+    );
+
+    // Warning: Patches can only be added once the face list is
+    // completed, as they hold a subList of the face list
+    forAll(boundaryFaces, patchI)
+    {
+        // add the patch to the list
+        boundary_.set
+        (
+            patchI,
+            polyPatch::New
+            (
+                boundaryPatchTypes[patchI],
+                boundaryPatchNames[patchI],
+                patchSizes[patchI],
+                patchStarts[patchI],
+                patchI,
+                boundary_
+            )
+        );
+
+        if
+        (
+            boundaryPatchPhysicalTypes.size()
+         && boundaryPatchPhysicalTypes[patchI].size()
+        )
+        {
+            boundary_[patchI].physicalType() =
+                boundaryPatchPhysicalTypes[patchI];
+        }
+    }
+
+    label nAllPatches = boundaryFaces.size();
+
+    if (nFaces > defaultPatchStart)
+    {
+        WarningIn("polyMesh::polyMesh(... construct from shapes...)")
+            << "Found " << nFaces - defaultPatchStart
+            << " undefined faces in mesh; adding to default patch." << endl;
+
+        // Check if there already exists a defaultFaces patch as last patch
+        // and reuse it.
+        label patchI = findIndex(boundaryPatchNames, defaultBoundaryPatchName);
+
+        if (patchI != -1)
+        {
+            if (patchI != boundaryFaces.size()-1 || boundary_[patchI].size())
+            {
+                FatalErrorIn("polyMesh::polyMesh(... construct from shapes...)")
+                    << "Default patch " << boundary_[patchI].name()
+                    << " already has faces in it or is not"
+                    << " last in list of patches." << exit(FatalError);
+            }
+
+            WarningIn("polyMesh::polyMesh(... construct from shapes...)")
+                << "Reusing existing patch " << patchI
+                << " for undefined faces." << endl;
+
+            boundary_.set
+            (
+                patchI,
+                polyPatch::New
+                (
+                    boundaryPatchTypes[patchI],
+                    boundaryPatchNames[patchI],
+                    nFaces - defaultPatchStart,
+                    defaultPatchStart,
+                    patchI,
+                    boundary_
+                )
+            );
+        }
+        else
+        {
+            boundary_.set
+            (
+                nAllPatches,
+                polyPatch::New
+                (
+                    defaultBoundaryPatchType,
+                    defaultBoundaryPatchName,
+                    nFaces - defaultPatchStart,
+                    defaultPatchStart,
+                    boundary_.size() - 1,
+                    boundary_
+                )
+            );
+
+            nAllPatches++;
+        }
+    }
+
+    // Reset the size of the boundary
+    boundary_.setSize(nAllPatches);
+
+    // Set the primitive mesh
+    initMesh(cells);
+
+    if (syncPar)
+    {
+        // Calculate topology for the patches (processor-processor comms etc.)
+        boundary_.updateMesh();
+
+        // Calculate the geometry for the patches (transformation tensors etc.)
+        boundary_.calcGeometry();
+    }
+
+    if (debug)
+    {
+        if (checkMesh())
+        {
+            Info<< "Mesh OK" << endl;
+        }
+    }
+}
+
+
+Foam::polyMesh::polyMesh
+(
+    const IOobject& io,
+    const Xfer<pointField>& points,
+    const cellShapeList& cellsAsShapes,
+    const faceListList& boundaryFaces,
+    const PtrList<dictionary>& boundaryDicts,
+    const word& defaultBoundaryPatchName,
+    const word& defaultBoundaryPatchType,
+    const bool syncPar
+)
+:
+    objectRegistry(io),
+    primitiveMesh(),
+    points_
+    (
+        IOobject
+        (
+            "points",
+            instance(),
+            meshSubDir,
+            *this,
+            IOobject::NO_READ,
+            IOobject::AUTO_WRITE
+        ),
+        points
+    ),
+    faces_
+    (
+        IOobject
+        (
+            "faces",
+            instance(),
+            meshSubDir,
+            *this,
+            IOobject::NO_READ,
+            IOobject::AUTO_WRITE
+        ),
+        0
+    ),
+    owner_
+    (
+        IOobject
+        (
+            "owner",
+            instance(),
+            meshSubDir,
+            *this,
+            IOobject::NO_READ,
+            IOobject::AUTO_WRITE
+        ),
+        0
+    ),
+    neighbour_
+    (
+        IOobject
+        (
+            "neighbour",
+            instance(),
+            meshSubDir,
+            *this,
+            IOobject::NO_READ,
+            IOobject::AUTO_WRITE
+        ),
+        0
+    ),
+    clearedPrimitives_(false),
+    boundary_
+    (
+        IOobject
+        (
+            "boundary",
+            instance(),
+            meshSubDir,
+            *this,
+            IOobject::NO_READ,
+            IOobject::AUTO_WRITE
+        ),
+        *this,
+        boundaryFaces.size() + 1    // add room for a default patch
+    ),
+    bounds_(points_, syncPar),
+    geometricD_(Vector<label>::zero),
+    solutionD_(Vector<label>::zero),
+    pointZones_
+    (
+        IOobject
+        (
+            "pointZones",
+            instance(),
+            meshSubDir,
+            *this,
+            IOobject::NO_READ,
+            IOobject::NO_WRITE
+        ),
+        *this,
+        0
+    ),
+    faceZones_
+    (
+        IOobject
+        (
+            "faceZones",
+            instance(),
+            meshSubDir,
+            *this,
+            IOobject::NO_READ,
+            IOobject::NO_WRITE
+        ),
+        *this,
+        0
+    ),
+    cellZones_
+    (
+        IOobject
+        (
+            "cellZones",
+            instance(),
+            meshSubDir,
+            *this,
+            IOobject::NO_READ,
+            IOobject::NO_WRITE
+        ),
+        *this,
+        0
+    ),
+    globalMeshDataPtr_(NULL),
+    moving_(false),
+    curMotionTimeIndex_(time().timeIndex()),
+    oldPointsPtr_(NULL)
+{
+    if (debug)
+    {
+        Info<<"Constructing polyMesh from cell and boundary shapes." << endl;
+    }
+
+    // Remove all of the old mesh files if they exist
+    removeFiles(instance());
+
+    wordList boundaryPatchNames(boundaryDicts.size());
+    forAll(boundaryDicts, patchI)
+    {
+        boundaryDicts[patchI].lookup("name") >> boundaryPatchNames[patchI];
+    }
+
+    // Calculate faces and cells
+    labelList patchSizes;
+    labelList patchStarts;
+    label defaultPatchStart;
+    label nFaces;
+    cellList cells;
+    setTopology
+    (
+        cellsAsShapes,
+        boundaryFaces,
+        boundaryPatchNames,
+        patchSizes,
+        patchStarts,
+        defaultPatchStart,
+        nFaces,
+        cells
+    );
+
+    // Warning: Patches can only be added once the face list is
+    // completed, as they hold a subList of the face list
+    forAll (boundaryFaces, patchI)
+    {
+        dictionary patchDict(boundaryDicts[patchI]);
+
+        patchDict.set("nFaces", patchSizes[patchI]);
+        patchDict.set("startFace", patchStarts[patchI]);
+
+        // add the patch to the list
+        boundary_.set
+        (
+            patchI,
+            polyPatch::New
+            (
+                boundaryPatchNames[patchI],
+                patchDict,
+                patchI,
+                boundary_
+            )
+        );
+    }
+
+    label nAllPatches = boundaryFaces.size();
+
+    if (nFaces > defaultPatchStart)
+    {
+        WarningIn("polyMesh::polyMesh(... construct from shapes...)")
+            << "Found " << nFaces - defaultPatchStart
+            << " undefined faces in mesh; adding to default patch." << endl;
+
+        // Check if there already exists a defaultFaces patch as last patch
+        // and reuse it.
+        label patchI = findIndex(boundaryPatchNames, defaultBoundaryPatchName);
+
+        if (patchI != -1)
+        {
+            if (patchI != boundaryFaces.size()-1 || boundary_[patchI].size())
+            {
+                FatalErrorIn("polyMesh::polyMesh(... construct from shapes...)")
+                    << "Default patch " << boundary_[patchI].name()
+                    << " already has faces in it or is not"
+                    << " last in list of patches." << exit(FatalError);
+            }
+
+            WarningIn("polyMesh::polyMesh(... construct from shapes...)")
+                << "Reusing existing patch " << patchI
+                << " for undefined faces." << endl;
+
+            boundary_.set
+            (
+                patchI,
+                polyPatch::New
+                (
+                    boundary_[patchI].type(),
+                    boundary_[patchI].name(),
+                    nFaces - defaultPatchStart,
+                    defaultPatchStart,
+                    patchI,
+                    boundary_
+                )
+            );
+        }
+        else
+        {
+            boundary_.set
+            (
+                nAllPatches,
+                polyPatch::New
+                (
+                    defaultBoundaryPatchType,
+                    defaultBoundaryPatchName,
+                    nFaces - defaultPatchStart,
+                    defaultPatchStart,
+                    boundary_.size() - 1,
+                    boundary_
+                )
+            );
+
+            nAllPatches++;
+        }
+    }
+
+    // Reset the size of the boundary
+    boundary_.setSize(nAllPatches);
+
+    // Set the primitive mesh
+    initMesh(cells);
+
+    if (syncPar)
+    {
+        // Calculate topology for the patches (processor-processor comms etc.)
+        boundary_.updateMesh();
+
+        // Calculate the geometry for the patches (transformation tensors etc.)
+        boundary_.calcGeometry();
+    }
+
+    if (debug)
+    {
+        if (checkMesh())
+        {
+            Info << "Mesh OK" << endl;
         }
     }
 }
diff --git a/src/OpenFOAM/meshes/polyMesh/polyPatches/basic/coupled/coupledPolyPatch.C b/src/OpenFOAM/meshes/polyMesh/polyPatches/basic/coupled/coupledPolyPatch.C
index a18ec94f5cac5398c4dfe43d392eb753f97543ec..ea44ec07d1a20ac73c62647318ec67799ce2ee8e 100644
--- a/src/OpenFOAM/meshes/polyMesh/polyPatches/basic/coupled/coupledPolyPatch.C
+++ b/src/OpenFOAM/meshes/polyMesh/polyPatches/basic/coupled/coupledPolyPatch.C
@@ -111,23 +111,6 @@ void Foam::coupledPolyPatch::writeOBJ
 }
 
 
-Foam::pointField Foam::coupledPolyPatch::calcFaceCentres
-(
-    const UList<face>& faces,
-    const pointField& points
-)
-{
-    pointField ctrs(faces.size());
-
-    forAll(faces, faceI)
-    {
-        ctrs[faceI] = faces[faceI].centre(points);
-    }
-
-    return ctrs;
-}
-
-
 Foam::pointField Foam::coupledPolyPatch::getAnchorPoints
 (
     const UList<face>& faces,
@@ -145,43 +128,6 @@ Foam::pointField Foam::coupledPolyPatch::getAnchorPoints
 }
 
 
-bool Foam::coupledPolyPatch::inPatch
-(
-    const labelList& oldToNew,
-    const label oldFaceI
-) const
-{
-    label faceI = oldToNew[oldFaceI];
-
-    return faceI >= start() && faceI < start()+size();
-}
-
-
-Foam::label Foam::coupledPolyPatch::whichPatch
-(
-    const labelList& patchStarts,
-    const label faceI
-)
-{
-    forAll(patchStarts, patchI)
-    {
-        if (patchStarts[patchI] <= faceI)
-        {
-            if (patchI == patchStarts.size()-1)
-            {
-                return patchI;
-            }
-            else if (patchStarts[patchI+1] > faceI)
-            {
-                return patchI;
-            }
-        }
-    }
-
-    return -1;
-}
-
-
 Foam::scalarField Foam::coupledPolyPatch::calcFaceTol
 (
     const UList<face>& faces,
@@ -266,7 +212,8 @@ void Foam::coupledPolyPatch::calcTransformTensors
         Pout<< "coupledPolyPatch::calcTransformTensors : " << name() << endl
             << "    (half)size:" << Cf.size() << nl
             << "    absTol:" << absTol << nl
-            //<< "    smallDist:" << smallDist << nl
+            << "    smallDist min:" << min(smallDist) << nl
+            << "    smallDist max:" << max(smallDist) << nl
             << "    sum(mag(nf & nr)):" << sum(mag(nf & nr)) << endl;
     }
 
@@ -278,7 +225,7 @@ void Foam::coupledPolyPatch::calcTransformTensors
     // Then the overall error of summing the normals is sqrt(size())*absTol
     // - separation calculation: pass in from the outside an allowable error.
 
-    if (size() == 0)
+    if (Cf.size() == 0)
     {
         // Dummy geometry.
         separation_.setSize(0);
diff --git a/src/OpenFOAM/meshes/polyMesh/polyPatches/basic/coupled/coupledPolyPatch.H b/src/OpenFOAM/meshes/polyMesh/polyPatches/basic/coupled/coupledPolyPatch.H
index 423a94ccb7dbc6276120039c036ece0e938a7f4c..92fcdc821cf64655141edb6e2c15454bcfb8e1b1 100644
--- a/src/OpenFOAM/meshes/polyMesh/polyPatches/basic/coupled/coupledPolyPatch.H
+++ b/src/OpenFOAM/meshes/polyMesh/polyPatches/basic/coupled/coupledPolyPatch.H
@@ -38,6 +38,7 @@ SourceFiles
 #define coupledPolyPatch_H
 
 #include "polyPatch.H"
+#include "diagTensorField.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -133,13 +134,6 @@ protected:
             label& vertI
         );
 
-        //- Calculate face centres
-        static pointField calcFaceCentres
-        (
-            const UList<face>&,
-            const pointField&
-        );
-
         //- Get f[0] for all faces
         static pointField getAnchorPoints
         (
@@ -147,21 +141,6 @@ protected:
             const pointField&
         );
 
-        //- Is face (in old face labels) in current patch?
-        bool inPatch
-        (
-            const labelList& oldToNew,
-            const label oldFaceI
-        ) const;
-
-        //- Given list of starts of patches and a face label determine
-        //  the patch.
-        static label whichPatch
-        (
-            const labelList& patchStarts,
-            const label faceI
-        );
-
         //- Calculate typical tolerance per face. Is currently max distance
         //  from face centre to any of the face vertices.
         static scalarField calcFaceTol
@@ -248,45 +227,67 @@ public:
                 return true;
             }
 
+            //- Does this side own the patch ?
+            virtual bool owner() const = 0;
 
-            //- Are the coupled planes separated
-            bool separated() const
+            //- Does the coupled side own the patch ?
+            virtual bool neighbour() const
+            {
+                return !owner();
+            }
+
+            //- Transform a patch-based position from other side to this side
+            virtual void transformPosition(pointField& l) const = 0;
+
+            //- Are the planes separated.
+            virtual bool separated() const
             {
                 return separation_.size();
             }
 
-            //- Return the offset (distance) vector from one side of the couple
-            //  to the other
-            const vectorField& separation() const
+            //- If the planes are separated the separation vector.
+            virtual const vectorField& separation() const
             {
                 return separation_;
             }
 
-            //- Are the cyclic planes parallel
-            bool parallel() const
+            //- Are the cyclic planes parallel.
+            virtual bool parallel() const
             {
                 return forwardT_.empty();
             }
 
-            //- Return face transformation tensor
-            const tensorField& forwardT() const
+            //- Return face transformation tensor.
+            virtual const tensorField& forwardT() const
             {
                 return forwardT_;
             }
 
-            //- Return neighbour-cell transformation tensor
-            const tensorField& reverseT() const
+            //- Return neighbour-cell transformation tensor.
+            virtual const tensorField& reverseT() const
             {
                 return reverseT_;
             }
 
             //- Are faces collocated. Either size 0,1 or length of patch
-            const boolList& collocated() const
+            virtual const boolList& collocated() const
             {
                 return collocated_;
             }
 
 
+        //- Calculate the patch geometry
+        virtual void calcGeometry
+        (
+            const primitivePatch& referPatch,
+            const UList<point>& thisCtrs,
+            const UList<point>& thisAreas,
+            const UList<point>& thisCc,
+            const UList<point>& nbrCtrs,
+            const UList<point>& nbrAreas,
+            const UList<point>& nbrCc
+        ) = 0;
+
         //- Initialize ordering for primitivePatch. Does not
         //  refer to *this (except for name() and type() etc.)
         virtual void initOrder
diff --git a/src/OpenFOAM/meshes/polyMesh/polyPatches/constraint/cyclic/cyclicPolyPatch.C b/src/OpenFOAM/meshes/polyMesh/polyPatches/constraint/cyclic/cyclicPolyPatch.C
index 1341d8083da274298d94d58457f0b31aaef489de..4348d321cfc7cccff5df8c7fc9128260a3037c47 100644
--- a/src/OpenFOAM/meshes/polyMesh/polyPatches/constraint/cyclic/cyclicPolyPatch.C
+++ b/src/OpenFOAM/meshes/polyMesh/polyPatches/constraint/cyclic/cyclicPolyPatch.C
@@ -33,7 +33,8 @@ License
 #include "matchPoints.H"
 #include "EdgeMap.H"
 #include "Time.H"
-#include "transformList.H"
+#include "diagTensor.H"
+#include "transformField.H"
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
@@ -88,38 +89,12 @@ void Foam::cyclicPolyPatch::calcTransforms()
 {
     if (size())
     {
-        const pointField& points = this->points();
+        // Half0
 
-        // Determine geometric quantities on the two halves
-        // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+        const cyclicPolyPatch& half0 = *this;
 
-        primitivePatch half0
-        (
-            SubList<face>
-            (
-                *this,
-                size()/2
-            ),
-            points
-        );
-
-        pointField half0Ctrs(calcFaceCentres(half0, half0.points()));
+        const pointField& half0Ctrs = half0.faceCentres();
 
-        scalarField half0Tols(calcFaceTol(half0, half0.points(), half0Ctrs));
-
-        primitivePatch half1
-        (
-            SubList<face>
-            (
-                *this,
-                size()/2,
-                size()/2
-            ),
-            points
-        );
-        pointField half1Ctrs(calcFaceCentres(half1, half1.points()));
-
-        // Dump halves
         if (debug)
         {
             fileName casePath(boundaryMesh().mesh().time().path());
@@ -128,6 +103,27 @@ void Foam::cyclicPolyPatch::calcTransforms()
             Pout<< "cyclicPolyPatch::calcTransforms : Writing half0"
                 << " faces to OBJ file " << nm0 << endl;
             writeOBJ(nm0, half0, half0.points());
+        }
+
+        vectorField half0Areas(half0.size());
+
+        forAll(half0, facei)
+        {
+            half0Areas[facei] = half0[facei].normal(half0.points());
+        }
+
+
+
+        // Half0
+
+        const cyclicPolyPatch& half1 = neighbPatch();
+
+        const pointField& half1Ctrs = half1.faceCentres();
+
+        // Dump halves
+        if (debug)
+        {
+            fileName casePath(boundaryMesh().mesh().time().path());
 
             fileName nm1(casePath/name()+"_half1_faces.obj");
             Pout<< "cyclicPolyPatch::calcTransforms : Writing half1"
@@ -151,17 +147,65 @@ void Foam::cyclicPolyPatch::calcTransforms()
             }
         }
 
-        vectorField half0Normals(half0.size());
-        vectorField half1Normals(half1.size());
+        vectorField half1Areas(half1.size());
 
-        for (label facei = 0; facei < size()/2; facei++)
+        forAll(half1, facei)
         {
-            half0Normals[facei] = operator[](facei).normal(points);
-            label nbrFacei = facei+size()/2;
-            half1Normals[facei] = operator[](nbrFacei).normal(points);
+            half1Areas[facei] = half1[facei].normal(half1.points());
+        }
 
-            scalar magSf = mag(half0Normals[facei]);
-            scalar nbrMagSf = mag(half1Normals[facei]);
+        calcTransforms
+        (
+            half0,
+            half0Ctrs,
+            half0Areas,
+            half1Ctrs,
+            half1Areas
+        );
+    }
+}
+
+
+void Foam::cyclicPolyPatch::calcTransforms
+(
+    const primitivePatch& half0,
+    const UList<point>& half0Ctrs,
+    const UList<point>& half0Areas,
+    const UList<point>& half1Ctrs,
+    const UList<point>& half1Areas
+)
+{
+    if (half0Ctrs.size() != half1Ctrs.size())
+    {
+        FatalErrorIn
+        (
+            "cyclicPolyPatch::calcTransforms()"
+        )   << "For patch " << name()
+            << " there are " << half0Ctrs.size()
+            << " face centres, for the neighbour patch " << neighbPatch().name()
+            << " there are " << half1Ctrs.size()
+            << exit(FatalError);
+    }
+
+    if (half0Ctrs.size() > 0)
+    {
+        scalarField half0Tols
+        (
+            calcFaceTol
+            (
+                half0,
+                half0.points(),
+                static_cast<const pointField&>(half0Ctrs)
+            )
+        );
+
+        vectorField half0Normals(half0Areas.size());
+        vectorField half1Normals(half1Areas.size());
+
+        forAll(half0, facei)
+        {
+            scalar magSf = mag(half0Areas[facei]);
+            scalar nbrMagSf = mag(half1Areas[facei]);
             scalar avSf = (magSf + nbrMagSf)/2.0;
 
             if (magSf < ROOTVSMALL && nbrMagSf < ROOTVSMALL)
@@ -177,8 +221,7 @@ void Foam::cyclicPolyPatch::calcTransforms()
                 FatalErrorIn
                 (
                     "cyclicPolyPatch::calcTransforms()"
-                )   << "face " << facei << " area does not match neighbour "
-                    << nbrFacei << " by "
+                )   << "face " << facei << " area does not match neighbour by "
                     << 100*mag(magSf - nbrMagSf)/avSf
                     << "% -- possible face ordering problem." << endl
                     << "patch:" << name()
@@ -187,268 +230,29 @@ void Foam::cyclicPolyPatch::calcTransforms()
                     << " matching tolerance:" << coupledPolyPatch::matchTol
                      << endl
                     << "Mesh face:" << start()+facei
-                    << " vertices:"
-                    << UIndirectList<point>(points, operator[](facei))()
+                    << " fc:" << half0Ctrs[facei]
                     << endl
-                    << "Neighbour face:" << start()+nbrFacei
-                    << " vertices:"
-                    << UIndirectList<point>(points, operator[](nbrFacei))()
+                    << "Neighbour fc:" << half1Ctrs[facei]
                     << endl
                     << "Rerun with cyclic debug flag set"
                     << " for more information." << exit(FatalError);
             }
             else
             {
-                half0Normals[facei] /= magSf;
-                half1Normals[facei] /= nbrMagSf;
+                half0Normals[facei] = half0Areas[facei] / magSf;
+                half1Normals[facei] = half1Areas[facei] / nbrMagSf;
             }
         }
 
-
-        // See if transformation is prescribed
-        // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-        switch (transform_)
-        {
-            case ROTATIONAL:
-            {
-                // Specified single rotation tensor.
-
-                // Get best fitting face and its opposite number
-                label face0 = getConsistentRotationFace(half0Ctrs);
-                label face1 = face0;
-
-                vector n0 =
-                    (
-                        (half0Ctrs[face0] - rotationCentre_)
-                      ^ rotationAxis_
-                    );
-                vector n1 =
-                    (
-                        (half1Ctrs[face1] - rotationCentre_)
-                      ^ -rotationAxis_
-                    );
-                n0 /= mag(n0) + VSMALL;
-                n1 /= mag(n1) + VSMALL;
-
-                if (debug)
-                {
-                    Pout<< "cyclicPolyPatch::calcTransforms :"
-                        << " Specified rotation :"
-                        << " n0:" << n0 << " n1:" << n1 << endl;
-                }
-
-                // Calculate transformation tensors from face0,1 only.
-                // Note: can use tight tolerance now.
-                calcTransformTensors
-                (
-                    pointField(1, half0Ctrs[face0]),
-                    pointField(1, half1Ctrs[face1]),
-                    vectorField(1, n0),
-                    vectorField(1, n1),
-                    scalarField(1, half0Tols[face0]),
-                    1E-4
-                );
-
-                break;
-            }
-
-            default:
-            {
-                // Calculate transformation tensors from all faces.
-                calcTransformTensors
-                (
-                    half0Ctrs,
-                    half1Ctrs,
-                    half0Normals,
-                    half1Normals,
-                    half0Tols
-                );
-
-                break;
-            }
-        }
-    }
-}
-
-
-// Get geometric zones of patch by looking at normals.
-// Method 1: any edge with sharpish angle is edge between two halves.
-//           (this will handle e.g. wedge geometries).
-//           Also two fully disconnected regions will be handled this way.
-// Method 2: sort faces into two halves based on face normal.
-bool Foam::cyclicPolyPatch::getGeometricHalves
-(
-    const primitivePatch& pp,
-    labelList& half0ToPatch,
-    labelList& half1ToPatch
-) const
-{
-    // Calculate normals
-    const vectorField& faceNormals = pp.faceNormals();
-
-    // Find edges with sharp angles.
-    boolList regionEdge(pp.nEdges(), false);
-
-    const labelListList& edgeFaces = pp.edgeFaces();
-
-    label nRegionEdges = 0;
-
-    forAll(edgeFaces, edgeI)
-    {
-        const labelList& eFaces = edgeFaces[edgeI];
-
-        // Check manifold edges for sharp angle.
-        // (Non-manifold already handled by patchZones)
-        if (eFaces.size() == 2)
-        {
-            if ((faceNormals[eFaces[0]] & faceNormals[eFaces[1]])< featureCos_)
-            {
-                regionEdge[edgeI] = true;
-
-                nRegionEdges++;
-            }
-        }
-    }
-
-
-    // For every face determine zone it is connected to (without crossing
-    // any regionEdge)
-    patchZones ppZones(pp, regionEdge);
-
-    if (debug)
-    {
-        Pout<< "cyclicPolyPatch::getGeometricHalves : "
-            << "Found " << nRegionEdges << " edges on patch " << name()
-            << " where the cos of the angle between two connected faces"
-            << " was less than " << featureCos_ << nl
-            << "Patch divided by these and by single sides edges into "
-            << ppZones.nZones() << " parts." << endl;
-
-
-        // Dumping zones to obj files.
-
-        labelList nZoneFaces(ppZones.nZones());
-
-        for (label zoneI = 0; zoneI < ppZones.nZones(); zoneI++)
-        {
-            OFstream stream
-            (
-                boundaryMesh().mesh().time().path()
-               /name()+"_zone_"+Foam::name(zoneI)+".obj"
-            );
-            Pout<< "cyclicPolyPatch::getGeometricHalves : Writing zone "
-                << zoneI << " face centres to OBJ file " << stream.name()
-                << endl;
-
-            labelList zoneFaces(findIndices(ppZones, zoneI));
-
-            forAll(zoneFaces, i)
-            {
-                writeOBJ(stream, pp[zoneFaces[i]].centre(pp.points()));
-            }
-
-            nZoneFaces[zoneI] = zoneFaces.size();
-        }
-    }
-
-
-    if (ppZones.nZones() == 2)
-    {
-        half0ToPatch = findIndices(ppZones, 0);
-        half1ToPatch = findIndices(ppZones, 1);
-    }
-    else
-    {
-        if (debug)
-        {
-            Pout<< "cyclicPolyPatch::getGeometricHalves :"
-                << " falling back to face-normal comparison" << endl;
-        }
-        label n0Faces = 0;
-        half0ToPatch.setSize(pp.size());
-
-        label n1Faces = 0;
-        half1ToPatch.setSize(pp.size());
-
-        // Compare to face 0 normal.
-        forAll(faceNormals, faceI)
-        {
-            if ((faceNormals[faceI] & faceNormals[0]) > 0)
-            {
-                half0ToPatch[n0Faces++] = faceI;
-            }
-            else
-            {
-                half1ToPatch[n1Faces++] = faceI;
-            }
-        }
-        half0ToPatch.setSize(n0Faces);
-        half1ToPatch.setSize(n1Faces);
-
-        if (debug)
-        {
-            Pout<< "cyclicPolyPatch::getGeometricHalves :"
-                << " Number of faces per zone:("
-                << n0Faces << ' ' << n1Faces << ')' << endl;
-        }
-    }
-
-    if (half0ToPatch.size() != half1ToPatch.size())
-    {
-        fileName casePath(boundaryMesh().mesh().time().path());
-
-        // Dump halves
-        {
-            fileName nm0(casePath/name()+"_half0_faces.obj");
-            Pout<< "cyclicPolyPatch::getGeometricHalves : Writing half0"
-                << " faces to OBJ file " << nm0 << endl;
-            writeOBJ(nm0, UIndirectList<face>(pp, half0ToPatch)(), pp.points());
-
-            fileName nm1(casePath/name()+"_half1_faces.obj");
-            Pout<< "cyclicPolyPatch::getGeometricHalves : Writing half1"
-                << " faces to OBJ file " << nm1 << endl;
-            writeOBJ(nm1, UIndirectList<face>(pp, half1ToPatch)(), pp.points());
-        }
-
-        // Dump face centres
-        {
-            OFstream str0(casePath/name()+"_half0.obj");
-            Pout<< "cyclicPolyPatch::getGeometricHalves : Writing half0"
-                << " face centres to OBJ file " << str0.name() << endl;
-
-            forAll(half0ToPatch, i)
-            {
-                writeOBJ(str0, pp[half0ToPatch[i]].centre(pp.points()));
-            }
-
-            OFstream str1(casePath/name()+"_half1.obj");
-            Pout<< "cyclicPolyPatch::getGeometricHalves : Writing half1"
-                << " face centres to OBJ file " << str1.name() << endl;
-            forAll(half1ToPatch, i)
-            {
-                writeOBJ(str1, pp[half1ToPatch[i]].centre(pp.points()));
-            }
-        }
-
-        SeriousErrorIn
+        // Calculate transformation tensors
+        calcTransformTensors
         (
-            "cyclicPolyPatch::getGeometricHalves"
-            "(const primitivePatch&, labelList&, labelList&) const"
-        )   << "Patch " << name() << " gets decomposed in two zones of"
-            << "inequal size: " << half0ToPatch.size()
-            << " and " << half1ToPatch.size() << endl
-            << "This means that the patch is either not two separate regions"
-            << " or one region where the angle between the different regions"
-            << " is not sufficiently sharp." << endl
-            << "Please adapt the featureCos setting." << endl
-            << "Continuing with incorrect face ordering from now on!" << endl;
-
-        return false;
-    }
-    else
-    {
-        return true;
+            static_cast<const pointField&>(half0Ctrs),
+            static_cast<const pointField&>(half1Ctrs),
+            half0Normals,
+            half1Normals,
+            half0Tols
+        );
     }
 }
 
@@ -458,11 +262,9 @@ bool Foam::cyclicPolyPatch::getGeometricHalves
 // right ones.
 void Foam::cyclicPolyPatch::getCentresAndAnchors
 (
-    const primitivePatch& pp,
-    const faceList& half0Faces,
-    const faceList& half1Faces,
+    const primitivePatch& pp0,
+    const primitivePatch& pp1,
 
-    pointField& ppPoints,
     pointField& half0Ctrs,
     pointField& half1Ctrs,
     pointField& anchors0,
@@ -470,9 +272,9 @@ void Foam::cyclicPolyPatch::getCentresAndAnchors
 ) const
 {
     // Get geometric data on both halves.
-    half0Ctrs = calcFaceCentres(half0Faces, pp.points());
-    anchors0 = getAnchorPoints(half0Faces, pp.points());
-    half1Ctrs = calcFaceCentres(half1Faces, pp.points());
+    half0Ctrs = pp0.faceCentres();
+    anchors0 = getAnchorPoints(pp0, pp0.points());
+    half1Ctrs = pp1.faceCentres();
 
     switch (transform_)
     {
@@ -503,8 +305,6 @@ void Foam::cyclicPolyPatch::getCentresAndAnchors
                 anchors0[faceI] = Foam::transform(reverseT, anchors0[faceI]);
             }
 
-            ppPoints = Foam::transform(reverseT, pp.points());
-
             break;
         }
         //- Problem: usually specified translation is not accurate enough
@@ -531,12 +331,12 @@ void Foam::cyclicPolyPatch::getCentresAndAnchors
 
             // Determine the face with max area on both halves. These
             // two faces are used to determine the transformation tensors
-            label max0I = findMaxArea(pp.points(), half0Faces);
-            vector n0 = half0Faces[max0I].normal(pp.points());
+            label max0I = findMaxArea(pp0.points(), pp0);
+            vector n0 = pp0[max0I].normal(pp0.points());
             n0 /= mag(n0) + VSMALL;
 
-            label max1I = findMaxArea(pp.points(), half1Faces);
-            vector n1 = half1Faces[max1I].normal(pp.points());
+            label max1I = findMaxArea(pp1.points(), pp1);
+            vector n1 = pp1[max1I].normal(pp1.points());
             n1 /= mag(n1) + VSMALL;
 
             if (mag(n0 & n1) < 1-coupledPolyPatch::matchTol)
@@ -565,19 +365,13 @@ void Foam::cyclicPolyPatch::getCentresAndAnchors
                         anchors0[faceI]
                     );
                 }
-                ppPoints = Foam::transform(reverseT, pp.points());
             }
             else
             {
                 // Parallel translation. Get average of all used points.
 
-                primitiveFacePatch half0(half0Faces, pp.points());
-                const pointField& half0Pts = half0.localPoints();
-                const point ctr0(sum(half0Pts)/half0Pts.size());
-
-                primitiveFacePatch half1(half1Faces, pp.points());
-                const pointField& half1Pts = half1.localPoints();
-                const point ctr1(sum(half1Pts)/half1Pts.size());
+                const point ctr0(sum(pp0.localPoints())/pp0.nPoints());
+                const point ctr1(sum(pp1.localPoints())/pp1.nPoints());
 
                 if (debug)
                 {
@@ -589,7 +383,6 @@ void Foam::cyclicPolyPatch::getCentresAndAnchors
 
                 half0Ctrs += ctr1 - ctr0;
                 anchors0 += ctr1 - ctr0;
-                ppPoints = pp.points() + ctr1 - ctr0;
             }
             break;
         }
@@ -597,92 +390,7 @@ void Foam::cyclicPolyPatch::getCentresAndAnchors
 
 
     // Calculate typical distance per face
-    tols = calcFaceTol(half1Faces, pp.points(), half1Ctrs);
-}
-
-
-// Calculates faceMap and rotation. Returns true if all ok.
-bool Foam::cyclicPolyPatch::matchAnchors
-(
-    const bool report,
-    const primitivePatch& pp,
-    const labelList& half0ToPatch,
-    const pointField& anchors0,
-
-    const labelList& half1ToPatch,
-    const faceList& half1Faces,
-    const labelList& from1To0,
-
-    const scalarField& tols,
-
-    labelList& faceMap,
-    labelList& rotation
-) const
-{
-    // Set faceMap such that half0 faces get first and corresponding half1
-    // faces last.
-
-    forAll(half0ToPatch, half0FaceI)
-    {
-        // Label in original patch
-        label patchFaceI = half0ToPatch[half0FaceI];
-
-        faceMap[patchFaceI] = half0FaceI;
-
-        // No rotation
-        rotation[patchFaceI] = 0;
-    }
-
-    bool fullMatch = true;
-
-    forAll(from1To0, half1FaceI)
-    {
-        label patchFaceI = half1ToPatch[half1FaceI];
-
-        // This face has to match the corresponding one on half0.
-        label half0FaceI = from1To0[half1FaceI];
-
-        label newFaceI = half0FaceI + pp.size()/2;
-
-        faceMap[patchFaceI] = newFaceI;
-
-        // Rotate patchFaceI such that its f[0] aligns with that of
-        // the corresponding face
-        // (which after shuffling will be at position half0FaceI)
-
-        const point& wantedAnchor = anchors0[half0FaceI];
-
-        rotation[newFaceI] = getRotation
-        (
-            pp.points(),
-            half1Faces[half1FaceI],
-            wantedAnchor,
-            tols[half1FaceI]
-        );
-
-        if (rotation[newFaceI] == -1)
-        {
-            fullMatch = false;
-
-            if (report)
-            {
-                const face& f = half1Faces[half1FaceI];
-                SeriousErrorIn
-                (
-                    "cyclicPolyPatch::matchAnchors(..)"
-                )   << "Patch:" << name() << " : "
-                    << "Cannot find point on face " << f
-                    << " with vertices:"
-                    << UIndirectList<point>(pp.points(), f)()
-                    << " that matches point " << wantedAnchor
-                    << " when matching the halves of cyclic patch " << name()
-                    << endl
-                    << "Continuing with incorrect face ordering from now on!"
-                    << endl;
-            }
-        }
-    }
-    return fullMatch;
+    tols = calcFaceTol(pp1, pp1.points(), half1Ctrs);
 }
 
 
@@ -715,7 +423,7 @@ Foam::label Foam::cyclicPolyPatch::getConsistentRotationFace
 
     if (debug)
     {
-        Info<< "getConsistentRotationFace(const pointField&)" << nl
+        Pout<< "getConsistentRotationFace(const pointField&)" << nl
             << "    rotFace = " << rotFace << nl
             << "    point =  " << faceCentres[rotFace] << endl;
     }
@@ -736,14 +444,18 @@ Foam::cyclicPolyPatch::cyclicPolyPatch
 )
 :
     coupledPolyPatch(name, size, start, index, bm),
-    coupledPointsPtr_(NULL),
-    coupledEdgesPtr_(NULL),
-    featureCos_(0.9),
+    neighbPatchName_(word::null),
+    neighbPatchID_(-1),
     transform_(UNKNOWN),
     rotationAxis_(vector::zero),
     rotationCentre_(point::zero),
-    separationVector_(vector::zero)
-{}
+    separationVector_(vector::zero),
+    coupledPointsPtr_(NULL),
+    coupledEdgesPtr_(NULL)
+{
+    // Neighbour patch might not be valid yet so no transformation
+    // calculation possible.
+}
 
 
 Foam::cyclicPolyPatch::cyclicPolyPatch
@@ -755,15 +467,40 @@ Foam::cyclicPolyPatch::cyclicPolyPatch
 )
 :
     coupledPolyPatch(name, dict, index, bm),
-    coupledPointsPtr_(NULL),
-    coupledEdgesPtr_(NULL),
-    featureCos_(0.9),
+    neighbPatchName_(dict.lookupOrDefault("neighbourPatch", word::null)),
+    neighbPatchID_(-1),
     transform_(UNKNOWN),
     rotationAxis_(vector::zero),
     rotationCentre_(point::zero),
-    separationVector_(vector::zero)
+    separationVector_(vector::zero),
+    coupledPointsPtr_(NULL),
+    coupledEdgesPtr_(NULL)
 {
-    dict.readIfPresent("featureCos", featureCos_);
+    if (neighbPatchName_ == word::null)
+    {
+        FatalIOErrorIn
+        (
+            "cyclicPolyPatch::cyclicPolyPatch\n"
+            "(\n"
+            "    const word& name,\n"
+            "    const dictionary& dict,\n"
+            "    const label index,\n"
+            "    const polyBoundaryMesh& bm\n"
+            ")",
+            dict
+        )   << "No \"neighbourPatch\" provided." << endl
+            << "Is your mesh uptodate with split cyclics?" << endl
+            << "Run foamUpgradeCyclics to convert mesh and fields"
+            << " to split cyclics." << exit(FatalIOError);
+    }
+
+    if (neighbPatchName_ == name)
+    {
+        FatalIOErrorIn("cyclicPolyPatch::cyclicPolyPatch(..)", dict)
+            << "Neighbour patch name " << neighbPatchName_
+            << " cannot be the same as this patch " << name
+            << exit(FatalIOError);
+    }
 
     if (dict.found("transform"))
     {
@@ -787,6 +524,9 @@ Foam::cyclicPolyPatch::cyclicPolyPatch
             }
         }
     }
+
+    // Neighbour patch might not be valid yet so no transformation
+    // calculation possible.
 }
 
 
@@ -797,14 +537,18 @@ Foam::cyclicPolyPatch::cyclicPolyPatch
 )
 :
     coupledPolyPatch(pp, bm),
-    coupledPointsPtr_(NULL),
-    coupledEdgesPtr_(NULL),
-    featureCos_(pp.featureCos_),
+    neighbPatchName_(pp.neighbPatchName()),
+    neighbPatchID_(-1),
     transform_(pp.transform_),
     rotationAxis_(pp.rotationAxis_),
     rotationCentre_(pp.rotationCentre_),
-    separationVector_(pp.separationVector_)
-{}
+    separationVector_(pp.separationVector_),
+    coupledPointsPtr_(NULL),
+    coupledEdgesPtr_(NULL)
+{
+    // Neighbour patch might not be valid yet so no transformation
+    // calculation possible.
+}
 
 
 Foam::cyclicPolyPatch::cyclicPolyPatch
@@ -813,18 +557,31 @@ Foam::cyclicPolyPatch::cyclicPolyPatch
     const polyBoundaryMesh& bm,
     const label index,
     const label newSize,
-    const label newStart
+    const label newStart,
+    const word& neighbPatchName
 )
 :
     coupledPolyPatch(pp, bm, index, newSize, newStart),
-    coupledPointsPtr_(NULL),
-    coupledEdgesPtr_(NULL),
-    featureCos_(pp.featureCos_),
+    neighbPatchName_(neighbPatchName),
+    neighbPatchID_(-1),
     transform_(pp.transform_),
     rotationAxis_(pp.rotationAxis_),
     rotationCentre_(pp.rotationCentre_),
-    separationVector_(pp.separationVector_)
-{}
+    separationVector_(pp.separationVector_),
+    coupledPointsPtr_(NULL),
+    coupledEdgesPtr_(NULL)
+{
+    if (neighbPatchName_ == name())
+    {
+        FatalErrorIn("cyclicPolyPatch::cyclicPolyPatch(..)")
+            << "Neighbour patch name " << neighbPatchName_
+            << " cannot be the same as this patch " << name()
+            << exit(FatalError);
+    }
+
+    // Neighbour patch might not be valid yet so no transformation
+    // calculation possible.
+}
 
 
 Foam::cyclicPolyPatch::cyclicPolyPatch
@@ -837,13 +594,14 @@ Foam::cyclicPolyPatch::cyclicPolyPatch
 )
 :
     coupledPolyPatch(pp, bm, index, mapAddressing, newStart),
-    coupledPointsPtr_(NULL),
-    coupledEdgesPtr_(NULL),
-    featureCos_(pp.featureCos_),
+    neighbPatchName_(pp.neighbPatchName_),
+    neighbPatchID_(-1),
     transform_(pp.transform_),
     rotationAxis_(pp.rotationAxis_),
     rotationCentre_(pp.rotationCentre_),
-    separationVector_(pp.separationVector_)
+    separationVector_(pp.separationVector_),
+    coupledPointsPtr_(NULL),
+    coupledEdgesPtr_(NULL)
 {}
 
 
@@ -859,17 +617,72 @@ Foam::cyclicPolyPatch::~cyclicPolyPatch()
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
+void Foam::cyclicPolyPatch::transformPosition(pointField& l) const
+{
+    if (!parallel())
+    {
+        Foam::transform(forwardT(), l);
+    }
+    else if (separated())
+    {
+        l -= separation();
+    }
+}
+
+
 void Foam::cyclicPolyPatch::initGeometry(PstreamBuffers& pBufs)
 {
     polyPatch::initGeometry(pBufs);
 }
 
+
+void Foam::cyclicPolyPatch::initGeometry
+(
+    const primitivePatch& referPatch,
+    UList<point>& nbrCtrs,
+    UList<point>& nbrAreas,
+    UList<point>& nbrCc
+)
+{}
+
+
+void Foam::cyclicPolyPatch::calcGeometry
+(
+    const primitivePatch& referPatch,
+    const UList<point>& thisCtrs,
+    const UList<point>& thisAreas,
+    const UList<point>& thisCc,
+    const UList<point>& nbrCtrs,
+    const UList<point>& nbrAreas,
+    const UList<point>& nbrCc
+)
+{
+    calcTransforms
+    (
+        referPatch,
+        thisCtrs,
+        thisAreas,
+        nbrCtrs,
+        nbrAreas
+    );
+}
+
+
 void Foam::cyclicPolyPatch::calcGeometry(PstreamBuffers& pBufs)
 {
-    polyPatch::calcGeometry(pBufs);
-    calcTransforms();
+    calcGeometry
+    (
+        *this,
+        faceCentres(),
+        faceAreas(),
+        faceCellCentres(),
+        neighbPatch().faceCentres(),
+        neighbPatch().faceAreas(),
+        neighbPatch().faceCellCentres()
+    );
 }
 
+
 void Foam::cyclicPolyPatch::initMovePoints
 (
     PstreamBuffers& pBufs,
@@ -906,17 +719,20 @@ const Foam::edgeList& Foam::cyclicPolyPatch::coupledPoints() const
 {
     if (!coupledPointsPtr_)
     {
-        // Look at cyclic patch as two halves, A and B.
-        // Now all we know is that relative face index in halfA is same
-        // as coupled face in halfB and also that the 0th vertex
+        const faceList& nbrLocalFaces = neighbPatch().localFaces();
+        const labelList& nbrMeshPoints = neighbPatch().meshPoints();
+
+        // Now all we know is that relative face index in *this is same
+        // as coupled face in nbrPatch and also that the 0th vertex
         // corresponds.
 
-        // From halfA point to halfB or -1.
+        // From local point to nbrPatch or -1.
         labelList coupledPoint(nPoints(), -1);
 
-        for (label patchFaceA = 0; patchFaceA < size()/2; patchFaceA++)
+        forAll(*this, patchFaceI)
         {
-            const face& fA = localFaces()[patchFaceA];
+            const face& fA = localFaces()[patchFaceI];
+            const face& fB = nbrLocalFaces[patchFaceI];
 
             forAll(fA, indexA)
             {
@@ -924,12 +740,10 @@ const Foam::edgeList& Foam::cyclicPolyPatch::coupledPoints() const
 
                 if (coupledPoint[patchPointA] == -1)
                 {
-                    const face& fB = localFaces()[patchFaceA + size()/2];
-
                     label indexB = (fB.size() - indexA) % fB.size();
 
                     // Filter out points on wedge axis
-                    if (patchPointA != fB[indexB])
+                    if (meshPoints()[patchPointA] != nbrMeshPoints[fB[indexB]])
                     {
                         coupledPoint[patchPointA] = fB[indexB];
                     }
@@ -958,7 +772,7 @@ const Foam::edgeList& Foam::cyclicPolyPatch::coupledPoints() const
             OFstream str
             (
                 boundaryMesh().mesh().time().path()
-               /"coupledPoints.obj"
+               /name() + "_coupledPoints.obj"
             );
             label vertI = 0;
 
@@ -968,7 +782,7 @@ const Foam::edgeList& Foam::cyclicPolyPatch::coupledPoints() const
             forAll(connected, i)
             {
                 const point& a = points()[meshPoints()[connected[i][0]]];
-                const point& b = points()[meshPoints()[connected[i][1]]];
+                const point& b = points()[nbrMeshPoints[connected[i][1]]];
 
                 str<< "v " << a.x() << ' ' << a.y() << ' ' << a.z() << nl;
                 str<< "v " << b.x() << ' ' << b.y() << ' ' << b.z() << nl;
@@ -979,8 +793,20 @@ const Foam::edgeList& Foam::cyclicPolyPatch::coupledPoints() const
         }
 
         // Remove any addressing calculated for the coupled edges calculation
-        const_cast<primitivePatch&>(static_cast<const primitivePatch&>(*this))
-            .clearOut();
+        const_cast<primitivePatch&>
+        (
+            static_cast<const primitivePatch&>
+            (
+                *this
+            )
+        ).clearOut();
+        const_cast<primitivePatch&>
+        (
+            static_cast<const primitivePatch&>
+            (
+                neighbPatch()
+            )
+        ).clearOut();
     }
     return *coupledPointsPtr_;
 }
@@ -990,9 +816,9 @@ const Foam::edgeList& Foam::cyclicPolyPatch::coupledEdges() const
 {
     if (!coupledEdgesPtr_)
     {
-        // Build map from points on halfA to points on halfB.
         const edgeList& pointCouples = coupledPoints();
 
+        // Build map from points on *this (A) to points on neighbourpatch (B)
         Map<label> aToB(2*pointCouples.size());
 
         forAll(pointCouples, i)
@@ -1002,12 +828,12 @@ const Foam::edgeList& Foam::cyclicPolyPatch::coupledEdges() const
             aToB.insert(e[0], e[1]);
         }
 
-        // Map from edge on half A to points (in halfB indices)
+        // Map from edge on A to points (in B indices)
         EdgeMap<label> edgeMap(nEdges());
 
-        for (label patchFaceA = 0; patchFaceA < size()/2; patchFaceA++)
+        forAll(*this, patchFaceI)
         {
-            const labelList& fEdges = faceEdges()[patchFaceA];
+            const labelList& fEdges = faceEdges()[patchFaceI];
 
             forAll(fEdges, i)
             {
@@ -1015,8 +841,7 @@ const Foam::edgeList& Foam::cyclicPolyPatch::coupledEdges() const
 
                 const edge& e = edges()[edgeI];
 
-                // Convert edge end points to corresponding points on halfB
-                // side.
+                // Convert edge end points to corresponding points on B side.
                 Map<label>::const_iterator fnd0 = aToB.find(e[0]);
                 if (fnd0 != aToB.end())
                 {
@@ -1029,31 +854,44 @@ const Foam::edgeList& Foam::cyclicPolyPatch::coupledEdges() const
             }
         }
 
-        coupledEdgesPtr_ = new edgeList(nEdges()/2);
+        // Use the edgeMap to get the edges on the B side.
+
+        const cyclicPolyPatch& neighbPatch = this->neighbPatch();
+        const labelList& nbrMp = neighbPatch.meshPoints();
+        const labelList& mp = meshPoints();
+
+
+
+        coupledEdgesPtr_ = new edgeList(edgeMap.size());
         edgeList& coupledEdges = *coupledEdgesPtr_;
         label coupleI = 0;
 
-        for (label patchFaceB = size()/2; patchFaceB < size(); patchFaceB++)
+        forAll(neighbPatch, patchFaceI)
         {
-            const labelList& fEdges = faceEdges()[patchFaceB];
+            const labelList& fEdges = neighbPatch.faceEdges()[patchFaceI];
 
             forAll(fEdges, i)
             {
                 label edgeI = fEdges[i];
 
-                const edge& e = edges()[edgeI];
+                const edge& e = neighbPatch.edges()[edgeI];
 
-                // Look up halfA edge from HashTable.
+                // Look up A edge from HashTable.
                 EdgeMap<label>::iterator iter = edgeMap.find(e);
 
                 if (iter != edgeMap.end())
                 {
-                    label halfAEdgeI = iter();
+                    label edgeA = iter();
+                    const edge& eA = edges()[edgeA];
 
                     // Store correspondence. Filter out edges on wedge axis.
-                    if (halfAEdgeI != edgeI)
+                    if
+                    (
+                        edge(mp[eA[0]], mp[eA[1]])
+                     != edge(nbrMp[e[0]], nbrMp[e[1]])
+                    )
                     {
-                        coupledEdges[coupleI++] = edge(halfAEdgeI, edgeI);
+                        coupledEdges[coupleI++] = edge(edgeA, edgeI);
                     }
 
                     // Remove so we build unique list
@@ -1070,7 +908,7 @@ const Foam::edgeList& Foam::cyclicPolyPatch::coupledEdges() const
         {
             const edge& e = coupledEdges[i];
 
-            if (e[0] == e[1] || e[0] < 0 || e[1] < 0)
+            if (e[0] < 0 || e[1] < 0)
             {
                 FatalErrorIn("cyclicPolyPatch::coupledEdges() const")
                     << "Problem : at position " << i
@@ -1084,7 +922,7 @@ const Foam::edgeList& Foam::cyclicPolyPatch::coupledEdges() const
             OFstream str
             (
                 boundaryMesh().mesh().time().path()
-               /"coupledEdges.obj"
+               /name() + "_coupledEdges.obj"
             );
             label vertI = 0;
 
@@ -1096,7 +934,10 @@ const Foam::edgeList& Foam::cyclicPolyPatch::coupledEdges() const
                 const edge& e = coupledEdges[i];
 
                 const point& a = edges()[e[0]].centre(localPoints());
-                const point& b = edges()[e[1]].centre(localPoints());
+                const point& b = neighbPatch.edges()[e[1]].centre
+                (
+                    neighbPatch.localPoints()
+                );
 
                 str<< "v " << a.x() << ' ' << a.y() << ' ' << a.z() << nl;
                 str<< "v " << b.x() << ' ' << b.y() << ' ' << b.z() << nl;
@@ -1107,8 +948,20 @@ const Foam::edgeList& Foam::cyclicPolyPatch::coupledEdges() const
         }
 
         // Remove any addressing calculated for the coupled edges calculation
-        const_cast<primitivePatch&>(static_cast<const primitivePatch&>(*this))
-            .clearOut();
+        const_cast<primitivePatch&>
+        (
+            static_cast<const primitivePatch&>
+            (
+                *this
+            )
+        ).clearOut();
+        const_cast<primitivePatch&>
+        (
+            static_cast<const primitivePatch&>
+            (
+                neighbPatch
+            )
+        ).clearOut();
     }
     return *coupledEdgesPtr_;
 }
@@ -1119,7 +972,21 @@ void Foam::cyclicPolyPatch::initOrder
     PstreamBuffers&,
     const primitivePatch& pp
 ) const
-{}
+{
+    if (owner())
+    {
+        // Save patch for use in non-owner side ordering. Equivalent to
+        // processorPolyPatch using OPstream.
+        ownerPatchPtr_.reset
+        (
+            new primitivePatch
+            (
+                pp,
+                pp.points()
+            )
+        );
+    }
+}
 
 
 //  Return new ordering. Ordering is -faceMap: for every face index
@@ -1140,148 +1007,36 @@ bool Foam::cyclicPolyPatch::order
     rotation.setSize(pp.size());
     rotation = 0;
 
-    if (pp.empty())
+    if (pp.empty() || transform_ == NOORDERING)
     {
         // No faces, nothing to change.
         return false;
     }
 
-    if (pp.size()&1)
+    if (owner())
     {
-        FatalErrorIn("cyclicPolyPatch::order(..)")
-            << "Size of cyclic " << name() << " should be a multiple of 2"
-            << ". It is " << pp.size() << abort(FatalError);
-    }
-
-    if (transform_ == NOORDERING)
-    {
-        if (debug)
+        // Do nothing (i.e. identical mapping, zero rotation).
+        // See comment at top.
+        forAll(faceMap, patchFaceI)
         {
-            Pout<< "cyclicPolyPatch::order : noOrdering mode." << endl;
+            faceMap[patchFaceI] = patchFaceI;
         }
-        return false;
-    }
-
-
-    label halfSize = pp.size()/2;
-
-    // Supplied primitivePatch already with new points.
-    // Cyclics are limited to one transformation tensor
-    // currently anyway (i.e. straight plane) so should not be too big a
-    // problem.
-
-
-    // Indices of faces on half0
-    labelList half0ToPatch;
-    // Indices of faces on half1
-    labelList half1ToPatch;
-
-
-    // 1. Test if already correctly oriented by starting from trivial ordering.
-    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-    half0ToPatch = identity(halfSize);
-    half1ToPatch = half0ToPatch + halfSize;
-
-    // Get faces
-    faceList half0Faces(UIndirectList<face>(pp, half0ToPatch));
-    faceList half1Faces(UIndirectList<face>(pp, half1ToPatch));
-
-    // Get geometric quantities
-    pointField half0Ctrs, half1Ctrs, anchors0, ppPoints;
-    scalarField tols;
-    getCentresAndAnchors
-    (
-        pp,
-        half0Faces,
-        half1Faces,
-
-        ppPoints,
-        half0Ctrs,
-        half1Ctrs,
-        anchors0,
-        tols
-    );
-
-    // Geometric match of face centre vectors
-    labelList from1To0;
-    bool matchedAll = matchPoints
-    (
-        half1Ctrs,
-        half0Ctrs,
-        tols,
-        false,
-        from1To0
-    );
-
-    if (debug)
-    {
-        Pout<< "cyclicPolyPatch::order : test if already ordered:"
-            << matchedAll << endl;
-
-        // Dump halves
-        fileName nm0("match1_"+name()+"_half0_faces.obj");
-        Pout<< "cyclicPolyPatch::order : Writing half0"
-            << " faces to OBJ file " << nm0 << endl;
-        writeOBJ(nm0, half0Faces, ppPoints);
-
-        fileName nm1("match1_"+name()+"_half1_faces.obj");
-        Pout<< "cyclicPolyPatch::order : Writing half1"
-            << " faces to OBJ file " << nm1 << endl;
-        writeOBJ(nm1, half1Faces, pp.points());
-
-        OFstream ccStr
-        (
-            boundaryMesh().mesh().time().path()
-           /"match1_"+ name() + "_faceCentres.obj"
-        );
-        Pout<< "cyclicPolyPatch::order : "
-            << "Dumping currently found cyclic match as lines between"
-            << " corresponding face centres to file " << ccStr.name()
-            << endl;
 
-        // Recalculate untransformed face centres
-        //pointField rawHalf0Ctrs = calcFaceCentres(half0Faces, pp.points());
-        label vertI = 0;
-
-        forAll(half1Ctrs, i)
-        {
-            //if (from1To0[i] != -1)
-            {
-                // Write edge between c1 and c0
-                //const point& c0 = rawHalf0Ctrs[from1To0[i]];
-                //const point& c0 = half0Ctrs[from1To0[i]];
-                const point& c0 = half0Ctrs[i];
-                const point& c1 = half1Ctrs[i];
-                writeOBJ(ccStr, c0, c1, vertI);
-            }
-        }
+        return false;
     }
-
-
-    // 2. Ordered in pairs (so 0,1 coupled and 2,3 etc.)
-    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-    if (!matchedAll)
+    else
     {
-        label faceI = 0;
-        for (label i = 0; i < halfSize; i++)
-        {
-            half0ToPatch[i] = faceI++;
-            half1ToPatch[i] = faceI++;
-        }
-
-        // And redo all matching
-        half0Faces = UIndirectList<face>(pp, half0ToPatch);
-        half1Faces = UIndirectList<face>(pp, half1ToPatch);
+        // Get stored geometry from initOrder invocation of owner.
+        const primitivePatch& pp0 = neighbPatch().ownerPatchPtr_();
 
+        // Get geometric quantities
+        pointField half0Ctrs, half1Ctrs, anchors0;
+        scalarField tols;
         getCentresAndAnchors
         (
+            pp0,
             pp,
-            half0Faces,
-            half1Faces,
 
-            ppPoints,
             half0Ctrs,
             half1Ctrs,
             anchors0,
@@ -1289,34 +1044,40 @@ bool Foam::cyclicPolyPatch::order
         );
 
         // Geometric match of face centre vectors
-        matchedAll = matchPoints
+        bool matchedAll = matchPoints
         (
             half1Ctrs,
             half0Ctrs,
             tols,
-            false,
-            from1To0
+            true,
+            faceMap
         );
 
-        if (debug)
+        if (!matchedAll || debug)
         {
-            Pout<< "cyclicPolyPatch::order : test if pairwise ordered:"
-                << matchedAll << endl;
             // Dump halves
-            fileName nm0("match2_"+name()+"_half0_faces.obj");
+            fileName nm0
+            (
+                boundaryMesh().mesh().time().path()
+               /name()+"_half0_faces.obj"
+            );
             Pout<< "cyclicPolyPatch::order : Writing half0"
                 << " faces to OBJ file " << nm0 << endl;
-            writeOBJ(nm0, half0Faces, ppPoints);
+            writeOBJ(nm0, pp0, pp0.points());
 
-            fileName nm1("match2_"+name()+"_half1_faces.obj");
+            fileName nm1
+            (
+                boundaryMesh().mesh().time().path()
+               /name()+"_half1_faces.obj"
+            );
             Pout<< "cyclicPolyPatch::order : Writing half1"
                 << " faces to OBJ file " << nm1 << endl;
-            writeOBJ(nm1, half1Faces, pp.points());
+            writeOBJ(nm1, pp, pp.points());
 
             OFstream ccStr
             (
                 boundaryMesh().mesh().time().path()
-               /"match2_"+name()+"_faceCentres.obj"
+               /name() + "_faceCentres.obj"
             );
             Pout<< "cyclicPolyPatch::order : "
                 << "Dumping currently found cyclic match as lines between"
@@ -1330,312 +1091,95 @@ bool Foam::cyclicPolyPatch::order
 
             forAll(half1Ctrs, i)
             {
-                if (from1To0[i] != -1)
+                if (faceMap[i] != -1)
                 {
                     // Write edge between c1 and c0
-                    //const point& c0 = rawHalf0Ctrs[from1To0[i]];
-                    const point& c0 = half0Ctrs[from1To0[i]];
+                    const point& c0 = half0Ctrs[faceMap[i]];
                     const point& c1 = half1Ctrs[i];
                     writeOBJ(ccStr, c0, c1, vertI);
                 }
             }
         }
-    }
-
-
-    // 3. Baffles(coincident faces) converted into cyclics (e.g. jump)
-    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-    if (!matchedAll)
-    {
-        label baffleI = 0;
-
-        forAll(pp, faceI)
-        {
-            const face& f = pp.localFaces()[faceI];
-            const labelList& pFaces = pp.pointFaces()[f[0]];
-
-            label matchedFaceI = -1;
-
-            forAll(pFaces, i)
-            {
-                label otherFaceI = pFaces[i];
-
-                if (otherFaceI > faceI)
-                {
-                    const face& otherF = pp.localFaces()[otherFaceI];
-
-                    // Note: might pick up two similar oriented faces
-                    //       (but that is illegal anyway)
-                    if (f == otherF)
-                    {
-                        matchedFaceI = otherFaceI;
-                        break;
-                    }
-                }
-            }
-
-            if (matchedFaceI != -1)
-            {
-                half0ToPatch[baffleI] = faceI;
-                half1ToPatch[baffleI] = matchedFaceI;
-                baffleI++;
-            }
-        }
 
-        if (baffleI == halfSize)
+        if (!matchedAll)
         {
-            // And redo all matching
-            half0Faces = UIndirectList<face>(pp, half0ToPatch);
-            half1Faces = UIndirectList<face>(pp, half1ToPatch);
-
-            getCentresAndAnchors
-            (
-                pp,
-                half0Faces,
-                half1Faces,
-
-                ppPoints,
-                half0Ctrs,
-                half1Ctrs,
-                anchors0,
-                tols
-            );
-
-            // Geometric match of face centre vectors
-            matchedAll = matchPoints
+            SeriousErrorIn
             (
-                half1Ctrs,
-                half0Ctrs,
-                tols,
-                false,
-                from1To0
-            );
-
-            if (debug)
-            {
-                Pout<< "cyclicPolyPatch::order : test if baffles:"
-                    << matchedAll << endl;
-                // Dump halves
-                fileName nm0("match3_"+name()+"_half0_faces.obj");
-                Pout<< "cyclicPolyPatch::order : Writing half0"
-                    << " faces to OBJ file " << nm0 << endl;
-                writeOBJ(nm0, half0Faces, ppPoints);
-
-                fileName nm1("match3_"+name()+"_half1_faces.obj");
-                Pout<< "cyclicPolyPatch::order : Writing half1"
-                    << " faces to OBJ file " << nm1 << endl;
-                writeOBJ(nm1, half1Faces, pp.points());
-
-                OFstream ccStr
-                (
-                    boundaryMesh().mesh().time().path()
-                   /"match3_"+ name() + "_faceCentres.obj"
-                );
-                Pout<< "cyclicPolyPatch::order : "
-                    << "Dumping currently found cyclic match as lines between"
-                    << " corresponding face centres to file " << ccStr.name()
-                    << endl;
-
-                // Recalculate untransformed face centres
-                //pointField rawHalf0Ctrs =
-                //    calcFaceCentres(half0Faces, pp.points());
-                label vertI = 0;
+                "cyclicPolyPatch::order"
+                "(const primitivePatch&, labelList&, labelList&) const"
+            )   << "Patch:" << name() << " : "
+                << "Cannot match vectors to faces on both sides of patch"
+                << endl
+                << "    Perhaps your faces do not match?"
+                << " The obj files written contain the current match." << endl
+                << "    Continuing with incorrect face ordering from now on!"
+                << endl;
 
-                forAll(half1Ctrs, i)
-                {
-                    if (from1To0[i] != -1)
-                    {
-                        // Write edge between c1 and c0
-                        //const point& c0 = rawHalf0Ctrs[from1To0[i]];
-                        const point& c0 = half0Ctrs[from1To0[i]];
-                        const point& c1 = half1Ctrs[i];
-                        writeOBJ(ccStr, c0, c1, vertI);
-                    }
-                }
-            }
+                return false;
         }
-    }
-
 
-    // 4. Automatic geometric ordering
-    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-    if (!matchedAll)
-    {
-        // Split faces according to feature angle or topology
-        bool okSplit = getGeometricHalves(pp, half0ToPatch, half1ToPatch);
-
-        if (!okSplit)
+        // Set rotation.
+        forAll(faceMap, oldFaceI)
         {
-            // Did not split into two equal parts.
-            return false;
-        }
-
-        // And redo all matching
-        half0Faces = UIndirectList<face>(pp, half0ToPatch);
-        half1Faces = UIndirectList<face>(pp, half1ToPatch);
-
-        getCentresAndAnchors
-        (
-            pp,
-            half0Faces,
-            half1Faces,
-
-            ppPoints,
-            half0Ctrs,
-            half1Ctrs,
-            anchors0,
-            tols
-        );
-
-        // Geometric match of face centre vectors
-        matchedAll = matchPoints
-        (
-            half1Ctrs,
-            half0Ctrs,
-            tols,
-            false,
-            from1To0
-        );
+            // The face f will be at newFaceI (after morphing) and we want its
+            // anchorPoint (= f[0]) to align with the anchorpoint for the
+            // corresponding face on the other side.
 
-        if (debug)
-        {
-            Pout<< "cyclicPolyPatch::order : automatic ordering result:"
-                << matchedAll << endl;
-            // Dump halves
-            fileName nm0("match4_"+name()+"_half0_faces.obj");
-            Pout<< "cyclicPolyPatch::order : Writing half0"
-                << " faces to OBJ file " << nm0 << endl;
-            writeOBJ(nm0, half0Faces, ppPoints);
+            label newFaceI = faceMap[oldFaceI];
 
-            fileName nm1("match4_"+name()+"_half1_faces.obj");
-            Pout<< "cyclicPolyPatch::order : Writing half1"
-                << " faces to OBJ file " << nm1 << endl;
-            writeOBJ(nm1, half1Faces, pp.points());
+            const point& wantedAnchor = anchors0[newFaceI];
 
-            OFstream ccStr
+            rotation[newFaceI] = getRotation
             (
-                boundaryMesh().mesh().time().path()
-               /"match4_"+ name() + "_faceCentres.obj"
+                pp.points(),
+                pp[oldFaceI],
+                wantedAnchor,
+                tols[oldFaceI]
             );
-            Pout<< "cyclicPolyPatch::order : "
-                << "Dumping currently found cyclic match as lines between"
-                << " corresponding face centres to file " << ccStr.name()
-                << endl;
-
-            // Recalculate untransformed face centres
-            //pointField rawHalf0Ctrs =
-            //    calcFaceCentres(half0Faces, pp.points());
-            label vertI = 0;
 
-            forAll(half1Ctrs, i)
+            if (rotation[newFaceI] == -1)
             {
-                if (from1To0[i] != -1)
-                {
-                    // Write edge between c1 and c0
-                    //const point& c0 = rawHalf0Ctrs[from1To0[i]];
-                    const point& c0 = half0Ctrs[from1To0[i]];
-                    const point& c1 = half1Ctrs[i];
-                    writeOBJ(ccStr, c0, c1, vertI);
-                }
+                SeriousErrorIn
+                (
+                    "cyclicPolyPatch::order(const primitivePatch&"
+                    ", labelList&, labelList&) const"
+                )   << "in patch " << name()
+                    << " : "
+                    << "Cannot find point on face " << pp[oldFaceI]
+                    << " with vertices "
+                    << IndirectList<point>(pp.points(), pp[oldFaceI])()
+                    << " that matches point " << wantedAnchor
+                    << " when matching the halves of processor patch " << name()
+                    << "Continuing with incorrect face ordering from now on!"
+                    << endl;
+
+                return false;
             }
         }
-    }
 
+        ownerPatchPtr_.clear();
 
-    if (!matchedAll || debug)
-    {
-        // Dump halves
-        fileName nm0(name()+"_half0_faces.obj");
-        Pout<< "cyclicPolyPatch::order : Writing half0"
-            << " faces to OBJ file " << nm0 << endl;
-        writeOBJ(nm0, half0Faces, pp.points());
+        // Return false if no change neccesary, true otherwise.
 
-        fileName nm1(name()+"_half1_faces.obj");
-        Pout<< "cyclicPolyPatch::order : Writing half1"
-            << " faces to OBJ file " << nm1 << endl;
-        writeOBJ(nm1, half1Faces, pp.points());
-
-        OFstream ccStr
-        (
-            boundaryMesh().mesh().time().path()
-           /name() + "_faceCentres.obj"
-        );
-        Pout<< "cyclicPolyPatch::order : "
-            << "Dumping currently found cyclic match as lines between"
-            << " corresponding face centres to file " << ccStr.name()
-            << endl;
-
-        // Recalculate untransformed face centres
-        //pointField rawHalf0Ctrs = calcFaceCentres(half0Faces, pp.points());
-        label vertI = 0;
-
-        forAll(half1Ctrs, i)
+        forAll(faceMap, faceI)
         {
-            if (from1To0[i] != -1)
+            if (faceMap[faceI] != faceI || rotation[faceI] != 0)
             {
-                // Write edge between c1 and c0
-                //const point& c0 = rawHalf0Ctrs[from1To0[i]];
-                const point& c0 = half0Ctrs[from1To0[i]];
-                const point& c1 = half1Ctrs[i];
-                writeOBJ(ccStr, c0, c1, vertI);
+                return true;
             }
         }
-    }
-
 
-    if (!matchedAll)
-    {
-        SeriousErrorIn
-        (
-            "cyclicPolyPatch::order"
-            "(const primitivePatch&, labelList&, labelList&) const"
-        )   << "Patch:" << name() << " : "
-            << "Cannot match vectors to faces on both sides of patch" << endl
-            << "    Perhaps your faces do not match?"
-            << " The obj files written contain the current match." << endl
-            << "    Continuing with incorrect face ordering from now on!"
-            << endl;
-
-            return false;
-    }
-
-
-    // Set faceMap such that half0 faces get first and corresponding half1
-    // faces last.
-    matchAnchors
-    (
-        true,                   // report if anchor matching error
-        pp,
-        half0ToPatch,
-        anchors0,
-        half1ToPatch,
-        half1Faces,
-        from1To0,
-        tols,
-        faceMap,
-        rotation
-    );
-
-    // Return false if no change neccesary, true otherwise.
-
-    forAll(faceMap, faceI)
-    {
-        if (faceMap[faceI] != faceI || rotation[faceI] != 0)
-        {
-            return true;
-        }
+        return false;
     }
-
-    return false;
 }
 
 
 void Foam::cyclicPolyPatch::write(Ostream& os) const
 {
     polyPatch::write(os);
-    os.writeKeyword("featureCos") << featureCos_ << token::END_STATEMENT << nl;
+    os.writeKeyword("neighbourPatch") << neighbPatchName_
+        << token::END_STATEMENT << nl;
     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 f8ae312f20e08a1373c2d76a6b3922ea1ea0822f..324a9f90d6e0d3ef5171bda279179655b601bfef 100644
--- a/src/OpenFOAM/meshes/polyMesh/polyPatches/constraint/cyclic/cyclicPolyPatch.H
+++ b/src/OpenFOAM/meshes/polyMesh/polyPatches/constraint/cyclic/cyclicPolyPatch.H
@@ -29,11 +29,10 @@ Description
 
     Note: morph patch face ordering uses geometric matching so with the
     following restrictions:
-        -halves should be flat planes.
+        -coupled patches should be flat planes.
         -no rotation in patch plane
 
-    Uses a featureCos to find the two halves (or should be fully
-    disconnected). Uses coupledPolyPatch::calcFaceTol to calculate
+    Uses coupledPolyPatch::calcFaceTol to calculate
     tolerance per face which might need tweaking.
 
     Switch on 'cyclicPolyPatch' debug flag to write .obj files to show
@@ -48,10 +47,9 @@ SourceFiles
 #define cyclicPolyPatch_H
 
 #include "coupledPolyPatch.H"
-#include "SubField.H"
-#include "FixedList.H"
 #include "edgeList.H"
-#include "transform.H"
+#include "polyBoundaryMesh.H"
+#include "diagTensorField.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -82,18 +80,11 @@ private:
 
     // Private data
 
-        //- List of edges formed from connected points. e[0] is the point on
-        //  the first half of the patch, e[1] the corresponding point on the
-        //  second half.
-        mutable edgeList* coupledPointsPtr_;
-
-        //- List of connected edges. e[0] is the edge on the first half of the
-        //  patch, e[1] the corresponding edge on the second half.
-        mutable edgeList* coupledEdgesPtr_;
+        //- Name of other half
+        const word neighbPatchName_;
 
-        //- Morph:angle between normals of neighbouring faces.
-        //  Used to split cyclic into halves.
-        scalar featureCos_;
+        //- Index of other half
+        mutable label neighbPatchID_;
 
         //- Type of transformation - rotational or translational
         transformType transform_;
@@ -112,60 +103,50 @@ private:
             vector separationVector_;
 
 
+        //- List of edges formed from connected points. e[0] is the point on
+        //  the first half of the patch, e[1] the corresponding point on the
+        //  second half.
+        mutable edgeList* coupledPointsPtr_;
+
+        //- List of connected edges. e[0] is the edge on the first half of the
+        //  patch, e[1] the corresponding edge on the second half.
+        mutable edgeList* coupledEdgesPtr_;
+
+        //- Temporary storage of owner side patch during ordering.
+        mutable autoPtr<primitivePatch> ownerPatchPtr_;
+
+
     // Private Member Functions
 
         //- Find amongst selected faces the one with the largest area
         static label findMaxArea(const pointField&, const faceList&);
 
+        void calcTransforms
+        (
+            const primitivePatch& half0,
+            const UList<point>& half0Ctrs,
+            const UList<point>& half0Areas,
+            const UList<point>& half1Ctrs,
+            const UList<point>& half1Areas
+        );
 
         // Face ordering
 
-            //- Find the two parts of the faces of pp using feature edges.
-            //  Returns true if successfull.
-            bool getGeometricHalves
-            (
-                const primitivePatch&,
-                labelList&,
-                labelList&
-            ) const;
-
             //- Calculate geometric factors of the two halves.
             void getCentresAndAnchors
             (
-                const primitivePatch&,
-                const faceList& half0Faces,
-                const faceList& half1Faces,
+                const primitivePatch& pp0,
+                const primitivePatch& pp1,
 
-                pointField& ppPoints,
                 pointField& half0Ctrs,
                 pointField& half1Ctrs,
                 pointField& anchors0,
                 scalarField& tols
             ) const;
 
-            //- Given matched faces matches the anchor point. Sets faceMap,
-            //  rotation. Returns true if all matched.
-            bool matchAnchors
-            (
-                const bool report,
-                const primitivePatch&,
-                const labelList&,
-                const pointField&,
-                const labelList&,
-                const faceList&,
-                const labelList&,
-                const scalarField&,
-
-                labelList& faceMap,
-                labelList& rotation
-            ) const;
-
             //- For rotational cases, try to find a unique face on each side
             //  of the cyclic.
-            label getConsistentRotationFace
-            (
-                const pointField& faceCentres
-            ) const;
+            label getConsistentRotationFace(const pointField&) const;
 
 
 protected:
@@ -178,9 +159,30 @@ protected:
         //- Initialise the calculation of the patch geometry
         virtual void initGeometry(PstreamBuffers&);
 
+        //- Initialise the calculation of the patch geometry
+        virtual void initGeometry
+        (
+            const primitivePatch& referPatch,
+            UList<point>& nbrCtrs,
+            UList<point>& nbrAreas,
+            UList<point>& nbrCc
+        );
+
         //- Calculate the patch geometry
         virtual void calcGeometry(PstreamBuffers&);
 
+        //- Calculate the patch geometry
+        virtual void calcGeometry
+        (
+            const primitivePatch& referPatch,
+            const UList<point>& thisCtrs,
+            const UList<point>& thisAreas,
+            const UList<point>& thisCc,
+            const UList<point>& nbrCtrs,
+            const UList<point>& nbrAreas,
+            const UList<point>& nbrCc
+        );
+
         //- Initialise the patches for moving points
         virtual void initMovePoints(PstreamBuffers&, const pointField&);
 
@@ -231,7 +233,8 @@ public:
             const polyBoundaryMesh& bm,
             const label index,
             const label newSize,
-            const label newStart
+            const label newStart,
+            const word& neighbPatchName
         );
 
         //- Construct given the original patch and a map
@@ -262,7 +265,15 @@ public:
         {
             return autoPtr<polyPatch>
             (
-                new cyclicPolyPatch(*this, bm, index, newSize, newStart)
+                new cyclicPolyPatch
+                (
+                    *this,
+                    bm,
+                    index,
+                    newSize,
+                    newStart,
+                    neighbPatchName_
+                )
             );
         }
 
@@ -289,103 +300,107 @@ public:
 
     // Member Functions
 
-        //- Return connected points (in patch local point indexing). Demand
-        //  driven calculation. Does primitivePatch::clearOut after calculation!
-        const edgeList& coupledPoints() const;
-
-        //- Return connected edges (in patch local edge indexing). Demand
-        //  driven calculation. Does primitivePatch::clearOut after calculation!
-        const edgeList& coupledEdges() const;
-
-
-
-        // Transformation
+        const word& neighbPatchName() const
+        {
+            return neighbPatchName_;
+        }
 
-            vector separation(const label facei) const
+        //- Neighbour patchID.
+        virtual label neighbPatchID() const
+        {
+            if (neighbPatchID_ == -1)
             {
-                if (facei < size()/2)
+                neighbPatchID_ = this->boundaryMesh().findPatchID
+                (
+                    neighbPatchName_
+                );
+                if (neighbPatchID_ == -1)
                 {
-                    return coupledPolyPatch::separation()[0];
-                }
-                else
-                {
-                    return -coupledPolyPatch::separation()[0];
+                    FatalErrorIn("cyclicPolyPatch::neighbPatchID() const")
+                        << "Illegal neighbourPatch name " << neighbPatchName_
+                        << endl << "Valid patch names are "
+                        << this->boundaryMesh().names()
+                        << exit(FatalError);
                 }
             }
+            return neighbPatchID_;
+        }
 
-            const tensor& transformT(const label facei) const
-            {
-                if (facei < size()/2)
-                {
-                    return reverseT()[0];
-                }
-                else
-                {
-                    return forwardT()[0];
-                }
-            }
+        virtual bool owner() const
+        {
+            return index() < neighbPatchID();
+        }
 
-            template<class T>
-            T transform(const T& t, const label facei) const
-            {
-                if (parallel())
-                {
-                    return t;
-                }
-                else
-                {
-                    return Foam::transform(transformT(facei), t);
-                }
-            }
+        virtual bool neighbour() const
+        {
+            return !owner();
+        }
 
-            label transformLocalFace(const label facei) const
-            {
-                if (facei < size()/2)
-                {
-                    return facei + size()/2;
-                }
-                else
-                {
-                    return facei - size()/2;
-                }
-            }
+        const cyclicPolyPatch& neighbPatch() const
+        {
+            const polyPatch& pp = this->boundaryMesh()[neighbPatchID()];
+            return refCast<const cyclicPolyPatch>(pp);
+        }
 
-            label transformGlobalFace(const label facei) const
-            {
-                if (facei - start() < size()/2)
-                {
-                    return facei + size()/2;
-                }
-                else
-                {
-                    return facei - size()/2;
-                }
-            }
+        //- Return connected points (from patch local to neighbour patch local)
+        //  Demand driven calculation. Does primitivePatch::clearOut after
+        //  calculation!
+        const edgeList& coupledPoints() const;
 
-            //- Type of transform
-            transformType transform() const
-            {
-                return transform_;
-            }
+        //- Return connected edges (from patch local to neighbour patch local).
+        //  Demand driven calculation. Does primitivePatch::clearOut after
+        //  calculation!
+        const edgeList& coupledEdges() const;
 
-            //- Axis of rotation for rotational cyclics
-            const vector& rotationAxis() const
-            {
-                return rotationAxis_;
-            }
+        //- Transform a patch-based position from other side to this side
+        virtual void transformPosition(pointField& l) const;
 
-            //- point on axis of rotation for rotational cyclics
-            const point& rotationCentre() const
+
+        // Transformation
+
+        label transformGlobalFace(const label facei) const
+        {
+            label offset = facei-start();
+            label neighbStart = neighbPatch().start();
+
+            if (offset >= 0 && offset < size())
             {
-                return rotationCentre_;
+                return neighbStart+offset;
             }
-
-            //- Translation vector for translational cyclics
-            const vector& separationVector() const
+            else
             {
-                return separationVector_;
+                FatalErrorIn
+                (
+                    "cyclicPolyPatch::transformGlobalFace(const label) const"
+                )   << "Face " << facei << " not in patch " << name()
+                    << exit(FatalError);
+                return -1;
             }
+        }
 
+        //- Type of transform
+        transformType transform() const
+        {
+            return transform_;
+        }
+
+        //- Axis of rotation for rotational cyclics
+        const vector& rotationAxis() const
+        {
+            return rotationAxis_;
+        }
+
+        //- point on axis of rotation for rotational cyclics
+        const point& rotationCentre() const
+        {
+            return rotationCentre_;
+        }
+
+        //- Translation vector for translational cyclics
+        const vector& separationVector() const
+        {
+            return separationVector_;
+        }
 
 
         //- Initialize ordering for primitivePatch. Does not
diff --git a/src/OpenFOAM/meshes/polyMesh/polyPatches/constraint/processor/processorPolyPatch.C b/src/OpenFOAM/meshes/polyMesh/polyPatches/constraint/processor/processorPolyPatch.C
index f2b5c4b09525433c1e425f740033c61598866147..277a274b91087d2396e4f2d5033571d6c707e569 100644
--- a/src/OpenFOAM/meshes/polyMesh/polyPatches/constraint/processor/processorPolyPatch.C
+++ b/src/OpenFOAM/meshes/polyMesh/polyPatches/constraint/processor/processorPolyPatch.C
@@ -62,9 +62,9 @@ Foam::processorPolyPatch::processorPolyPatch
     neighbProcNo_(neighbProcNo),
     neighbFaceCentres_(),
     neighbFaceAreas_(),
-    neighbFaceCellCentres_(),
-    neighbPointsPtr_(NULL),
-    neighbEdgesPtr_(NULL)
+    neighbFaceCellCentres_()
+//    neighbPointsPtr_(NULL),
+//    neighbEdgesPtr_(NULL)
 {}
 
 
@@ -81,9 +81,9 @@ Foam::processorPolyPatch::processorPolyPatch
     neighbProcNo_(readLabel(dict.lookup("neighbProcNo"))),
     neighbFaceCentres_(),
     neighbFaceAreas_(),
-    neighbFaceCellCentres_(),
-    neighbPointsPtr_(NULL),
-    neighbEdgesPtr_(NULL)
+    neighbFaceCellCentres_()
+//    neighbPointsPtr_(NULL),
+//    neighbEdgesPtr_(NULL)
 {}
 
 
@@ -98,9 +98,9 @@ Foam::processorPolyPatch::processorPolyPatch
     neighbProcNo_(pp.neighbProcNo_),
     neighbFaceCentres_(),
     neighbFaceAreas_(),
-    neighbFaceCellCentres_(),
-    neighbPointsPtr_(NULL),
-    neighbEdgesPtr_(NULL)
+    neighbFaceCellCentres_()
+//    neighbPointsPtr_(NULL),
+//    neighbEdgesPtr_(NULL)
 {}
 
 
@@ -118,9 +118,9 @@ Foam::processorPolyPatch::processorPolyPatch
     neighbProcNo_(pp.neighbProcNo_),
     neighbFaceCentres_(),
     neighbFaceAreas_(),
-    neighbFaceCellCentres_(),
-    neighbPointsPtr_(NULL),
-    neighbEdgesPtr_(NULL)
+    neighbFaceCellCentres_()
+//    neighbPointsPtr_(NULL),
+//    neighbEdgesPtr_(NULL)
 {}
 
 
@@ -129,7 +129,7 @@ Foam::processorPolyPatch::processorPolyPatch
     const processorPolyPatch& pp,
     const polyBoundaryMesh& bm,
     const label index,
-     const unallocLabelList& mapAddressing,
+    const unallocLabelList& mapAddressing,
     const label newStart
 )
 :
@@ -138,9 +138,9 @@ Foam::processorPolyPatch::processorPolyPatch
     neighbProcNo_(pp.neighbProcNo_),
     neighbFaceCentres_(),
     neighbFaceAreas_(),
-    neighbFaceCellCentres_(),
-    neighbPointsPtr_(NULL),
-    neighbEdgesPtr_(NULL)
+    neighbFaceCellCentres_()
+//    neighbPointsPtr_(NULL),
+//    neighbEdgesPtr_(NULL)
 {}
 
 
@@ -148,8 +148,8 @@ Foam::processorPolyPatch::processorPolyPatch
 
 Foam::processorPolyPatch::~processorPolyPatch()
 {
-    deleteDemandDrivenData(neighbPointsPtr_);
-    deleteDemandDrivenData(neighbEdgesPtr_);
+    neighbPointsPtr_.clear();
+    neighbEdgesPtr_.clear();
 }
 
 
@@ -157,6 +157,7 @@ Foam::processorPolyPatch::~processorPolyPatch()
 
 void Foam::processorPolyPatch::initGeometry(PstreamBuffers& pBufs)
 {
+//Pout<< "**processorPolyPatch::initGeometry()" << endl;
     if (Pstream::parRun())
     {
         UOPstream toNeighbProc(neighbProcNo(), pBufs);
@@ -171,6 +172,7 @@ void Foam::processorPolyPatch::initGeometry(PstreamBuffers& pBufs)
 
 void Foam::processorPolyPatch::calcGeometry(PstreamBuffers& pBufs)
 {
+//Pout<< "processorPolyPatch::calcGeometry() for " << name() << endl;
     if (Pstream::parRun())
     {
         {
@@ -182,6 +184,9 @@ void Foam::processorPolyPatch::calcGeometry(PstreamBuffers& pBufs)
                 >> neighbFaceCellCentres_;
         }
 
+//Pout<< "processorPolyPatch::calcGeometry() : received data for "
+//    << neighbFaceCentres_.size() << " faces." << endl;
+
         // My normals
         vectorField faceNormals(size());
 
@@ -247,6 +252,9 @@ void Foam::processorPolyPatch::calcGeometry(PstreamBuffers& pBufs)
             nbrFaceNormals,
             calcFaceTol(*this, points(), faceCentres())
         );
+//Pout<< "**neighbFaceCentres_:" << neighbFaceCentres_ << endl;
+//Pout<< "**neighbFaceAreas_:" << neighbFaceAreas_ << endl;
+//Pout<< "**neighbFaceCellCentres_:" << neighbFaceCellCentres_ << endl;
     }
 }
 
@@ -276,9 +284,6 @@ void Foam::processorPolyPatch::initUpdateMesh(PstreamBuffers& pBufs)
 {
     polyPatch::initUpdateMesh(pBufs);
 
-    deleteDemandDrivenData(neighbPointsPtr_);
-    deleteDemandDrivenData(neighbEdgesPtr_);
-
     if (Pstream::parRun())
     {
         // Express all points as patch face and index in face.
@@ -327,6 +332,9 @@ void Foam::processorPolyPatch::updateMesh(PstreamBuffers& pBufs)
     // For completeness
     polyPatch::updateMesh(pBufs);
 
+    neighbPointsPtr_.clear();
+    neighbEdgesPtr_.clear();
+
     if (Pstream::parRun())
     {
         labelList nbrPointFace;
@@ -352,8 +360,8 @@ void Foam::processorPolyPatch::updateMesh(PstreamBuffers& pBufs)
         // Convert points.
         // ~~~~~~~~~~~~~~~
 
-        neighbPointsPtr_ = new labelList(nPoints(), -1);
-        labelList& neighbPoints = *neighbPointsPtr_;
+        neighbPointsPtr_.reset(new labelList(nPoints(), -1));
+        labelList& neighbPoints = neighbPointsPtr_();
 
         forAll(nbrPointFace, nbrPointI)
         {
@@ -386,8 +394,8 @@ void Foam::processorPolyPatch::updateMesh(PstreamBuffers& pBufs)
         // Convert edges.
         // ~~~~~~~~~~~~~~
 
-        neighbEdgesPtr_ = new labelList(nEdges(), -1);
-        labelList& neighbEdges = *neighbEdgesPtr_;
+        neighbEdgesPtr_.reset(new labelList(nEdges(), -1));
+        labelList& neighbEdges = neighbEdgesPtr_();
 
         forAll(nbrEdgeFace, nbrEdgeI)
         {
@@ -425,25 +433,25 @@ void Foam::processorPolyPatch::updateMesh(PstreamBuffers& pBufs)
 
 const Foam::labelList& Foam::processorPolyPatch::neighbPoints() const
 {
-    if (!neighbPointsPtr_)
+    if (!neighbPointsPtr_.valid())
     {
         FatalErrorIn("processorPolyPatch::neighbPoints() const")
             << "No extended addressing calculated for patch " << name()
             << abort(FatalError);
     }
-    return *neighbPointsPtr_;
+    return neighbPointsPtr_();
 }
 
 
 const Foam::labelList& Foam::processorPolyPatch::neighbEdges() const
 {
-    if (!neighbEdgesPtr_)
+    if (!neighbEdgesPtr_.valid())
     {
         FatalErrorIn("processorPolyPatch::neighbEdges() const")
             << "No extended addressing calculated for patch " << name()
             << abort(FatalError);
     }
-    return *neighbEdgesPtr_;
+    return neighbEdgesPtr_();
 }
 
 
@@ -470,7 +478,7 @@ void Foam::processorPolyPatch::initOrder
         writeOBJ(nm, pp, pp.points());
 
         // Calculate my face centres
-        pointField ctrs(calcFaceCentres(pp, pp.points()));
+        const pointField& fc = pp.faceCentres();
 
         OFstream localStr
         (
@@ -478,26 +486,22 @@ void Foam::processorPolyPatch::initOrder
            /name() + "_localFaceCentres.obj"
         );
         Pout<< "processorPolyPatch::order : "
-            << "Dumping " << ctrs.size()
+            << "Dumping " << fc.size()
             << " local faceCentres to " << localStr.name() << endl;
 
-        forAll(ctrs, faceI)
+        forAll(fc, faceI)
         {
-            writeOBJ(localStr, ctrs[faceI]);
+            writeOBJ(localStr, fc[faceI]);
         }
     }
 
-    const bool isMaster = Pstream::myProcNo() < neighbProcNo();
-
-    if (isMaster)
+    if (owner())
     {
-        pointField ctrs(calcFaceCentres(pp, pp.points()));
-
         pointField anchors(getAnchorPoints(pp, pp.points()));
 
         // Now send all info over to the neighbour
         UOPstream toNeighbour(neighbProcNo(), pBufs);
-        toNeighbour << ctrs << anchors;
+        toNeighbour << pp.faceCentres() << anchors;
     }
 }
 
@@ -514,6 +518,8 @@ bool Foam::processorPolyPatch::order
     labelList& rotation
 ) const
 {
+    // Note: we only get the faces that originate from internal faces.
+
     if (!Pstream::parRun())
     {
         return false;
@@ -525,9 +531,7 @@ bool Foam::processorPolyPatch::order
     rotation.setSize(pp.size());
     rotation = 0;
 
-    const bool isMaster = Pstream::myProcNo() < neighbProcNo();
-
-    if (isMaster)
+    if (owner())
     {
         // Do nothing (i.e. identical mapping, zero rotation).
         // See comment at top.
@@ -549,11 +553,8 @@ bool Foam::processorPolyPatch::order
             fromNeighbour >> masterCtrs >> masterAnchors;
         }
 
-        // Calculate my face centres
-        pointField ctrs(calcFaceCentres(pp, pp.points()));
-
         // Calculate typical distance from face centre
-        scalarField tols(calcFaceTol(pp, pp.points(), ctrs));
+        scalarField tols(calcFaceTol(pp, pp.points(), pp.faceCentres()));
 
         if (debug || masterCtrs.size() != pp.size())
         {
@@ -591,84 +592,14 @@ bool Foam::processorPolyPatch::order
         // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
         // 1. Try existing ordering and transformation
-        bool matchedAll = false;
-
-        if
-        (
-            separated()
-         && (separation().size() == 1 || separation().size() == pp.size())
-        )
-        {
-            vectorField transformedCtrs;
-
-            const vectorField& v = separation();
-
-            if (v.size() == 1)
-            {
-                transformedCtrs = masterCtrs-v[0];
-            }
-            else
-            {
-                transformedCtrs = masterCtrs-v;
-            }
-            matchedAll = matchPoints
-            (
-                ctrs,
-                transformedCtrs,
-                tols,
-                true,
-                faceMap
-            );
-
-            if (matchedAll)
-            {
-                // Use transformed centers from now on
-                masterCtrs = transformedCtrs;
-
-                // Transform anchors
-                if (v.size() == 1)
-                {
-                    masterAnchors -= v[0];
-                }
-                else
-                {
-                    masterAnchors -= v;
-                }
-            }
-        }
-        else if
+        bool matchedAll = matchPoints
         (
-           !parallel()
-         && (forwardT().size() == 1 || forwardT().size() == pp.size())
-        )
-        {
-            vectorField transformedCtrs = masterCtrs;
-            transformList(forwardT(), transformedCtrs);
-            matchedAll = matchPoints
-            (
-                ctrs,
-                transformedCtrs,
-                tols,
-                true,
-                faceMap
-            );
-
-            if (matchedAll)
-            {
-                // Use transformed centers from now on
-                masterCtrs = transformedCtrs;
-
-                // Transform anchors
-                transformList(forwardT(), masterAnchors);
-            }
-        }
-
-
-        // 2. Try zero separation automatic matching
-        if (!matchedAll)
-        {
-            matchedAll = matchPoints(ctrs, masterCtrs, tols, true, faceMap);
-        }
+            pp.faceCentres(),
+            masterCtrs,
+            tols,
+            true,
+            faceMap
+        );
 
         if (!matchedAll || debug)
         {
@@ -695,14 +626,14 @@ bool Foam::processorPolyPatch::order
 
             label vertI = 0;
 
-            forAll(ctrs, faceI)
+            forAll(pp.faceCentres(), faceI)
             {
                 label masterFaceI = faceMap[faceI];
 
                 if (masterFaceI != -1)
                 {
                     const point& c0 = masterCtrs[masterFaceI];
-                    const point& c1 = ctrs[faceI];
+                    const point& c1 = pp.faceCentres()[faceI];
                     writeOBJ(ccStr, c0, c1, vertI);
                 }
             }
@@ -718,7 +649,7 @@ bool Foam::processorPolyPatch::order
                 << "Cannot match vectors to faces on both sides of patch"
                 << endl
                 << "    masterCtrs[0]:" << masterCtrs[0] << endl
-                << "    ctrs[0]:" << ctrs[0] << endl
+                << "    ctrs[0]:" << pp.faceCentres()[0] << endl
                 << "    Please check your topology changes or maybe you have"
                 << " multiple separated (from cyclics) processor patches"
                 << endl
diff --git a/src/OpenFOAM/meshes/polyMesh/polyPatches/constraint/processor/processorPolyPatch.H b/src/OpenFOAM/meshes/polyMesh/polyPatches/constraint/processor/processorPolyPatch.H
index 8b168b9806ae23444d3c907afea901c30ac7cd86..0af1cfaa17f334f28006754162207e7449cb7ede 100644
--- a/src/OpenFOAM/meshes/polyMesh/polyPatches/constraint/processor/processorPolyPatch.H
+++ b/src/OpenFOAM/meshes/polyMesh/polyPatches/constraint/processor/processorPolyPatch.H
@@ -40,6 +40,8 @@ SourceFiles
 #define processorPolyPatch_H
 
 #include "coupledPolyPatch.H"
+#include "polyBoundaryMesh.H"
+#include "faceListFwd.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -70,23 +72,11 @@ class processorPolyPatch
 
         //- Corresponding neighbouring local point label for every local point
         //  (so localPoints()[i] == neighb.localPoints()[neighbPoints_[i]])
-        mutable labelList* neighbPointsPtr_;
+        mutable autoPtr<labelList> neighbPointsPtr_;
 
         //- Corresponding neighbouring local edge label for every local edge
         //  (so edges()[i] == neighb.edges()[neighbEdges_[i]])
-        mutable labelList* neighbEdgesPtr_;
-
-
-
-    // Private static data
-
-        //- Whether to use geometric or topological matching
-        static bool geometricMatch_;
-
-        //- Relative tolerance (for geometric matching only). Is factor of
-        //  maximum edge length per face.
-        static scalar matchTol_;
-
+        mutable autoPtr<labelList> neighbEdgesPtr_;
 
 protected:
 
@@ -98,6 +88,22 @@ protected:
         //- Calculate the patch geometry
         void calcGeometry(PstreamBuffers&);
 
+        //- Calculate the patch geometry with externally
+        //  provided geometry
+        virtual void calcGeometry
+        (
+            const primitivePatch& referPatch,
+            const UList<point>& thisCtrs,
+            const UList<point>& thisAreas,
+            const UList<point>& thisCc,
+            const UList<point>& nbrCtrs,
+            const UList<point>& nbrAreas,
+            const UList<point>& nbrCc
+        )
+        {
+            notImplemented("processorPolyPatch::calcGeometry(..)");
+        }
+
         //- Initialise the patches for moving points
         void initMovePoints(PstreamBuffers&, const pointField&);
 
@@ -236,7 +242,7 @@ public:
         }
 
         //- Does the processor own the patch ?
-        bool owner() const
+        virtual bool owner() const
         {
             return (myProcNo_ < neighbProcNo_);
         }
@@ -265,16 +271,21 @@ public:
             return neighbFaceCellCentres_;
         }
 
-        //- Return neighbour point labels. This is for my local point (-1 or)
-        //  the corresponding local point on the other side. It is -1 if
-        //  there are multiple corresponding points on this or the other side
-        //  (can happen for cyclics being converted into proc patches)
+        //- Return neighbour point labels. WIP.
         const labelList& neighbPoints() const;
 
-        //- Return neighbour edge labels. This is for my local edge (-1 or) the
-        //  corresponding local edge on the other side. See above for -1 cause.
+        //- Return neighbour edge labels. WIP.
         const labelList& neighbEdges() const;
 
+        //- Return message tag to use for communication
+        virtual int tag() const
+        {
+            return Pstream::msgType();
+        }
+
+        //- Transform a patch-based position from other side to this side
+        virtual void transformPosition(pointField& l) const
+        {}
 
         //- Initialize ordering for primitivePatch. Does not
         //  refer to *this (except for name() and type() etc.)
diff --git a/src/OpenFOAM/meshes/polyMesh/polyPatches/constraint/processor/processorPolyPatchTemplates.C b/src/OpenFOAM/meshes/polyMesh/polyPatches/constraint/processor/processorPolyPatchTemplates.C
new file mode 100644
index 0000000000000000000000000000000000000000..391f4ecbf64fe02d62d1cfa55cb0978a3c42d0cb
--- /dev/null
+++ b/src/OpenFOAM/meshes/polyMesh/polyPatches/constraint/processor/processorPolyPatchTemplates.C
@@ -0,0 +1,60 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 1991-2008 OpenCFD Ltd.
+     \\/     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 2 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, write to the Free Software Foundation,
+    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+\*---------------------------------------------------------------------------*/
+
+#include "processorPolyPatch.H"
+#include "transformField.H"
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+template<class T>
+void Foam::processorPolyPatch::transform(Field<T>& l) const
+{
+    if (l.size() != size())
+    {
+        FatalErrorIn("processorPolyPatch::transform(Field<T>&) const")
+            << "Size of field " << l.size() << " differs from patch size "
+            << size() << abort(FatalError);
+    }
+
+    forAll(patchIDs_, subI)
+    {
+        label patchI = patchIDs_[subI];
+
+        if (patchI != -1)
+        {
+            // Get field on patch
+            typename Field<T>::subField subFld(subSlice(l, subI));
+
+            refCast<const coupledPolyPatch>
+            (
+                boundaryMesh()[patchI]
+            ).transform(subFld);
+        }
+    }
+}
+
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/meshes/polyMesh/polyPatches/constraint/processorCyclic/processorCyclicPolyPatch.C b/src/OpenFOAM/meshes/polyMesh/polyPatches/constraint/processorCyclic/processorCyclicPolyPatch.C
new file mode 100644
index 0000000000000000000000000000000000000000..df93919fd21bb5c2da94bb35f929bb1d62458d75
--- /dev/null
+++ b/src/OpenFOAM/meshes/polyMesh/polyPatches/constraint/processorCyclic/processorCyclicPolyPatch.C
@@ -0,0 +1,246 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
+     \\/     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 2 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, write to the Free Software Foundation,
+    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+\*---------------------------------------------------------------------------*/
+
+#include "processorCyclicPolyPatch.H"
+#include "addToRunTimeSelectionTable.H"
+#include "SubField.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+    defineTypeNameAndDebug(processorCyclicPolyPatch, 0);
+    addToRunTimeSelectionTable(polyPatch, processorCyclicPolyPatch, dictionary);
+}
+
+
+// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+Foam::processorCyclicPolyPatch::processorCyclicPolyPatch
+(
+    const word& name,
+    const label size,
+    const label start,
+    const label index,
+    const polyBoundaryMesh& bm,
+    const int myProcNo,
+    const int neighbProcNo,
+    const word& referPatchName
+)
+:
+    processorPolyPatch(name, size, start, index, bm, myProcNo, neighbProcNo),
+    tag_(UPstream::allocateTag()),
+    referPatchName_(referPatchName),
+    referPatchID_(-1)
+{}
+
+
+Foam::processorCyclicPolyPatch::processorCyclicPolyPatch
+(
+    const word& name,
+    const dictionary& dict,
+    const label index,
+    const polyBoundaryMesh& bm
+)
+:
+    processorPolyPatch(name, dict, index, bm),
+    tag_(UPstream::allocateTag()),
+    referPatchName_(dict.lookup("referPatch")),
+    referPatchID_(-1)
+{}
+
+
+Foam::processorCyclicPolyPatch::processorCyclicPolyPatch
+(
+    const processorCyclicPolyPatch& pp,
+    const polyBoundaryMesh& bm
+)
+:
+    processorPolyPatch(pp, bm),
+    tag_(pp.tag_),
+    referPatchName_(pp.referPatchName()),
+    referPatchID_(-1)
+{}
+
+
+Foam::processorCyclicPolyPatch::processorCyclicPolyPatch
+(
+    const processorCyclicPolyPatch& pp,
+    const polyBoundaryMesh& bm,
+    const label index,
+    const label newSize,
+    const label newStart,
+    const word& referPatchName
+)
+:
+    processorPolyPatch(pp, bm, index, newSize, newStart),
+    tag_(pp.tag_),
+    referPatchName_(referPatchName),
+    referPatchID_(-1)
+{}
+
+
+Foam::processorCyclicPolyPatch::processorCyclicPolyPatch
+(
+    const processorCyclicPolyPatch& pp,
+    const polyBoundaryMesh& bm,
+    const label index,
+    const unallocLabelList& mapAddressing,
+    const label newStart
+)
+:
+    processorPolyPatch(pp, bm, index, mapAddressing, newStart),
+    tag_(pp.tag_),
+    referPatchName_(pp.referPatchName()),
+    referPatchID_(-1)
+{}
+
+
+// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
+
+Foam::processorCyclicPolyPatch::~processorCyclicPolyPatch()
+{
+    UPstream::freeTag(tag_);
+}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+
+void Foam::processorCyclicPolyPatch::initGeometry(PstreamBuffers& pBufs)
+{
+    // Send over processorPolyPatch data
+    processorPolyPatch::initGeometry(pBufs);
+}
+
+
+void Foam::processorCyclicPolyPatch::calcGeometry(PstreamBuffers& pBufs)
+{
+    // Receive and initialise processorPolyPatch data
+    processorPolyPatch::calcGeometry(pBufs);
+
+    if (Pstream::parRun())
+    {
+
+        // Where do we store the calculated transformation?
+        // - on the processor patch?
+        // - on the underlying cyclic patch?
+        // - or do we not auto-calculate the transformation but
+        //   have option of reading it.
+
+        // Update underlying cyclic
+        coupledPolyPatch& pp = const_cast<coupledPolyPatch&>(referPatch());
+
+        Pout<< "updating geometry on refered patch:" << pp.name() << endl;
+
+        pp.calcGeometry
+        (
+            *this,
+            faceCentres(),
+            faceAreas(),
+            faceCellCentres(),
+            neighbFaceCentres(),
+            neighbFaceAreas(),
+            neighbFaceCellCentres()
+        );
+    }
+}
+
+
+void Foam::processorCyclicPolyPatch::initMovePoints
+(
+    PstreamBuffers& pBufs,
+    const pointField& p
+)
+{
+    // Recalculate geometry
+    initGeometry(pBufs);
+}
+
+
+void Foam::processorCyclicPolyPatch::movePoints
+(
+    PstreamBuffers& pBufs,
+    const pointField&
+)
+{
+    calcGeometry(pBufs);
+}
+
+
+void Foam::processorCyclicPolyPatch::initUpdateMesh(PstreamBuffers& pBufs)
+{
+    processorPolyPatch::initUpdateMesh(pBufs);
+}
+
+
+void Foam::processorCyclicPolyPatch::updateMesh(PstreamBuffers& pBufs)
+{
+     referPatchID_ = -1;
+     processorPolyPatch::updateMesh(pBufs);
+}
+
+
+void Foam::processorCyclicPolyPatch::initOrder
+(
+    PstreamBuffers& pBufs,
+    const primitivePatch& pp
+) const
+{
+    // For now use the same algorithm as processorPolyPatch
+    processorPolyPatch::initOrder(pBufs, pp);
+}
+
+
+// Return new ordering. Ordering is -faceMap: for every face index
+// the new face -rotation:for every new face the clockwise shift
+// of the original face. Return false if nothing changes (faceMap
+// is identity, rotation is 0)
+bool Foam::processorCyclicPolyPatch::order
+(
+    PstreamBuffers& pBufs,
+    const primitivePatch& pp,
+    labelList& faceMap,
+    labelList& rotation
+) const
+{
+    // For now use the same algorithm as processorPolyPatch
+    return processorPolyPatch::order(pBufs, pp, faceMap, rotation);
+}
+
+
+void Foam::processorCyclicPolyPatch::write(Ostream& os) const
+{
+    processorPolyPatch::write(os);
+    os.writeKeyword("referPatch") << referPatchName_
+        << token::END_STATEMENT << nl;
+}
+
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/meshes/polyMesh/polyPatches/constraint/processorCyclic/processorCyclicPolyPatch.H b/src/OpenFOAM/meshes/polyMesh/polyPatches/constraint/processorCyclic/processorCyclicPolyPatch.H
new file mode 100644
index 0000000000000000000000000000000000000000..b0ffa28086342d5e5506fa21510c6d0fc67439a7
--- /dev/null
+++ b/src/OpenFOAM/meshes/polyMesh/polyPatches/constraint/processorCyclic/processorCyclicPolyPatch.H
@@ -0,0 +1,394 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
+     \\/     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 2 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, write to the Free Software Foundation,
+    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+Class
+    Foam::processorCyclicPolyPatch
+
+Description
+    Neighbour processor patch.
+
+    Note: morph patch face ordering is geometric.
+
+SourceFiles
+    processorCyclicPolyPatch.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef processorCyclicPolyPatch_H
+#define processorCyclicPolyPatch_H
+
+#include "processorPolyPatch.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+                           Class processorCyclicPolyPatch Declaration
+\*---------------------------------------------------------------------------*/
+
+class processorCyclicPolyPatch
+:
+    public processorPolyPatch
+{
+    // Private data
+
+        //- Message tag to use for communication
+        const int tag_;
+
+        //- Name of originating patch
+        const word referPatchName_;
+
+        //- Index of originating patch
+        mutable label referPatchID_;
+
+    // Private member functions
+
+
+protected:
+
+    // Protected Member functions
+
+        //- Initialise the calculation of the patch geometry
+        void initGeometry(PstreamBuffers&);
+
+//        //- Initialise the calculation of the patch geometry with externally
+//        //  provided geometry
+//        virtual void initGeometry
+//        (
+//            const primitivePatch& referPatch,
+//            UList<point>&,
+//            UList<point>&,
+//            UList<point>&
+//        )
+//        {
+//            notImplemented("processorCyclicPolyPatch::initGeometry(..)");
+//        }
+
+        //- Calculate the patch geometry
+        void calcGeometry(PstreamBuffers&);
+
+        //- Calculate the patch geometry with externally
+        //  provided geometry
+        virtual void calcGeometry
+        (
+            const primitivePatch& referPatch,
+            const UList<point>& thisCtrs,
+            const UList<point>& thisAreas,
+            const UList<point>& thisCc,
+            const UList<point>& nbrCtrs,
+            const UList<point>& nbrAreas,
+            const UList<point>& nbrCc
+        )
+        {
+            notImplemented("processorCyclicPolyPatch::calcGeometry(..)");
+        }
+
+        //- Initialise the patches for moving points
+        void initMovePoints(PstreamBuffers&, const pointField&);
+
+        //- Correct patches after moving points
+        void movePoints(PstreamBuffers&, const pointField&);
+
+        //- Initialise the update of the patch topology
+        virtual void initUpdateMesh(PstreamBuffers&);
+
+        //- Update of the patch topology
+        virtual void updateMesh(PstreamBuffers&);
+
+
+public:
+
+    //- Runtime type information
+    TypeName("processorCyclic");
+
+
+    // Constructors
+
+        //- Construct from components
+        processorCyclicPolyPatch
+        (
+            const word& name,
+            const label size,
+            const label start,
+            const label index,
+            const polyBoundaryMesh& bm,
+            const int myProcNo,
+            const int neighbProcNo,
+            const word& referPatchName
+        );
+
+        //- Construct from dictionary
+        processorCyclicPolyPatch
+        (
+            const word& name,
+            const dictionary& dict,
+            const label index,
+            const polyBoundaryMesh&
+        );
+
+        //- Construct as copy, resetting the boundary mesh
+        processorCyclicPolyPatch
+        (
+            const processorCyclicPolyPatch&,
+            const polyBoundaryMesh&
+        );
+
+        //- Construct as given the original patch and resetting the
+        //  face list and boundary mesh information
+        processorCyclicPolyPatch
+        (
+            const processorCyclicPolyPatch& pp,
+            const polyBoundaryMesh& bm,
+            const label index,
+            const label newSize,
+            const label newStart,
+            const word& referPatchName
+        );
+
+        //- Construct given the original patch and a map
+        processorCyclicPolyPatch
+        (
+            const processorCyclicPolyPatch& pp,
+            const polyBoundaryMesh& bm,
+            const label index,
+            const unallocLabelList& mapAddressing,
+            const label newStart
+        );
+
+
+        //- Construct and return a clone, resetting the boundary mesh
+        virtual autoPtr<polyPatch> clone(const polyBoundaryMesh& bm) const
+        {
+            return autoPtr<polyPatch>(new processorCyclicPolyPatch(*this, bm));
+        }
+
+        //- Construct and return a clone, resetting the face list
+        //  and boundary mesh
+        virtual autoPtr<polyPatch> clone
+        (
+            const polyBoundaryMesh& bm,
+            const label index,
+            const label newSize,
+            const label newStart,
+            const word& referPatchName
+        ) const
+        {
+            return autoPtr<polyPatch>
+            (
+                new processorCyclicPolyPatch
+                (
+                    *this,
+                    bm,
+                    index,
+                    newSize,
+                    newStart,
+                    referPatchName
+                )
+            );
+        }
+
+        //- Construct and return a clone, resetting the face list
+        //  and boundary mesh
+        virtual autoPtr<polyPatch> clone
+        (
+            const polyBoundaryMesh& bm,
+            const label index,
+            const unallocLabelList& mapAddressing,
+            const label newStart
+        ) const
+        {
+            return autoPtr<polyPatch>
+            (
+                new processorCyclicPolyPatch
+                (
+                    *this,
+                    bm,
+                    index,
+                    mapAddressing,
+                    newStart
+                )
+            );
+        }
+
+
+    // Destructor
+
+        virtual ~processorCyclicPolyPatch();
+
+
+    // Member functions
+
+        const word& referPatchName() const
+        {
+            return referPatchName_;
+        }
+
+        //- Referring patchID.
+        label referPatchID() const
+        {
+            if (referPatchID_ == -1)
+            {
+                referPatchID_ = this->boundaryMesh().findPatchID
+                (
+                    referPatchName_
+                );
+                if (referPatchID_ == -1)
+                {
+                    FatalErrorIn
+                    (
+                        "processorCyclicPolyPatch::referPatchID() const"
+                    )   << "Illegal referPatch name " << referPatchName_
+                        << endl << "Valid patch names are "
+                        << this->boundaryMesh().names()
+                        << exit(FatalError);
+                }
+            }
+            return referPatchID_;
+        }
+
+        const coupledPolyPatch& referPatch() const
+        {
+            const polyPatch& pp = this->boundaryMesh()[referPatchID()];
+            return refCast<const coupledPolyPatch>(pp);
+        }
+
+        //- Return message tag to use for communication
+        virtual int tag() const
+        {
+            return tag_;
+        }
+
+        //- Does this side own the patch ?
+        virtual bool owner() const
+        {
+            return referPatch().owner();
+        }
+
+//        //- Transform a patch-based field from other side to this side.
+//        virtual bool doTransform() const
+//        {
+//            return referPatch().doTransform();
+//        }
+//        virtual void transform(scalarField& l) const
+//        {
+//            referPatch().transform(l);
+//        }
+//        virtual void transform(vectorField& l) const
+//        {
+//            referPatch().transform(l);
+//        }
+//        virtual void transform(sphericalTensorField& l) const
+//        {
+//            referPatch().transform(l);
+//        }
+//        virtual void transform(diagTensorField& l) const
+//        {
+//            referPatch().transform(l);
+//        }
+//        virtual void transform(symmTensorField& l) const
+//        {
+//            referPatch().transform(l);
+//        }
+//        virtual void transform(tensorField& l) const
+//        {
+//            referPatch().transform(l);
+//        }
+
+        //- Transform a patch-based position from other side to this side
+        virtual void transformPosition(pointField& l) const
+        {
+            referPatch().transformPosition(l);
+        }
+
+        //- Are the planes separated.
+        virtual bool separated() const
+        {
+            return referPatch().separated();
+        }
+
+        //- If the planes are separated the separation vector.
+        virtual const vectorField& separation() const
+        {
+            return referPatch().separation();
+        }
+
+        //- Are the cyclic planes parallel.
+        virtual bool parallel() const
+        {
+            return referPatch().parallel();
+        }
+
+        //- Return face transformation tensor.
+        virtual const tensorField& forwardT() const
+        {
+            return referPatch().forwardT();
+        }
+
+        //- Return neighbour-cell transformation tensor.
+        virtual const tensorField& reverseT() const
+        {
+            return referPatch().reverseT();
+        }
+
+        //- Are faces collocated. Either size 0,1 or length of patch
+        virtual const boolList& collocated() const
+        {
+            return referPatch().collocated();
+        }
+
+
+        //- Initialize ordering for primitivePatch. Does not
+        //  refer to *this (except for name() and type() etc.)
+        virtual void initOrder(PstreamBuffers&, const primitivePatch&) const;
+
+        //- Return new ordering for primitivePatch.
+        //  Ordering is -faceMap: for every face
+        //  index of the new face -rotation:for every new face the clockwise
+        //  shift of the original face. Return false if nothing changes
+        //  (faceMap is identity, rotation is 0), true otherwise.
+        virtual bool order
+        (
+            PstreamBuffers&,
+            const primitivePatch&,
+            labelList& faceMap,
+            labelList& rotation
+        ) const;
+
+
+        //- Write the polyPatch data as a dictionary
+        virtual void write(Ostream&) const;
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/meshes/polyMesh/polyPatches/polyPatch/polyPatch.H b/src/OpenFOAM/meshes/polyMesh/polyPatches/polyPatch/polyPatch.H
index c9e5a8c8530d42ca7f53a4d8acc33f418749ff61..66daf6793bd9a499db9c8ba5d4177bffe7c1b2a6 100644
--- a/src/OpenFOAM/meshes/polyMesh/polyPatches/polyPatch/polyPatch.H
+++ b/src/OpenFOAM/meshes/polyMesh/polyPatches/polyPatch/polyPatch.H
@@ -87,12 +87,6 @@ class polyPatch
             mutable labelList* mePtr_;
 
 
-    // Private Member Functions
-
-        //- Calculate labels of mesh edges
-        void calcMeshEdges() const;
-
-
 protected:
 
     // Protected Member Functions
diff --git a/src/OpenFOAM/meshes/polyMesh/syncTools/dummyTransform.H b/src/OpenFOAM/meshes/polyMesh/syncTools/dummyTransform.H
new file mode 100644
index 0000000000000000000000000000000000000000..cdda839d32b6a6d45437cbf626721d33fdc2c5c9
--- /dev/null
+++ b/src/OpenFOAM/meshes/polyMesh/syncTools/dummyTransform.H
@@ -0,0 +1,121 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
+     \\/     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 2 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, write to the Free Software Foundation,
+    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+InClass
+    Foam::dummyTransform
+
+Description
+    Dummy transform to be used with syncTools.
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef dummyTransform_H
+#define dummyTransform_H
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+                           Class dummyTransform Declaration
+\*---------------------------------------------------------------------------*/
+
+class dummyTransform
+{
+public:
+    template<class T>
+    void operator()(const coupledPolyPatch& cpp, Field<T>& fld) const
+    {}
+    template<class T, template<class> class Container>
+    void operator()(const coupledPolyPatch& cpp, Container<T>& map) const
+    {}
+};
+
+
+template<class T>
+class pTraits<List<T> >
+:
+    public List<T>
+{
+public:
+    typedef label cmptType;
+
+    pTraits(Istream& is)
+    :
+        List<T>(is)
+    {}
+};
+
+template<class T>
+class pTraits<UList<T> >
+:
+    public UList<T>
+{
+public:
+    typedef label cmptType;
+
+    pTraits(Istream& is)
+    :
+        UList<T>(is)
+    {}
+};
+
+template<class T>
+class pTraits<Field<T> >
+:
+    public Field<T>
+{
+public:
+    typedef label cmptType;
+
+    pTraits(Istream& is)
+    :
+        Field<T>(is)
+    {}
+};
+
+template<>
+class pTraits<face>
+:
+    public face
+{
+public:
+    typedef label cmptType;
+
+    pTraits(Istream& is)
+    :
+        face(is)
+    {}
+};
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/meshes/polyMesh/syncTools/syncTools.C b/src/OpenFOAM/meshes/polyMesh/syncTools/syncTools.C
index 8bf68ba40b0527cafd5a67eceb0f398cfc31a56e..843e84908c1017fcfd59a1c732e4cdba89acc6da 100644
--- a/src/OpenFOAM/meshes/polyMesh/syncTools/syncTools.C
+++ b/src/OpenFOAM/meshes/polyMesh/syncTools/syncTools.C
@@ -28,6 +28,77 @@ License
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
+template<>
+void Foam::syncTools::transform::operator()
+(
+    const coupledPolyPatch&,
+    Field<label>&
+) const
+{}
+template<>
+void Foam::syncTools::transform::operator()
+(
+    const coupledPolyPatch&,
+    Map<label>&
+) const
+{}
+template<>
+void Foam::syncTools::transform::operator()
+(
+    const coupledPolyPatch&,
+    EdgeMap<label>&
+) const
+{}
+
+
+template<>
+void Foam::syncTools::transform::operator()
+(
+    const coupledPolyPatch&,
+    Field<scalar>&
+) const
+{}
+template<>
+void Foam::syncTools::transform::operator()
+(
+    const coupledPolyPatch&,
+    Map<scalar>&
+) const
+{}
+template<>
+void Foam::syncTools::transform::operator()
+(
+    const coupledPolyPatch&,
+    EdgeMap<scalar>&
+) const
+{}
+
+
+template<>
+void Foam::syncTools::transform::operator()
+(
+    const coupledPolyPatch&,
+    Field<bool>&
+) const
+{}
+template<>
+void Foam::syncTools::transform::operator()
+(
+    const coupledPolyPatch&,
+    Map<bool>&
+) const
+{}
+template<>
+void Foam::syncTools::transform::operator()
+(
+    const coupledPolyPatch&,
+    EdgeMap<bool>&
+) const
+{}
+
+
+// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
+
 // Does anyone have couples? Since meshes might have 0 cells and 0 proc
 // boundaries need to reduce this info.
 bool Foam::syncTools::hasCouples(const polyBoundaryMesh& patches)
@@ -46,31 +117,6 @@ bool Foam::syncTools::hasCouples(const polyBoundaryMesh& patches)
 }
 
 
-void Foam::syncTools::checkTransform
-(
-    const coupledPolyPatch& pp,
-    const bool applySeparation
-)
-{
-    if (!pp.parallel() && pp.forwardT().size() > 1)
-    {
-        FatalErrorIn("syncTools::checkTransform(const coupledPolyPatch&)")
-            << "Non-uniform transformation not supported for point or edge"
-            << " fields." << endl
-            << "Patch:" << pp.name()
-            << abort(FatalError);
-    }
-    if (applySeparation && pp.separated() && pp.separation().size() > 1)
-    {
-        FatalErrorIn("syncTools::checkTransform(const coupledPolyPatch&)")
-            << "Non-uniform separation vector not supported for point or edge"
-            << " fields." << endl
-            << "Patch:" << pp.name()
-            << abort(FatalError);
-    }
-}
-
-
 // Determines for every point whether it is coupled and if so sets only one.
 Foam::PackedBoolList Foam::syncTools::getMasterPoints(const polyMesh& mesh)
 {
@@ -154,36 +200,16 @@ Foam::PackedBoolList Foam::syncTools::getMasterFaces(const polyMesh& mesh)
     {
         if (patches[patchI].coupled())
         {
-            if (Pstream::parRun() && isA<processorPolyPatch>(patches[patchI]))
-            {
-                const processorPolyPatch& pp =
-                    refCast<const processorPolyPatch>(patches[patchI]);
+            const coupledPolyPatch& pp =
+                refCast<const coupledPolyPatch>(patches[patchI]);
 
-                if (!pp.owner())
-                {
-                    forAll(pp, i)
-                    {
-                        isMasterFace.unset(pp.start()+i);
-                    }
-                }
-            }
-            else if (isA<cyclicPolyPatch>(patches[patchI]))
+            if (!pp.owner())
             {
-                const cyclicPolyPatch& pp =
-                    refCast<const cyclicPolyPatch>(patches[patchI]);
-
-                for (label i = pp.size()/2; i < pp.size(); i++)
+                forAll(pp, i)
                 {
                     isMasterFace.unset(pp.start()+i);
                 }
             }
-            else
-            {
-                FatalErrorIn("syncTools::getMasterFaces(const polyMesh&)")
-                    << "Cannot handle coupled patch " << patches[patchI].name()
-                    << " of type " <<  patches[patchI].type()
-                    << abort(FatalError);
-            }
         }
     }
 
@@ -191,100 +217,4 @@ Foam::PackedBoolList Foam::syncTools::getMasterFaces(const polyMesh& mesh)
 }
 
 
-template <>
-void Foam::syncTools::separateList
-(
-    const vectorField& separation,
-    UList<vector>& field
-)
-{
-    if (separation.size() == 1)
-    {
-        // Single value for all.
-
-        forAll(field, i)
-        {
-            field[i] += separation[0];
-        }
-    }
-    else if (separation.size() == field.size())
-    {
-        forAll(field, i)
-        {
-            field[i] += separation[i];
-        }
-    }
-    else
-    {
-        FatalErrorIn
-        (
-            "syncTools::separateList(const vectorField&, UList<vector>&)"
-        )   << "Sizes of field and transformation not equal. field:"
-            << field.size() << " transformation:" << separation.size()
-            << abort(FatalError);
-    }
-}
-
-
-template <>
-void Foam::syncTools::separateList
-(
-    const vectorField& separation,
-    Map<vector>& field
-)
-{
-    if (separation.size() == 1)
-    {
-        // Single value for all.
-        forAllIter(Map<vector>, field, iter)
-        {
-            iter() += separation[0];
-        }
-    }
-    else if (separation.size() == field.size())
-    {
-        forAllIter(Map<vector>, field, iter)
-        {
-            iter() += separation[iter.key()];
-        }
-    }
-    else
-    {
-        FatalErrorIn
-        (
-            "syncTools::separateList(const vectorField&, Map<vector>&)"
-        )   << "Sizes of field and transformation not equal. field:"
-            << field.size() << " transformation:" << separation.size()
-            << abort(FatalError);
-    }
-}
-
-
-template <>
-void Foam::syncTools::separateList
-(
-    const vectorField& separation,
-    EdgeMap<vector>& field
-)
-{
-    if (separation.size() == 1)
-    {
-        // Single value for all.
-        forAllIter(EdgeMap<vector>, field, iter)
-        {
-            iter() += separation[0];
-        }
-    }
-    else
-    {
-        FatalErrorIn
-        (
-            "syncTools::separateList(const vectorField&, EdgeMap<vector>&)"
-        )   << "Multiple separation vectors not supported. field:"
-            << field.size() << " transformation:" << separation.size()
-            << abort(FatalError);
-    }
-}
-
-
 // ************************************************************************* //
diff --git a/src/OpenFOAM/meshes/polyMesh/syncTools/syncTools.H b/src/OpenFOAM/meshes/polyMesh/syncTools/syncTools.H
index 04ca6121cdc5149c2348100ee6281a681f876c67..725270a489536543116ef2e17d1469893b5bad61 100644
--- a/src/OpenFOAM/meshes/polyMesh/syncTools/syncTools.H
+++ b/src/OpenFOAM/meshes/polyMesh/syncTools/syncTools.H
@@ -50,10 +50,12 @@ SourceFiles
 
 #include "UList.H"
 #include "Pstream.H"
-#include "transformList.H"
 #include "Map.H"
 #include "EdgeMap.H"
 #include "PackedBoolList.H"
+#include "polyMesh.H"
+#include "coupledPolyPatch.H"
+#include "transformList.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -61,8 +63,6 @@ namespace Foam
 {
 
 class polyBoundaryMesh;
-class polyMesh;
-class coupledPolyPatch;
 
 /*---------------------------------------------------------------------------*\
                            Class syncTools Declaration
@@ -75,20 +75,6 @@ class syncTools
         //- Check whether uses couples.
         static bool hasCouples(const polyBoundaryMesh&);
 
-        //- Check for single transformation tensor only.
-        static void checkTransform(const coupledPolyPatch&, const bool);
-
-        //- Apply separation to list. Either single vector or one vector
-        //  per element.
-        template <class T>
-        static void separateList(const vectorField&, UList<T>&);
-
-        template <class T>
-        static void separateList(const vectorField&, Map<T>&);
-
-        template <class T>
-        static void separateList(const vectorField&, EdgeMap<T>&);
-
         //- Combine value with existing value in map.
         template <class T, class CombineOp>
         static void combine
@@ -112,116 +98,383 @@ class syncTools
 
 public:
 
-    // Static data members
+    // Public classes
+
+        class transform
+        {
+        public:
+            //- Transform patch-based field
+            template<class T>
+            void operator()(const coupledPolyPatch& cpp, Field<T>& fld) const
+            {
+                if (!cpp.parallel())
+                {
+                    transformList(cpp.forwardT(), fld);
+                }
+            }
+
+            //- Transform sparse field
+            template<class T, template<class> class Container>
+            void operator()(const coupledPolyPatch& cpp, Container<T>& map)
+            const
+            {
+                if (!cpp.parallel())
+                {
+                    transformList(cpp.forwardT(), map);
+                }
+            }
+        };
+
+        class transformPosition
+        {
+        public:
+            void operator()(const coupledPolyPatch& cpp, pointField& fld) const
+            {
+                cpp.transformPosition(fld);
+            }
+            template<template<class> class Container>
+            void operator()(const coupledPolyPatch& cpp, Container<point>& map)
+            const
+            {
+                Field<point> fld(map.size());
+                label i = 0;
+                forAllConstIter(typename Container<point>, map, iter)
+                {
+                    fld[i++] = iter();
+                }
+                cpp.transformPosition(fld);
+                i = 0;
+                forAllIter(typename Container<point>, map, iter)
+                {
+                    iter() = fld[i++];
+                }
+            }
+        };
+
+
+        // Basic routines with user-supplied transformation. Preferably
+        // use specialisations below.
 
-        //- Synchronize values on all mesh points.
-        //  Applies rotation and optionally separation for parallel cyclics
-        template <class T, class CombineOp>
-        static void syncPointList
-        (
-            const polyMesh&,
-            UList<T>&,
-            const CombineOp& cop,
-            const T& nullValue,
-            const bool applySeparation
-        );
+            //- Synchronize values on selected points.
+            template <class T, class CombineOp, class TransformOp>
+            static void syncPointMap
+            (
+                const polyMesh&,
+                Map<T>& pointValues,
+                const CombineOp& cop,
+                const TransformOp& top
+            );
 
-        //- Synchronize values on selected mesh points.
-        //  Applies rotation and optionally separation for parallel cyclics
-        template <class T, class CombineOp>
-        static void syncPointList
-        (
-            const polyMesh&,
-            const labelList& meshPoints,
-            UList<T>&,
-            const CombineOp& bop,
-            const T& nullValue,
-            const bool applySeparation
-        );
+            //- Synchronize values on selected edges.
+            template <class T, class CombineOp, class TransformOp>
+            static void syncEdgeMap
+            (
+                const polyMesh&,
+                EdgeMap<T>& edgeValues,
+                const CombineOp& cop,
+                const TransformOp& top
+            );
 
-        //- Synchronize values on all mesh edges.
-        //  Applies rotation and optionally separation for parallel cyclics
-        template <class T, class CombineOp>
-        static void syncEdgeList
-        (
-            const polyMesh&,
-            UList<T>&,
-            const CombineOp& cop,
-            const T& nullValue,
-            const bool applySeparation
-        );
+            //- Synchronize values on all mesh points.
+            template <class T, class CombineOp, class TransformOp>
+            static void syncPointList
+            (
+                const polyMesh&,
+                UList<T>&,
+                const CombineOp& cop,
+                const T& nullValue,
+                const TransformOp& top
+            );
 
-        //- Synchronize values on boundary faces only.
-        //  Optionally applies rotation tensor for non-parallel cyclics
-        //  (but not separation!)
-        template <class T, class CombineOp>
-        static void syncBoundaryFaceList
-        (
-            const polyMesh&,
-            UList<T>&,
-            const CombineOp& cop,
-            const bool applySeparation
-        );
+            //- Synchronize values on selected mesh points.
+            template <class T, class CombineOp, class TransformOp>
+            static void syncPointList
+            (
+                const polyMesh&,
+                const labelList& meshPoints,
+                UList<T>&,
+                const CombineOp& cop,
+                const T& nullValue,
+                const TransformOp& top
+            );
 
-        //- Synchronize values on all mesh faces.
-        //  Optionally applies rotation tensor for non-parallel cyclics
-        //  (but not separation!)
-        template <class T, class CombineOp>
-        static void syncFaceList
-        (
-            const polyMesh&,
-            UList<T>&,
-            const CombineOp& cop,
-            const bool applySeparation
-        );
+            //- Synchronize values on all mesh edges.
+            template <class T, class CombineOp, class TransformOp>
+            static void syncEdgeList
+            (
+                const polyMesh&,
+                UList<T>&,
+                const CombineOp& cop,
+                const T& nullValue,
+                const TransformOp& top
+            );
 
-        //- Swap coupled face values.
-        //  Applies rotation and optionally separation for parallel cyclics
-        template <class T>
-        static void swapBoundaryFaceList
-        (
-            const polyMesh&,
-            UList<T>&,
-            const bool applySeparation
-        );
+            //- Synchronize values on boundary faces only.
+            template <class T, class CombineOp, class TransformOp>
+            static void syncBoundaryFaceList
+            (
+                const polyMesh&,
+                UList<T>&,
+                const CombineOp& cop,
+                const TransformOp& top
+            );
 
-        //- Swap coupled face values.
-        //  Applies rotation and optionally separation for parallel cyclics
-        template <class T>
-        static void swapFaceList
-        (
-            const polyMesh&,
-            UList<T>&,
-            const bool applySeparation
-        );
+
+        // Synchronise point-wise data
+
+            //- Synchronize values on all mesh points.
+            template <class T, class CombineOp>
+            static void syncPointList
+            (
+                const polyMesh& mesh,
+                UList<T>& l,
+                const CombineOp& cop,
+                const T& nullValue
+            )
+            {
+                syncPointList(mesh, l, cop, nullValue, transform());
+            }
+
+            //- Synchronize locations on all mesh points.
+            template <class CombineOp>
+            static void syncPointPositions
+            (
+                const polyMesh& mesh,
+                UList<point>& l,
+                const CombineOp& cop,
+                const point& nullValue
+            )
+            {
+                syncPointList(mesh, l, cop, nullValue, transformPosition());
+            }
+
+            //- Synchronize values on selected mesh points.
+            template <class T, class CombineOp>
+            static void syncPointList
+            (
+                const polyMesh& mesh,
+                const labelList& meshPoints,
+                UList<T>& l,
+                const CombineOp& cop,
+                const T& nullValue
+            )
+            {
+                syncPointList
+                (
+                    mesh,
+                    meshPoints,
+                    l,
+                    cop,
+                    nullValue,
+                    transform()
+                );
+            }
+
+            //- Synchronize locations on selected mesh points.
+            template <class CombineOp>
+            static void syncPointPositions
+            (
+                const polyMesh& mesh,
+                const labelList& meshPoints,
+                UList<point>& l,
+                const CombineOp& cop,
+                const point& nullValue
+            )
+            {
+                syncPointList
+                (
+                    mesh,
+                    meshPoints,
+                    l,
+                    cop,
+                    nullValue,
+                    transformPosition()
+                );
+            }
+
+
+        // Synchronise edge-wise data
+
+            //- Synchronize values on all mesh edges.
+            template <class T, class CombineOp>
+            static void syncEdgeList
+            (
+                const polyMesh& mesh,
+                UList<T>& l,
+                const CombineOp& cop,
+                const T& nullValue
+            )
+            {
+                syncEdgeList(mesh, l, cop, nullValue, transform());
+            }
+
+            //- Synchronize values on all mesh edges.
+            template <class CombineOp>
+            static void syncEdgePositions
+            (
+                const polyMesh& mesh,
+                UList<point>& l,
+                const CombineOp& cop,
+                const point& nullValue
+            )
+            {
+                syncEdgeList(mesh, l, cop, nullValue, transformPosition());
+            }
+
+
+        // Synchronise face-wise data
+
+            //- Synchronize values on boundary faces only.
+            template <class T, class CombineOp>
+            static void syncBoundaryFaceList
+            (
+                const polyMesh& mesh,
+                UList<T>& l,
+                const CombineOp& cop
+            )
+            {
+                syncBoundaryFaceList(mesh, l, cop, transform());
+            }
+
+            //- Synchronize locations on boundary faces only.
+            template <class CombineOp>
+            static void syncBoundaryFacePositions
+            (
+                const polyMesh& mesh,
+                UList<point>& l,
+                const CombineOp& cop
+            )
+            {
+                syncBoundaryFaceList(mesh, l, cop, transformPosition());
+            }
+
+            //- Synchronize values on all mesh faces.
+            template <class T, class CombineOp>
+            static void syncFaceList
+            (
+                const polyMesh& mesh,
+                UList<T>& l,
+                const CombineOp& cop
+            )
+            {
+                SubList<T> bndValues
+                (
+                    l,
+                    mesh.nFaces()-mesh.nInternalFaces(),
+                    mesh.nInternalFaces()
+                );
+
+                syncBoundaryFaceList(mesh, bndValues, cop, transform());
+            }
+
+            //- Synchronize locations on all mesh faces.
+            template <class CombineOp>
+            static void syncFacePositions
+            (
+                const polyMesh& mesh,
+                UList<point>& l,
+                const CombineOp& cop
+            )
+            {
+                SubList<point> bndValues
+                (
+                    l,
+                    mesh.nFaces()-mesh.nInternalFaces(),
+                    mesh.nInternalFaces()
+                );
+                syncBoundaryFaceList(mesh, bndValues, cop, transformPosition());
+            }
+
+            //- Swap coupled boundary face values.
+            template <class T>
+            static void swapBoundaryFaceList
+            (
+                const polyMesh& mesh,
+                UList<T>& l
+            )
+            {
+                syncBoundaryFaceList(mesh, l, eqOp<T>(), transform());
+            }
+
+             //- Swap coupled positions.
+            template <class T>
+            static void swapBoundaryFacePositions
+            (
+                const polyMesh& mesh,
+                UList<T>& l
+            )
+            {
+                syncBoundaryFaceList(mesh, l, eqOp<T>(), transformPosition());
+            }
+
+            //- Swap coupled face values.
+            template <class T>
+            static void swapFaceList
+            (
+                const polyMesh& mesh,
+                UList<T>& l
+            )
+            {
+                SubList<T> bndValues
+                (
+                    l,
+                    mesh.nFaces()-mesh.nInternalFaces(),
+                    mesh.nInternalFaces()
+                );
+                syncBoundaryFaceList(mesh, bndValues, eqOp<T>(), transform());
+            }
 
         // Sparse versions
 
             //- Synchronize values on selected points.
-            //  Applies rotation and optionally separation for parallel
-            //  cyclics.
             template <class T, class CombineOp>
             static void syncPointMap
             (
-                const polyMesh&,
-                Map<T>& pointValues,
-                const CombineOp& cop,
-                const bool applySeparation
-            );
+                const polyMesh& mesh,
+                Map<T>& l,
+                const CombineOp& cop
+            )
+            {
+                syncPointMap(mesh, l, cop, transform());
+            }
+
+            //- Synchronize locations on selected points.
+            template <class CombineOp>
+            static void syncPointPositions
+            (
+                const polyMesh& mesh,
+                Map<point>& l,
+                const CombineOp& cop
+            )
+            {
+                syncPointMap(mesh, l, cop, transformPosition());
+            }
 
             //- Synchronize values on selected edges. Edges are represented
             //  by the two vertices that make it up so global edges never get
             //  constructed.
-            //  Applies rotation and optionally separation for parallel
-            //  cyclics.
             template <class T, class CombineOp>
             static void syncEdgeMap
             (
-                const polyMesh&,
-                EdgeMap<T>& edgeValues,
-                const CombineOp& cop,
-                const bool applySeparation
-            );
+                const polyMesh& mesh,
+                EdgeMap<T>& l,
+                const CombineOp& cop
+            )
+            {
+                syncEdgeMap(mesh, l, cop, transform());
+            }
+
+            //- Synchronize locations on selected edges.
+            template <class T, class CombineOp>
+            static void syncEdgePositions
+            (
+                const polyMesh& mesh,
+                EdgeMap<T>& l,
+                const CombineOp& cop
+            )
+            {
+                syncEdgeMap(mesh, l, cop, transformPosition());
+            }
 
         // PackedList versions
 
@@ -273,13 +526,62 @@ public:
 
 
 template<>
-void syncTools::separateList(const vectorField&, UList<vector>&);
+void syncTools::transform::operator()
+(
+    const coupledPolyPatch&,
+    Field<label>&
+) const;
+template<>
+void syncTools::transform::operator()
+(
+    const coupledPolyPatch&,
+    Map<label>&
+) const;
+template<>
+void syncTools::transform::operator()
+(
+    const coupledPolyPatch&,
+    EdgeMap<label>&
+) const;
+
 
 template<>
-void syncTools::separateList(const vectorField&, Map<vector>&);
+void syncTools::transform::operator()
+(
+    const coupledPolyPatch&,
+    Field<scalar>&
+) const;
+template<>
+void syncTools::transform::operator()
+(
+    const coupledPolyPatch&,
+    Map<scalar>&
+) const;
+template<>
+void syncTools::transform::operator()
+(
+    const coupledPolyPatch&,
+    EdgeMap<scalar>&
+) const;
 
 template<>
-void syncTools::separateList(const vectorField&, EdgeMap<vector>&);
+void syncTools::transform::operator()
+(
+    const coupledPolyPatch& cpp,
+    Field<bool>& fld
+) const;
+template<>
+void syncTools::transform::operator()
+(
+    const coupledPolyPatch&,
+    Map<bool>&
+) const;
+template<>
+void syncTools::transform::operator()
+(
+    const coupledPolyPatch&,
+    EdgeMap<bool>&
+) const;
 
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
diff --git a/src/OpenFOAM/meshes/polyMesh/syncTools/syncToolsTemplates.C b/src/OpenFOAM/meshes/polyMesh/syncTools/syncToolsTemplates.C
index 3591eac7562b6f39225b12d543a06f6d0893a52e..9675d29bb71f29c7c81b3adffe7a26834ce6ce75 100644
--- a/src/OpenFOAM/meshes/polyMesh/syncTools/syncToolsTemplates.C
+++ b/src/OpenFOAM/meshes/polyMesh/syncTools/syncToolsTemplates.C
@@ -30,35 +30,11 @@ License
 #include "globalMeshData.H"
 #include "contiguous.H"
 #include "transform.H"
+#include "transformList.H"
 
-// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
-
-template <class T>
-void Foam::syncTools::separateList
-(
-    const vectorField& separation,
-    UList<T>& field
-)
-{}
-
-
-template <class T>
-void Foam::syncTools::separateList
-(
-    const vectorField& separation,
-    Map<T>& field
-)
-{}
-
-
-template <class T>
-void Foam::syncTools::separateList
-(
-    const vectorField& separation,
-    EdgeMap<T>& field
-)
-{}
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
+// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
 // Combine val with existing value at index
 template <class T, class CombineOp>
@@ -106,13 +82,13 @@ void Foam::syncTools::combine
 }
 
 
-template <class T, class CombineOp>
+template <class T, class CombineOp, class TransformOp>
 void Foam::syncTools::syncPointMap
 (
     const polyMesh& mesh,
     Map<T>& pointValues,        // from mesh point label to value
     const CombineOp& cop,
-    const bool applySeparation
+    const TransformOp& top
 )
 {
     const polyBoundaryMesh& patches = mesh.boundaryMesh();
@@ -122,11 +98,10 @@ void Foam::syncTools::syncPointMap
         return;
     }
 
-    // Is there any coupled patch with transformation?
-    bool hasTransformation = false;
-
     if (Pstream::parRun())
     {
+        PstreamBuffers pBufs(Pstream::nonBlocking);
+
         // Send
 
         forAll(patches, patchI)
@@ -156,18 +131,16 @@ void Foam::syncTools::syncPointMap
 
                     if (iter != pointValues.end())
                     {
-                        if (nbrPts[i] >= 0)
-                        {
-                            patchInfo.insert(nbrPts[i], iter());
-                        }
+                        patchInfo.insert(nbrPts[i], iter());
                     }
                 }
 
-                OPstream toNeighb(Pstream::blocking, procPatch.neighbProcNo());
+                UOPstream toNeighb(procPatch.neighbProcNo(), pBufs);
                 toNeighb << patchInfo;
             }
         }
 
+        pBufs.finishedSends();
 
         // Receive and combine.
 
@@ -181,26 +154,16 @@ void Foam::syncTools::syncPointMap
             {
                 const processorPolyPatch& procPatch =
                     refCast<const processorPolyPatch>(patches[patchI]);
-                checkTransform(procPatch, applySeparation);
 
-                IPstream fromNb(Pstream::blocking, procPatch.neighbProcNo());
+                UIPstream fromNb(procPatch.neighbProcNo(), pBufs);
                 Map<T> nbrPatchInfo(fromNb);
 
-                if (!procPatch.parallel())
-                {
-                    hasTransformation = true;
-                    transformList(procPatch.forwardT(), nbrPatchInfo);
-                }
-                else if (applySeparation && procPatch.separated())
-                {
-                    hasTransformation = true;
-                    separateList(-procPatch.separation(), nbrPatchInfo);
-                }
+                // Transform
+                top(procPatch, nbrPatchInfo);
 
                 const labelList& meshPts = procPatch.meshPoints();
 
                 // Only update those values which come from neighbour
-
                 forAllConstIter(typename Map<T>, nbrPatchInfo, nbrIter)
                 {
                     combine
@@ -222,105 +185,86 @@ void Foam::syncTools::syncPointMap
         {
             const cyclicPolyPatch& cycPatch =
                 refCast<const cyclicPolyPatch>(patches[patchI]);
-            checkTransform(cycPatch, applySeparation);
-
-            const edgeList& coupledPoints = cycPatch.coupledPoints();
-            const labelList& meshPts = cycPatch.meshPoints();
-
-            // Extract local values. Create map from nbrPoint to value.
-            Map<T> half0Values(meshPts.size() / 20);
-            Map<T> half1Values(meshPts.size() / 20);
 
-            forAll(coupledPoints, i)
+            if (cycPatch.owner())
             {
-                const edge& e = coupledPoints[i];
+                // Owner does all.
 
-                typename Map<T>::const_iterator point0Fnd =
-                    pointValues.find(meshPts[e[0]]);
-
-                if (point0Fnd != pointValues.end())
-                {
-                    half0Values.insert(i, point0Fnd());
-                }
+                const cyclicPolyPatch& nbrPatch = cycPatch.neighbPatch();
+                const edgeList& coupledPoints = cycPatch.coupledPoints();
+                const labelList& meshPtsA = cycPatch.meshPoints();
+                const labelList& meshPtsB = nbrPatch.meshPoints();
 
-                typename Map<T>::const_iterator point1Fnd =
-                    pointValues.find(meshPts[e[1]]);
+                // Extract local values. Create map from coupled-edge to value.
+                Map<T> half0Values(meshPtsA.size() / 20);
+                Map<T> half1Values(half0Values.size());
 
-                if (point1Fnd != pointValues.end())
+                forAll(coupledPoints, i)
                 {
-                    half1Values.insert(i, point1Fnd());
-                }
-            }
+                    const edge& e = coupledPoints[i];
 
-            if (!cycPatch.parallel())
-            {
-                hasTransformation = true;
-                transformList(cycPatch.reverseT(), half0Values);
-                transformList(cycPatch.forwardT(), half1Values);
-            }
-            else if (applySeparation && cycPatch.separated())
-            {
-                hasTransformation = true;
+                    typename Map<T>::const_iterator point0Fnd =
+                        pointValues.find(meshPtsA[e[0]]);
 
-                const vectorField& v = cycPatch.coupledPolyPatch::separation();
-                separateList(v, half0Values);
-                separateList(-v, half1Values);
-            }
-
-            forAll(coupledPoints, i)
-            {
-                const edge& e = coupledPoints[i];
+                    if (point0Fnd != pointValues.end())
+                    {
+                        half0Values.insert(i, point0Fnd());
+                    }
 
-                typename Map<T>::const_iterator half1Fnd = half1Values.find(i);
+                    typename Map<T>::const_iterator point1Fnd =
+                        pointValues.find(meshPtsB[e[1]]);
 
-                if (half1Fnd != half1Values.end())
-                {
-                    combine
-                    (
-                        pointValues,
-                        cop,
-                        meshPts[e[0]],
-                        half1Fnd()
-                    );
+                    if (point1Fnd != pointValues.end())
+                    {
+                        half1Values.insert(i, point1Fnd());
+                    }
                 }
 
-                typename Map<T>::const_iterator half0Fnd = half0Values.find(i);
+                // Transform to receiving side
+                top(cycPatch, half1Values);
+                top(nbrPatch, half0Values);
 
-                if (half0Fnd != half0Values.end())
+                forAll(coupledPoints, i)
                 {
-                    combine
-                    (
-                        pointValues,
-                        cop,
-                        meshPts[e[1]],
-                        half0Fnd()
-                    );
+                    const edge& e = coupledPoints[i];
+
+                    typename Map<T>::const_iterator half0Fnd =
+                        half0Values.find(i);
+
+                    if (half0Fnd != half0Values.end())
+                    {
+                        combine
+                        (
+                            pointValues,
+                            cop,
+                            meshPtsB[e[1]],
+                            half0Fnd()
+                        );
+                    }
+
+                    typename Map<T>::const_iterator half1Fnd =
+                        half1Values.find(i);
+
+                    if (half1Fnd != half1Values.end())
+                    {
+                        combine
+                        (
+                            pointValues,
+                            cop,
+                            meshPtsA[e[0]],
+                            half1Fnd()
+                        );
+                    }
                 }
             }
         }
     }
 
-    //- Note: hasTransformation is only used for warning messages so
-    //  reduction not strictly nessecary.
-    //reduce(hasTransformation, orOp<bool>());
-
     // Synchronize multiple shared points.
     const globalMeshData& pd = mesh.globalData();
 
     if (pd.nGlobalPoints() > 0)
     {
-        if (hasTransformation)
-        {
-            WarningIn
-            (
-                "syncTools<class T, class CombineOp>::syncPointMap"
-                "(const polyMesh&, Map<T>&, const CombineOp&"
-                ", const bool)"
-            )   << "There are decomposed cyclics in this mesh with"
-                << " transformations." << endl
-                << "This is not supported. The result will be incorrect"
-                << endl;
-        }
         // meshPoint per local index
         const labelList& sharedPtLabels = pd.sharedPointLabels();
         // global shared index per local index
@@ -364,7 +308,7 @@ void Foam::syncTools::syncPointMap
                     slave++
                 )
                 {
-                    IPstream fromSlave(Pstream::blocking, slave);
+                    IPstream fromSlave(Pstream::scheduled, slave);
                     Map<T> nbrValues(fromSlave);
 
                     // Merge neighbouring values with my values
@@ -388,22 +332,22 @@ void Foam::syncTools::syncPointMap
                     slave++
                 )
                 {
-                    OPstream toSlave(Pstream::blocking, slave);
+                    OPstream toSlave(Pstream::scheduled, slave);
                     toSlave << sharedPointValues;
                 }
             }
             else
             {
-                // Send to master
+                // Slave: send to master
                 {
-                    OPstream toMaster(Pstream::blocking, Pstream::masterNo());
+                    OPstream toMaster(Pstream::scheduled, Pstream::masterNo());
                     toMaster << sharedPointValues;
                 }
                 // Receive merged values
                 {
                     IPstream fromMaster
                     (
-                        Pstream::blocking,
+                        Pstream::scheduled,
                         Pstream::masterNo()
                     );
                     fromMaster >> sharedPointValues;
@@ -443,13 +387,13 @@ void Foam::syncTools::syncPointMap
 }
 
 
-template <class T, class CombineOp>
+template <class T, class CombineOp, class TransformOp>
 void Foam::syncTools::syncEdgeMap
 (
     const polyMesh& mesh,
     EdgeMap<T>& edgeValues,
     const CombineOp& cop,
-    const bool applySeparation
+    const TransformOp& top
 )
 {
     const polyBoundaryMesh& patches = mesh.boundaryMesh();
@@ -469,6 +413,8 @@ void Foam::syncTools::syncEdgeMap
 
     if (Pstream::parRun())
     {
+        PstreamBuffers pBufs(Pstream::nonBlocking);
+
         // Send
 
         forAll(patches, patchI)
@@ -482,6 +428,7 @@ void Foam::syncTools::syncEdgeMap
                 const processorPolyPatch& procPatch =
                     refCast<const processorPolyPatch>(patches[patchI]);
 
+
                 // Get data per patch edge in neighbouring edge.
 
                 const edgeList& edges = procPatch.edges();
@@ -501,19 +448,16 @@ void Foam::syncTools::syncEdgeMap
                     if (iter != edgeValues.end())
                     {
                         const edge nbrEdge(nbrPts[e[0]], nbrPts[e[1]]);
-
-                        if (nbrEdge[0] >= 0 && nbrEdge[1] >= 0)
-                        {
-                            patchInfo.insert(nbrEdge, iter());
-                        }
+                        patchInfo.insert(nbrEdge, iter());
                     }
                 }
 
-                OPstream toNeighb(Pstream::blocking, procPatch.neighbProcNo());
+                UOPstream toNeighb(procPatch.neighbProcNo(), pBufs);
                 toNeighb << patchInfo;
             }
         }
 
+        pBufs.finishedSends();
 
         // Receive and combine.
 
@@ -527,23 +471,19 @@ void Foam::syncTools::syncEdgeMap
             {
                 const processorPolyPatch& procPatch =
                     refCast<const processorPolyPatch>(patches[patchI]);
-                checkTransform(procPatch, applySeparation);
-
-                const labelList& meshPts = procPatch.meshPoints();
 
-                IPstream fromNbr(Pstream::blocking, procPatch.neighbProcNo());
-                EdgeMap<T> nbrPatchInfo(fromNbr);
-
-                if (!procPatch.parallel())
+                EdgeMap<T> nbrPatchInfo;
                 {
-                    transformList(procPatch.forwardT(), nbrPatchInfo);
-                }
-                else if (applySeparation && procPatch.separated())
-                {
-                    separateList(-procPatch.separation(), nbrPatchInfo);
+                    UIPstream fromNbr(procPatch.neighbProcNo(), pBufs);
+                    fromNbr >> nbrPatchInfo;
                 }
 
+                // Apply transform to convert to this side properties.
+                top(procPatch, nbrPatchInfo);
+
+
                 // Only update those values which come from neighbour
+                const labelList& meshPts = procPatch.meshPoints();
 
                 forAllConstIter(typename EdgeMap<T>, nbrPatchInfo, nbrIter)
                 {
@@ -572,99 +512,95 @@ void Foam::syncTools::syncEdgeMap
         {
             const cyclicPolyPatch& cycPatch =
                 refCast<const cyclicPolyPatch>(patches[patchI]);
-            checkTransform(cycPatch, applySeparation);
 
-            const edgeList& coupledEdges = cycPatch.coupledEdges();
-            const labelList& meshPts = cycPatch.meshPoints();
-            const edgeList& edges = cycPatch.edges();
+            if (cycPatch.owner())
+            {
+                // Owner does all.
 
-            // Extract local values. Create map from nbrPoint to value.
-            Map<T> half0Values(meshPts.size() / 20);
-            Map<T> half1Values(meshPts.size() / 20);
+                const edgeList& coupledEdges = cycPatch.coupledEdges();
+                const labelList& meshPtsA = cycPatch.meshPoints();
+                const edgeList& edgesA = cycPatch.edges();
+                const cyclicPolyPatch& nbrPatch = cycPatch.neighbPatch();
+                const labelList& meshPtsB = nbrPatch.meshPoints();
+                const edgeList& edgesB = nbrPatch.edges();
 
-            forAll(coupledEdges, i)
-            {
-                const edge& twoEdges = coupledEdges[i];
+                // Extract local values. Create map from edge to value.
+                Map<T> half0Values(edgesA.size() / 20);
+                Map<T> half1Values(half0Values.size());
 
+                forAll(coupledEdges, i)
                 {
-                    const edge& e0 = edges[twoEdges[0]];
-                    const edge meshEdge0(meshPts[e0[0]], meshPts[e0[1]]);
-
-                    typename EdgeMap<T>::const_iterator iter =
-                        edgeValues.find(meshEdge0);
+                    const edge& twoEdges = coupledEdges[i];
 
-                    if (iter != edgeValues.end())
                     {
-                        half0Values.insert(i, iter());
-                    }
-                }
-                {
-                    const edge& e1 = edges[twoEdges[1]];
-                    const edge meshEdge1(meshPts[e1[0]], meshPts[e1[1]]);
+                        const edge& e0 = edgesA[twoEdges[0]];
+                        const edge meshEdge0(meshPtsA[e0[0]], meshPtsA[e0[1]]);
 
-                    typename EdgeMap<T>::const_iterator iter =
-                        edgeValues.find(meshEdge1);
+                        typename EdgeMap<T>::const_iterator iter =
+                            edgeValues.find(meshEdge0);
 
-                    if (iter != edgeValues.end())
-                    {
-                        half1Values.insert(i, iter());
+                        if (iter != edgeValues.end())
+                        {
+                            half0Values.insert(i, iter());
+                        }
                     }
-                }
-            }
+                    {
+                        const edge& e1 = edgesB[twoEdges[1]];
+                        const edge meshEdge1(meshPtsB[e1[0]], meshPtsB[e1[1]]);
 
+                        typename EdgeMap<T>::const_iterator iter =
+                            edgeValues.find(meshEdge1);
 
-            // Transform
+                        if (iter != edgeValues.end())
+                        {
+                            half1Values.insert(i, iter());
+                        }
+                    }
+                }
 
-            if (!cycPatch.parallel())
-            {
-                transformList(cycPatch.reverseT(), half0Values);
-                transformList(cycPatch.forwardT(), half1Values);
-            }
-            else if (applySeparation && cycPatch.separated())
-            {
-                const vectorField& v = cycPatch.coupledPolyPatch::separation();
-                separateList(v, half0Values);
-                separateList(-v, half1Values);
-            }
+                // Transform to this side
+                top(cycPatch, half1Values);
+                top(nbrPatch, half0Values);
 
 
-            // Extract and combine information
+                // Extract and combine information
 
-            forAll(coupledEdges, i)
-            {
-                const edge& twoEdges = coupledEdges[i];
+                forAll(coupledEdges, i)
+                {
+                    const edge& twoEdges = coupledEdges[i];
 
-                typename Map<T>::const_iterator half1Fnd =
-                    half1Values.find(i);
+                    typename Map<T>::const_iterator half1Fnd =
+                        half1Values.find(i);
 
-                if (half1Fnd != half1Values.end())
-                {
-                    const edge& e0 = edges[twoEdges[0]];
-                    const edge meshEdge0(meshPts[e0[0]], meshPts[e0[1]]);
+                    if (half1Fnd != half1Values.end())
+                    {
+                        const edge& e0 = edgesA[twoEdges[0]];
+                        const edge meshEdge0(meshPtsA[e0[0]], meshPtsA[e0[1]]);
 
-                    combine
-                    (
-                        edgeValues,
-                        cop,
-                        meshEdge0,  // edge
-                        half1Fnd()  // value
-                    );
-                }
+                        combine
+                        (
+                            edgeValues,
+                            cop,
+                            meshEdge0,  // edge
+                            half1Fnd()  // value
+                        );
+                    }
 
-                typename Map<T>::const_iterator half0Fnd =
-                    half0Values.find(i);
-                if (half0Fnd != half0Values.end())
-                {
-                    const edge& e1 = edges[twoEdges[1]];
-                    const edge meshEdge1(meshPts[e1[0]], meshPts[e1[1]]);
+                    typename Map<T>::const_iterator half0Fnd =
+                        half0Values.find(i);
+                    if (half0Fnd != half0Values.end())
+                    {
+                        const edge& e1 = edgesB[twoEdges[1]];
+                        const edge meshEdge1(meshPtsB[e1[0]], meshPtsB[e1[1]]);
 
-                    combine
-                    (
-                        edgeValues,
-                        cop,
-                        meshEdge1,  // edge
-                        half0Fnd()  // value
-                    );
+                        combine
+                        (
+                            edgeValues,
+                            cop,
+                            meshEdge1,  // edge
+                            half0Fnd()  // value
+                        );
+                    }
                 }
             }
         }
@@ -759,7 +695,7 @@ void Foam::syncTools::syncEdgeMap
                 slave++
             )
             {
-                IPstream fromSlave(Pstream::blocking, slave);
+                IPstream fromSlave(Pstream::scheduled, slave);
                 EdgeMap<T> nbrValues(fromSlave);
 
                 // Merge neighbouring values with my values
@@ -784,7 +720,7 @@ void Foam::syncTools::syncEdgeMap
             )
             {
 
-                OPstream toSlave(Pstream::blocking, slave);
+                OPstream toSlave(Pstream::scheduled, slave);
                 toSlave << sharedEdgeValues;
             }
         }
@@ -792,12 +728,12 @@ void Foam::syncTools::syncEdgeMap
         {
             // Send to master
             {
-                OPstream toMaster(Pstream::blocking, Pstream::masterNo());
+                OPstream toMaster(Pstream::scheduled, Pstream::masterNo());
                 toMaster << sharedEdgeValues;
             }
             // Receive merged values
             {
-                IPstream fromMaster(Pstream::blocking, Pstream::masterNo());
+                IPstream fromMaster(Pstream::scheduled, Pstream::masterNo());
                 fromMaster >> sharedEdgeValues;
             }
         }
@@ -831,14 +767,14 @@ void Foam::syncTools::syncEdgeMap
 }
 
 
-template <class T, class CombineOp>
+template <class T, class CombineOp, class TransformOp>
 void Foam::syncTools::syncPointList
 (
     const polyMesh& mesh,
     UList<T>& pointValues,
     const CombineOp& cop,
     const T& nullValue,
-    const bool applySeparation
+    const TransformOp& top
 )
 {
     if (pointValues.size() != mesh.nPoints())
@@ -860,11 +796,10 @@ void Foam::syncTools::syncPointList
         return;
     }
 
-    // Is there any coupled patch with transformation?
-    bool hasTransformation = false;
-
     if (Pstream::parRun())
     {
+        PstreamBuffers pBufs(Pstream::nonBlocking);
+
         // Send
 
         forAll(patches, patchI)
@@ -879,7 +814,7 @@ void Foam::syncTools::syncPointList
                     refCast<const processorPolyPatch>(patches[patchI]);
 
                 // Get data per patchPoint in neighbouring point numbers.
-                List<T> patchInfo(procPatch.nPoints(), nullValue);
+                Field<T> patchInfo(procPatch.nPoints());
 
                 const labelList& meshPts = procPatch.meshPoints();
                 const labelList& nbrPts = procPatch.neighbPoints();
@@ -887,17 +822,15 @@ void Foam::syncTools::syncPointList
                 forAll(nbrPts, pointI)
                 {
                     label nbrPointI = nbrPts[pointI];
-                    if (nbrPointI >= 0 && nbrPointI < patchInfo.size())
-                    {
-                        patchInfo[nbrPointI] = pointValues[meshPts[pointI]];
-                    }
+                    patchInfo[nbrPointI] = pointValues[meshPts[pointI]];
                 }
 
-                OPstream toNbr(Pstream::blocking, procPatch.neighbProcNo());
+                UOPstream toNbr(procPatch.neighbProcNo(), pBufs);
                 toNbr << patchInfo;
             }
         }
 
+        pBufs.finishedSends();
 
         // Receive and combine.
 
@@ -911,32 +844,15 @@ void Foam::syncTools::syncPointList
             {
                 const processorPolyPatch& procPatch =
                     refCast<const processorPolyPatch>(patches[patchI]);
-                checkTransform(procPatch, applySeparation);
 
-                List<T> nbrPatchInfo(procPatch.nPoints());
+                Field<T> nbrPatchInfo(procPatch.nPoints());
                 {
-                    // We do not know the number of points on the other side
-                    // so cannot use Pstream::read.
-                    IPstream fromNbr
-                    (
-                        Pstream::blocking,
-                        procPatch.neighbProcNo()
-                    );
+                    UIPstream fromNbr(procPatch.neighbProcNo(), pBufs);
                     fromNbr >> nbrPatchInfo;
                 }
-                // Null any value which is not on neighbouring processor
-                nbrPatchInfo.setSize(procPatch.nPoints(), nullValue);
 
-                if (!procPatch.parallel())
-                {
-                    hasTransformation = true;
-                    transformList(procPatch.forwardT(), nbrPatchInfo);
-                }
-                else if (applySeparation && procPatch.separated())
-                {
-                    hasTransformation = true;
-                    separateList(-procPatch.separation(), nbrPatchInfo);
-                }
+                // Transform to this side
+                top(procPatch, nbrPatchInfo);
 
                 const labelList& meshPts = procPatch.meshPoints();
 
@@ -957,77 +873,50 @@ void Foam::syncTools::syncPointList
             const cyclicPolyPatch& cycPatch =
                 refCast<const cyclicPolyPatch>(patches[patchI]);
 
-            checkTransform(cycPatch, applySeparation);
-
-            const edgeList& coupledPoints = cycPatch.coupledPoints();
-            const labelList& meshPts = cycPatch.meshPoints();
-
-            List<T> half0Values(coupledPoints.size());
-            List<T> half1Values(coupledPoints.size());
-
-            forAll(coupledPoints, i)
+            if (cycPatch.owner())
             {
-                const edge& e = coupledPoints[i];
+                // Owner does all.
 
-                label point0 = meshPts[e[0]];
-                label point1 = meshPts[e[1]];
+                const edgeList& coupledPoints = cycPatch.coupledPoints();
+                const labelList& meshPts = cycPatch.meshPoints();
+                const cyclicPolyPatch& nbrPatch = cycPatch.neighbPatch();
+                const labelList& nbrMeshPoints = nbrPatch.meshPoints();
 
-                half0Values[i] = pointValues[point0];
-                half1Values[i] = pointValues[point1];
-            }
+                Field<T> half0Values(coupledPoints.size());
+                Field<T> half1Values(coupledPoints.size());
 
-            if (!cycPatch.parallel())
-            {
-                hasTransformation = true;
-                transformList(cycPatch.reverseT(), half0Values);
-                transformList(cycPatch.forwardT(), half1Values);
-            }
-            else if (applySeparation && cycPatch.separated())
-            {
-                hasTransformation = true;
-                const vectorField& v = cycPatch.coupledPolyPatch::separation();
-                separateList(v, half0Values);
-                separateList(-v, half1Values);
-            }
+                forAll(coupledPoints, i)
+                {
+                    const edge& e = coupledPoints[i];
+                    half0Values[i] = pointValues[meshPts[e[0]]];
+                    half1Values[i] = pointValues[nbrMeshPoints[e[1]]];
+                }
 
-            forAll(coupledPoints, i)
-            {
-                const edge& e = coupledPoints[i];
+                //SubField<T> slice0(half0Values, half0Values.size());
+                //SubField<T> slice1(half1Values, half1Values.size());
+                //top(cycPatch, reinterpret_cast<Field<T>&>(slice1));
+                //top(nbrPatch, reinterpret_cast<Field<T>&>(slice0));
 
-                label point0 = meshPts[e[0]];
-                label point1 = meshPts[e[1]];
+                top(cycPatch, half1Values);
+                top(nbrPatch, half0Values);
 
-                cop(pointValues[point0], half1Values[i]);
-                cop(pointValues[point1], half0Values[i]);
+                forAll(coupledPoints, i)
+                {
+                    const edge& e = coupledPoints[i];
+                    cop(pointValues[meshPts[e[0]]], half1Values[i]);
+                    cop(pointValues[nbrMeshPoints[e[1]]], half0Values[i]);
+                }
             }
         }
     }
 
-    //- Note: hasTransformation is only used for warning messages so
-    //  reduction not strictly nessecary.
-    //reduce(hasTransformation, orOp<bool>());
-
     // Synchronize multiple shared points.
     const globalMeshData& pd = mesh.globalData();
 
     if (pd.nGlobalPoints() > 0)
     {
-        if (hasTransformation)
-        {
-            WarningIn
-            (
-                "syncTools<class T, class CombineOp>::syncPointList"
-                "(const polyMesh&, UList<T>&, const CombineOp&, const T&"
-                ", const bool)"
-            )   << "There are decomposed cyclics in this mesh with"
-                << " transformations." << endl
-                << "This is not supported. The result will be incorrect"
-                << endl;
-        }
-
-
         // Values on shared points.
-        List<T> sharedPts(pd.nGlobalPoints(), nullValue);
+        Field<T> sharedPts(pd.nGlobalPoints(), nullValue);
 
         forAll(pd.sharedPointLabels(), i)
         {
@@ -1051,7 +940,7 @@ void Foam::syncTools::syncPointList
 }
 
 
-template <class T, class CombineOp>
+template <class T, class CombineOp, class TransformOp>
 void Foam::syncTools::syncPointList
 (
     const polyMesh& mesh,
@@ -1059,7 +948,7 @@ void Foam::syncTools::syncPointList
     UList<T>& pointValues,
     const CombineOp& cop,
     const T& nullValue,
-    const bool applySeparation
+    const TransformOp& top
 )
 {
     if (pointValues.size() != meshPoints.size())
@@ -1079,7 +968,7 @@ void Foam::syncTools::syncPointList
         return;
     }
 
-    List<T> meshValues(mesh.nPoints(), nullValue);
+    Field<T> meshValues(mesh.nPoints(), nullValue);
 
     forAll(meshPoints, i)
     {
@@ -1092,7 +981,7 @@ void Foam::syncTools::syncPointList
         meshValues,
         cop,            // combine op
         nullValue,      // null value
-        applySeparation // separation
+        top             // position or field
     );
 
     forAll(meshPoints, i)
@@ -1102,14 +991,14 @@ void Foam::syncTools::syncPointList
 }
 
 
-template <class T, class CombineOp>
+template <class T, class CombineOp, class TransformOp>
 void Foam::syncTools::syncEdgeList
 (
     const polyMesh& mesh,
     UList<T>& edgeValues,
     const CombineOp& cop,
     const T& nullValue,
-    const bool applySeparation
+    const TransformOp& top
 )
 {
     if (edgeValues.size() != mesh.nEdges())
@@ -1131,11 +1020,10 @@ void Foam::syncTools::syncEdgeList
         return;
     }
 
-    // Is there any coupled patch with transformation?
-    bool hasTransformation = false;
-
     if (Pstream::parRun())
     {
+        PstreamBuffers pBufs(Pstream::nonBlocking);
+
         // Send
 
         forAll(patches, patchI)
@@ -1153,23 +1041,22 @@ void Foam::syncTools::syncEdgeList
                 const labelList& neighbEdges = procPatch.neighbEdges();
 
                 // Get region per patch edge in neighbouring edge numbers.
-                List<T> patchInfo(procPatch.nEdges(), nullValue);
+                Field<T> patchInfo(procPatch.nEdges(), nullValue);
 
                 forAll(neighbEdges, edgeI)
                 {
                     label nbrEdgeI = neighbEdges[edgeI];
 
-                    if (nbrEdgeI >= 0 && nbrEdgeI < patchInfo.size())
-                    {
-                        patchInfo[nbrEdgeI] = edgeValues[meshEdges[edgeI]];
-                    }
+                    patchInfo[nbrEdgeI] = edgeValues[meshEdges[edgeI]];
                 }
 
-                OPstream toNbr(Pstream::blocking, procPatch.neighbProcNo());
+                UOPstream toNbr(procPatch.neighbProcNo(), pBufs);
                 toNbr << patchInfo;
-            }
+           }
         }
 
+        pBufs.finishedSends();
+
         // Receive and combine.
 
         forAll(patches, patchI)
@@ -1183,40 +1070,23 @@ void Foam::syncTools::syncEdgeList
                 const processorPolyPatch& procPatch =
                     refCast<const processorPolyPatch>(patches[patchI]);
 
-                checkTransform(procPatch, applySeparation);
-
                 const labelList& meshEdges = procPatch.meshEdges();
 
                 // Receive from neighbour. Is per patch edge the region of the
                 // neighbouring patch edge.
-                List<T> nbrPatchInfo(procPatch.nEdges());
+                Field<T> nbrPatchInfo(procPatch.nEdges());
 
                 {
-                    IPstream fromNeighb
-                    (
-                        Pstream::blocking,
-                        procPatch.neighbProcNo()
-                    );
+                    UIPstream fromNeighb(procPatch.neighbProcNo(), pBufs);
                     fromNeighb >> nbrPatchInfo;
                 }
-                // Null any value which is not on neighbouring processor
-                nbrPatchInfo.setSize(procPatch.nEdges(), nullValue);
 
-                if (!procPatch.parallel())
-                {
-                    hasTransformation = true;
-                    transformList(procPatch.forwardT(), nbrPatchInfo);
-                }
-                else if (applySeparation && procPatch.separated())
-                {
-                    hasTransformation = true;
-                    separateList(-procPatch.separation(), nbrPatchInfo);
-                }
+                // Transform to this side
+                top(procPatch, nbrPatchInfo);
 
                 forAll(meshEdges, edgeI)
                 {
                     label meshEdgeI = meshEdges[edgeI];
-
                     cop(edgeValues[meshEdgeI], nbrPatchInfo[edgeI]);
                 }
             }
@@ -1231,49 +1101,38 @@ void Foam::syncTools::syncEdgeList
             const cyclicPolyPatch& cycPatch =
                 refCast<const cyclicPolyPatch>(patches[patchI]);
 
-            checkTransform(cycPatch, applySeparation);
-
-            const edgeList& coupledEdges = cycPatch.coupledEdges();
-            const labelList& meshEdges = cycPatch.meshEdges();
-
-            List<T> half0Values(coupledEdges.size());
-            List<T> half1Values(coupledEdges.size());
-
-            forAll(coupledEdges, i)
+            if (cycPatch.owner())
             {
-                const edge& e = coupledEdges[i];
-
-                label meshEdge0 = meshEdges[e[0]];
-                label meshEdge1 = meshEdges[e[1]];
+                // Owner does all.
+                const edgeList& coupledEdges = cycPatch.coupledEdges();
+                const labelList& meshEdges = cycPatch.meshEdges();
+                const cyclicPolyPatch& nbrPatch = cycPatch.neighbPatch();
+                const labelList& nbrMeshEdges = nbrPatch.meshEdges();
 
-                half0Values[i] = edgeValues[meshEdge0];
-                half1Values[i] = edgeValues[meshEdge1];
-            }
+                Field<T> half0Values(coupledEdges.size());
+                Field<T> half1Values(coupledEdges.size());
 
-            if (!cycPatch.parallel())
-            {
-                hasTransformation = true;
-                transformList(cycPatch.reverseT(), half0Values);
-                transformList(cycPatch.forwardT(), half1Values);
-            }
-            else if (applySeparation && cycPatch.separated())
-            {
-                hasTransformation = true;
-
-                const vectorField& v = cycPatch.coupledPolyPatch::separation();
-                separateList(v, half0Values);
-                separateList(-v, half1Values);
-            }
+                forAll(coupledEdges, i)
+                {
+                    const edge& e = coupledEdges[i];
+                    half0Values[i] = edgeValues[meshEdges[e[0]]];
+                    half1Values[i] = edgeValues[nbrMeshEdges[e[1]]];
+                }
 
-            forAll(coupledEdges, i)
-            {
-                const edge& e = coupledEdges[i];
+                //SubField<T> slice0(half0Values, half0Values.size());
+                //SubField<T> slice1(half1Values, half1Values.size());
+                //top(cycPatch, reinterpret_cast<Field<T>&>(slice1));
+                //top(nbrPatch, reinterpret_cast<Field<T>&>(slice0));
 
-                label meshEdge0 = meshEdges[e[0]];
-                label meshEdge1 = meshEdges[e[1]];
+                top(cycPatch, half1Values);
+                top(nbrPatch, half0Values);
 
-                cop(edgeValues[meshEdge0], half1Values[i]);
-                cop(edgeValues[meshEdge1], half0Values[i]);
+                forAll(coupledEdges, i)
+                {
+                    const edge& e = coupledEdges[i];
+                    cop(edgeValues[meshEdges[e[0]]], half1Values[i]);
+                    cop(edgeValues[nbrMeshEdges[e[1]]], half0Values[i]);
+                }
             }
         }
     }
@@ -1287,21 +1146,8 @@ void Foam::syncTools::syncEdgeList
 
     if (pd.nGlobalEdges() > 0)
     {
-        if (hasTransformation)
-        {
-            WarningIn
-            (
-                "syncTools<class T, class CombineOp>::syncEdgeList"
-                "(const polyMesh&, UList<T>&, const CombineOp&, const T&"
-                ", const bool)"
-            )   << "There are decomposed cyclics in this mesh with"
-                << " transformations." << endl
-                << "This is not supported. The result will be incorrect"
-                << endl;
-        }
-
         // Values on shared edges.
-        List<T> sharedPts(pd.nGlobalEdges(), nullValue);
+        Field<T> sharedPts(pd.nGlobalEdges(), nullValue);
 
         forAll(pd.sharedEdgeLabels(), i)
         {
@@ -1326,13 +1172,13 @@ void Foam::syncTools::syncEdgeList
 }
 
 
-template <class T, class CombineOp>
+template <class T, class CombineOp, class TransformOp>
 void Foam::syncTools::syncBoundaryFaceList
 (
     const polyMesh& mesh,
     UList<T>& faceValues,
     const CombineOp& cop,
-    const bool applySeparation
+    const TransformOp& top
 )
 {
     const label nBFaces = mesh.nFaces() - mesh.nInternalFaces();
@@ -1359,6 +1205,8 @@ void Foam::syncTools::syncBoundaryFaceList
 
     if (Pstream::parRun())
     {
+        PstreamBuffers pBufs(Pstream::nonBlocking);
+
         // Send
 
         forAll(patches, patchI)
@@ -1374,26 +1222,21 @@ void Foam::syncTools::syncBoundaryFaceList
 
                 label patchStart = procPatch.start()-mesh.nInternalFaces();
 
-                if (contiguous<T>())
-                {
-                    OPstream::write
+                UOPstream toNbr(procPatch.neighbProcNo(), pBufs);
+                toNbr << 
+                    SubField<T>
                     (
-                        Pstream::blocking,
-                        procPatch.neighbProcNo(),
-                        reinterpret_cast<const char*>(&faceValues[patchStart]),
-                        procPatch.size()*sizeof(T)
+                        faceValues,
+                        procPatch.size(),
+                        patchStart
                     );
-                }
-                else
-                {
-                    OPstream toNbr(Pstream::blocking, procPatch.neighbProcNo());
-                    toNbr <<
-                        SubList<T>(faceValues, procPatch.size(), patchStart);
-                }
             }
         }
 
 
+        pBufs.finishedSends();
+
+
         // Receive and combine.
 
         forAll(patches, patchI)
@@ -1407,37 +1250,12 @@ void Foam::syncTools::syncBoundaryFaceList
                 const processorPolyPatch& procPatch =
                     refCast<const processorPolyPatch>(patches[patchI]);
 
-                List<T> nbrPatchInfo(procPatch.size());
+                Field<T> nbrPatchInfo(procPatch.size());
 
-                if (contiguous<T>())
-                {
-                    IPstream::read
-                    (
-                        Pstream::blocking,
-                        procPatch.neighbProcNo(),
-                        reinterpret_cast<char*>(nbrPatchInfo.begin()),
-                        nbrPatchInfo.byteSize()
-                    );
-                }
-                else
-                {
-                    IPstream fromNeighb
-                    (
-                        Pstream::blocking,
-                        procPatch.neighbProcNo()
-                    );
-                    fromNeighb >> nbrPatchInfo;
-                }
-
-                if (!procPatch.parallel())
-                {
-                    transformList(procPatch.forwardT(), nbrPatchInfo);
-                }
-                else if (applySeparation && procPatch.separated())
-                {
-                    separateList(-procPatch.separation(), nbrPatchInfo);
-                }
+                UIPstream fromNeighb(procPatch.neighbProcNo(), pBufs);
+                fromNeighb >> nbrPatchInfo;
 
+                top(procPatch, nbrPatchInfo);
 
                 label bFaceI = procPatch.start()-mesh.nInternalFaces();
 
@@ -1457,103 +1275,40 @@ void Foam::syncTools::syncBoundaryFaceList
             const cyclicPolyPatch& cycPatch =
                 refCast<const cyclicPolyPatch>(patches[patchI]);
 
-            label patchStart = cycPatch.start()-mesh.nInternalFaces();
+            if (cycPatch.owner())
+            {
+                // Owner does all.
+                const cyclicPolyPatch& nbrPatch = cycPatch.neighbPatch();
+                label ownStart = cycPatch.start()-mesh.nInternalFaces();
+                label nbrStart = nbrPatch.start()-mesh.nInternalFaces();
 
-            label half = cycPatch.size()/2;
-            label half1Start = patchStart+half;
+                label sz = cycPatch.size();
 
-            List<T> half0Values(SubList<T>(faceValues, half, patchStart));
-            List<T> half1Values(SubList<T>(faceValues, half, half1Start));
+                // Transform (copy of) data on both sides
+                Field<T> ownVals(SubField<T>(faceValues, sz, ownStart));
+                top(nbrPatch, ownVals);
 
-            if (!cycPatch.parallel())
-            {
-                transformList(cycPatch.reverseT(), half0Values);
-                transformList(cycPatch.forwardT(), half1Values);
-            }
-            else if (applySeparation && cycPatch.separated())
-            {
-                const vectorField& v = cycPatch.coupledPolyPatch::separation();
-                separateList(v, half0Values);
-                separateList(-v, half1Values);
-            }
+                Field<T> nbrVals(SubField<T>(faceValues, sz, nbrStart));
+                top(cycPatch, nbrVals);
 
-            label i0 = patchStart;
-            forAll(half1Values, i)
-            {
-                cop(faceValues[i0++], half1Values[i]);
-            }
+                label i0 = ownStart;
+                forAll(nbrVals, i)
+                {
+                    cop(faceValues[i0++], nbrVals[i]);
+                }
 
-            label i1 = half1Start;
-            forAll(half0Values, i)
-            {
-                cop(faceValues[i1++], half0Values[i]);
+                label i1 = nbrStart;
+                forAll(ownVals, i)
+                {
+                    cop(faceValues[i1++], ownVals[i]);
+                }
             }
         }
     }
 }
 
 
-template <class T, class CombineOp>
-void Foam::syncTools::syncFaceList
-(
-    const polyMesh& mesh,
-    UList<T>& faceValues,
-    const CombineOp& cop,
-    const bool applySeparation
-)
-{
-    if (faceValues.size() != mesh.nFaces())
-    {
-        FatalErrorIn
-        (
-            "syncTools<class T, class CombineOp>::syncFaceList"
-            "(const polyMesh&, UList<T>&, const CombineOp&"
-            ", const bool)"
-        )   << "Number of values " << faceValues.size()
-            << " is not equal to the number of faces in the mesh "
-            << mesh.nFaces() << abort(FatalError);
-    }
-
-    SubList<T> bndValues
-    (
-        faceValues,
-        mesh.nFaces()-mesh.nInternalFaces(),
-        mesh.nInternalFaces()
-    );
-
-    syncBoundaryFaceList
-    (
-        mesh,
-        bndValues,
-        cop,
-        applySeparation
-    );
-}
-
-
-template <class T>
-void Foam::syncTools::swapBoundaryFaceList
-(
-    const polyMesh& mesh,
-    UList<T>& faceValues,
-    const bool applySeparation
-)
-{
-    syncBoundaryFaceList(mesh, faceValues, eqOp<T>(), applySeparation);
-}
-
-
-template <class T>
-void Foam::syncTools::swapFaceList
-(
-    const polyMesh& mesh,
-    UList<T>& faceValues,
-    const bool applySeparation
-)
-{
-    syncFaceList(mesh, faceValues, eqOp<T>(), applySeparation);
-}
-
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
 template <unsigned nBits, class CombineOp>
 void Foam::syncTools::syncFaceList
@@ -1581,11 +1336,10 @@ void Foam::syncTools::syncFaceList
         return;
     }
 
-    // Patch data (proc patches only).
-    List<List<unsigned int> > patchValues(patches.size());
-
     if (Pstream::parRun())
     {
+        PstreamBuffers pBufs(Pstream::nonBlocking);
+
         // Send
 
         forAll(patches, patchI)
@@ -1599,19 +1353,20 @@ void Foam::syncTools::syncFaceList
                 const processorPolyPatch& procPatch =
                     refCast<const processorPolyPatch>(patches[patchI]);
 
-                patchValues[patchI].setSize(procPatch.size());
+                List<unsigned int> patchInfo(procPatch.size());
                 forAll(procPatch, i)
                 {
-                    patchValues[patchI][i] =
-                        faceValues.get(procPatch.start()+i);
+                    patchInfo[i] = faceValues[procPatch.start()+i];
                 }
 
-                OPstream toNbr(Pstream::blocking, procPatch.neighbProcNo());
-                toNbr << patchValues[patchI];
+                UOPstream toNbr(procPatch.neighbProcNo(), pBufs);
+                toNbr << patchInfo;
             }
         }
 
 
+        pBufs.finishedSends();
+
         // Receive and combine.
 
         forAll(patches, patchI)
@@ -1625,23 +1380,20 @@ void Foam::syncTools::syncFaceList
                 const processorPolyPatch& procPatch =
                     refCast<const processorPolyPatch>(patches[patchI]);
 
+                List<unsigned int> patchInfo(procPatch.size());
                 {
-                    IPstream fromNbr
-                    (
-                        Pstream::blocking,
-                        procPatch.neighbProcNo()
-                    );
-                    fromNbr >> patchValues[patchI];
+                    UIPstream fromNbr(procPatch.neighbProcNo(), pBufs);
+                    fromNbr >> patchInfo;
                 }
 
                 // Combine (bitwise)
                 forAll(procPatch, i)
                 {
-                    unsigned int patchVal = patchValues[patchI][i];
+                    unsigned int patchVal = patchInfo[i];
                     label meshFaceI = procPatch.start()+i;
-                    unsigned int faceVal = faceValues.get(meshFaceI);
+                    unsigned int faceVal = faceValues[meshFaceI];
                     cop(faceVal, patchVal);
-                    faceValues.set(meshFaceI, faceVal);
+                    faceValues[meshFaceI] = faceVal;
                 }
             }
         }
@@ -1655,21 +1407,25 @@ void Foam::syncTools::syncFaceList
             const cyclicPolyPatch& cycPatch =
                 refCast<const cyclicPolyPatch>(patches[patchI]);
 
-            label half = cycPatch.size()/2;
-
-            for (label i = 0; i < half; i++)
+            if (cycPatch.owner())
             {
-                label meshFace0 = cycPatch.start()+i;
-                unsigned int val0 = faceValues.get(meshFace0);
-                label meshFace1 = meshFace0 + half;
-                unsigned int val1 = faceValues.get(meshFace1);
+                // Owner does all.
+                const cyclicPolyPatch& nbrPatch = cycPatch.neighbPatch();
 
-                unsigned int t = val0;
-                cop(t, val1);
-                faceValues.set(meshFace0, t);
+                for (label i = 0; i < cycPatch.size(); i++)
+                {
+                    label meshFace0 = cycPatch.start()+i;
+                    unsigned int val0 = faceValues[meshFace0];
+                    label meshFace1 = nbrPatch.start()+i;
+                    unsigned int val1 = faceValues[meshFace1];
+
+                    unsigned int t = val0;
+                    cop(t, val1);
+                    faceValues[meshFace0] = t;
 
-                cop(val1, val0);
-                faceValues.set(meshFace1, val1);
+                    cop(val1, val0);                
+                    faceValues[meshFace1] = val1;
+                }
             }
         }
     }
@@ -1702,7 +1458,7 @@ void Foam::syncTools::syncPointList
         (
             "syncTools<unsigned nBits, class CombineOp>::syncPointList"
             "(const polyMesh&, PackedList<nBits>&, const CombineOp&"
-            ", const unsigned int&)"
+            ", const unsigned int)"
         )   << "Number of values " << pointValues.size()
             << " is not equal to the number of points in the mesh "
             << mesh.nPoints() << abort(FatalError);
@@ -1715,11 +1471,10 @@ void Foam::syncTools::syncPointList
         return;
     }
 
-    // Patch data (proc patches only).
-    List<List<unsigned int> > patchValues(patches.size());
-
     if (Pstream::parRun())
     {
+        PstreamBuffers pBufs(Pstream::nonBlocking);
+
         // Send
 
         forAll(patches, patchI)
@@ -1733,8 +1488,7 @@ void Foam::syncTools::syncPointList
                 const processorPolyPatch& procPatch =
                     refCast<const processorPolyPatch>(patches[patchI]);
 
-                patchValues[patchI].setSize(procPatch.nPoints());
-                patchValues[patchI] = nullValue;
+                List<unsigned int> patchInfo(procPatch.nPoints());
 
                 const labelList& meshPts = procPatch.meshPoints();
                 const labelList& nbrPts = procPatch.neighbPoints();
@@ -1742,19 +1496,17 @@ void Foam::syncTools::syncPointList
                 forAll(nbrPts, pointI)
                 {
                     label nbrPointI = nbrPts[pointI];
-                    if (nbrPointI >= 0 && nbrPointI < procPatch.nPoints())
-                    {
-                        patchValues[patchI][nbrPointI] =
-                            pointValues.get(meshPts[pointI]);
-                    }
+                    patchInfo[nbrPointI] = pointValues[meshPts[pointI]];
                 }
 
-                OPstream toNbr(Pstream::blocking, procPatch.neighbProcNo());
-                toNbr << patchValues[patchI];
+                UOPstream toNbr(procPatch.neighbProcNo(), pBufs);
+                toNbr << patchInfo;
             }
         }
 
 
+        pBufs.finishedSends();
+
         // Receive and combine.
 
         forAll(patches, patchI)
@@ -1768,28 +1520,22 @@ void Foam::syncTools::syncPointList
                 const processorPolyPatch& procPatch =
                     refCast<const processorPolyPatch>(patches[patchI]);
 
+                List<unsigned int> nbrPatchInfo(procPatch.nPoints());
                 {
                     // We do not know the number of points on the other side
                     // so cannot use Pstream::read.
-                    IPstream fromNbr
-                    (
-                        Pstream::blocking,
-                        procPatch.neighbProcNo()
-                    );
-                    fromNbr >> patchValues[patchI];
+                    UIPstream fromNbr(procPatch.neighbProcNo(), pBufs);
+                    fromNbr >> nbrPatchInfo;
                 }
 
-                // Null any value which is not on neighbouring processor
-                patchValues[patchI].setSize(procPatch.nPoints(), nullValue);
-
                 const labelList& meshPts = procPatch.meshPoints();
 
                 forAll(meshPts, pointI)
                 {
                     label meshPointI = meshPts[pointI];
-                    unsigned int pointVal = pointValues.get(meshPointI);
-                    cop(pointVal, patchValues[patchI][pointI]);
-                    pointValues.set(meshPointI, pointVal);
+                    unsigned int pointVal = pointValues[meshPointI];
+                    cop(pointVal, nbrPatchInfo[pointI]);
+                    pointValues[meshPointI] = pointVal;
                 }
             }
         }
@@ -1803,24 +1549,30 @@ void Foam::syncTools::syncPointList
             const cyclicPolyPatch& cycPatch =
                 refCast<const cyclicPolyPatch>(patches[patchI]);
 
-            const edgeList& coupledPoints = cycPatch.coupledPoints();
-            const labelList& meshPts = cycPatch.meshPoints();
-
-            forAll(coupledPoints, i)
+            if (cycPatch.owner())
             {
-                const edge& e = coupledPoints[i];
-
-                label point0 = meshPts[e[0]];
-                label point1 = meshPts[e[1]];
+                // Owner does all.
 
-                unsigned int val0 = pointValues.get(point0);
-                unsigned int t = val0;
-                unsigned int val1 = pointValues.get(point1);
+                const edgeList& coupledPoints = cycPatch.coupledPoints();
+                const labelList& meshPts = cycPatch.meshPoints();
+                const cyclicPolyPatch& nbrPatch = cycPatch.neighbPatch();
+                const labelList& nbrMeshPts = nbrPatch.meshPoints();
 
-                cop(t, val1);
-                pointValues.set(point0, t);
-                cop(val1, val0);
-                pointValues.set(point1, val1);
+                forAll(coupledPoints, i)
+                {
+                    const edge& e = coupledPoints[i];
+                    label meshPoint0 = meshPts[e[0]];
+                    label meshPoint1 = nbrMeshPts[e[1]];
+
+                    unsigned int val0 = pointValues[meshPoint0];
+                    unsigned int val1 = pointValues[meshPoint1];
+                    unsigned int t = val0;
+
+                    cop(val0, val1);
+                    pointValues[meshPoint0] = val0;
+                    cop(val1, t);
+                    pointValues[meshPoint1] = val1;
+                }
             }
         }
     }
@@ -1837,7 +1589,7 @@ void Foam::syncTools::syncPointList
         {
             label meshPointI = pd.sharedPointLabels()[i];
             // Fill my entries in the shared points
-            sharedPts[pd.sharedPointAddr()[i]] = pointValues.get(meshPointI);
+            sharedPts[pd.sharedPointAddr()[i]] = pointValues[meshPointI];
         }
 
         // Combine on master.
@@ -1849,7 +1601,7 @@ void Foam::syncTools::syncPointList
         forAll(pd.sharedPointLabels(), i)
         {
             label meshPointI = pd.sharedPointLabels()[i];
-            pointValues.set(meshPointI, sharedPts[pd.sharedPointAddr()[i]]);
+            pointValues[meshPointI] = sharedPts[pd.sharedPointAddr()[i]];
         }
     }
 }
@@ -1870,7 +1622,7 @@ void Foam::syncTools::syncEdgeList
         (
             "syncTools<unsigned nBits, class CombineOp>::syncEdgeList"
             "(const polyMesh&, PackedList<nBits>&, const CombineOp&"
-            ", const unsigned int&)"
+            ", const unsigned int)"
         )   << "Number of values " << edgeValues.size()
             << " is not equal to the number of edges in the mesh "
             << mesh.nEdges() << abort(FatalError);
@@ -1883,11 +1635,10 @@ void Foam::syncTools::syncEdgeList
         return;
     }
 
-    // Patch data (proc patches only).
-    List<List<unsigned int> > patchValues(patches.size());
-
     if (Pstream::parRun())
     {
+        PstreamBuffers pBufs(Pstream::nonBlocking);
+
         // Send
 
         forAll(patches, patchI)
@@ -1901,7 +1652,7 @@ void Foam::syncTools::syncEdgeList
                 const processorPolyPatch& procPatch =
                     refCast<const processorPolyPatch>(patches[patchI]);
 
-                patchValues[patchI].setSize(procPatch.nEdges(), nullValue);
+                List<unsigned int> patchInfo(procPatch.nEdges());
 
                 const labelList& meshEdges = procPatch.meshEdges();
                 const labelList& neighbEdges = procPatch.neighbEdges();
@@ -1909,18 +1660,15 @@ void Foam::syncTools::syncEdgeList
                 forAll(neighbEdges, edgeI)
                 {
                     label nbrEdgeI = neighbEdges[edgeI];
-                    if (nbrEdgeI >= 0 && nbrEdgeI < procPatch.nEdges())
-                    {
-                        patchValues[patchI][nbrEdgeI] =
-                            edgeValues.get(meshEdges[edgeI]);
-                    }
+                    patchInfo[nbrEdgeI] = edgeValues[meshEdges[edgeI]];
                 }
 
-                OPstream toNbr(Pstream::blocking, procPatch.neighbProcNo());
-                toNbr << patchValues[patchI];
+                UOPstream toNbr(procPatch.neighbProcNo(), pBufs);
+                toNbr << patchInfo;
             }
         }
 
+        pBufs.finishedSends();
 
         // Receive and combine.
 
@@ -1935,26 +1683,23 @@ void Foam::syncTools::syncEdgeList
                 const processorPolyPatch& procPatch =
                     refCast<const processorPolyPatch>(patches[patchI]);
 
+                // Receive from neighbour. 
+                List<unsigned int> nbrPatchInfo(procPatch.nEdges());
+
                 {
-                    IPstream fromNeighb
-                    (
-                        Pstream::blocking,
-                        procPatch.neighbProcNo()
-                    );
-                    fromNeighb >> patchValues[patchI];
+                    UIPstream fromNeighb(procPatch.neighbProcNo(), pBufs);
+                    fromNeighb >> nbrPatchInfo;
                 }
 
-                patchValues[patchI].setSize(procPatch.nEdges(), nullValue);
-
                 const labelList& meshEdges = procPatch.meshEdges();
 
                 forAll(meshEdges, edgeI)
                 {
-                    unsigned int patchVal = patchValues[patchI][edgeI];
+                    unsigned int patchVal = nbrPatchInfo[edgeI];
                     label meshEdgeI = meshEdges[edgeI];
-                    unsigned int edgeVal = edgeValues.get(meshEdgeI);
+                    unsigned int edgeVal = edgeValues[meshEdgeI];
                     cop(edgeVal, patchVal);
-                    edgeValues.set(meshEdgeI, edgeVal);
+                    edgeValues[meshEdgeI] = edgeVal;
                 }
             }
         }
@@ -1968,24 +1713,30 @@ void Foam::syncTools::syncEdgeList
             const cyclicPolyPatch& cycPatch =
                 refCast<const cyclicPolyPatch>(patches[patchI]);
 
-            const edgeList& coupledEdges = cycPatch.coupledEdges();
-            const labelList& meshEdges = cycPatch.meshEdges();
-
-            forAll(coupledEdges, i)
+            if (cycPatch.owner())
             {
-                const edge& e = coupledEdges[i];
+                // Owner does all.
+                const edgeList& coupledEdges = cycPatch.coupledEdges();
+                const labelList& meshEdges = cycPatch.meshEdges();
+                const cyclicPolyPatch& nbrPatch = cycPatch.neighbPatch();
+                const labelList& nbrMeshEdges = nbrPatch.meshEdges();
 
-                label edge0 = meshEdges[e[0]];
-                label edge1 = meshEdges[e[1]];
+                forAll(coupledEdges, i)
+                {
+                    const edge& e = coupledEdges[i];
+
+                    label edge0 = meshEdges[e[0]];
+                    label edge1 = nbrMeshEdges[e[1]];
 
-                unsigned int val0 = edgeValues.get(edge0);
-                unsigned int t = val0;
-                unsigned int val1 = edgeValues.get(edge1);
+                    unsigned int val0 = edgeValues[edge0];
+                    unsigned int t = val0;
+                    unsigned int val1 = edgeValues[edge1];
 
-                cop(t, val1);
-                edgeValues.set(edge0, t);
-                cop(val1, val0);
-                edgeValues.set(edge1, val1);
+                    cop(t, val1);
+                    edgeValues[edge0] = t;
+                    cop(val1, val0);
+                    edgeValues[edge1] = val1;
+                }
             }
         }
     }
@@ -2002,7 +1753,7 @@ void Foam::syncTools::syncEdgeList
         {
             label meshEdgeI = pd.sharedEdgeLabels()[i];
             // Fill my entries in the shared edges
-            sharedPts[pd.sharedEdgeAddr()[i]] = edgeValues.get(meshEdgeI);
+            sharedPts[pd.sharedEdgeAddr()[i]] = edgeValues[meshEdgeI];
         }
 
         // Combine on master.
@@ -2014,7 +1765,7 @@ void Foam::syncTools::syncEdgeList
         forAll(pd.sharedEdgeLabels(), i)
         {
             label meshEdgeI = pd.sharedEdgeLabels()[i];
-            edgeValues.set(meshEdgeI, sharedPts[pd.sharedEdgeAddr()[i]]);
+            edgeValues[meshEdgeI] = sharedPts[pd.sharedEdgeAddr()[i]];
         }
     }
 }
diff --git a/src/OpenFOAM/meshes/polyMesh/zones/faceZone/faceZone.C b/src/OpenFOAM/meshes/polyMesh/zones/faceZone/faceZone.C
index 8c5b79e80a25f8b8b931795dc6b205e74336e1fb..ddda6efaf96248e2496a015db334b128fa3a4e6e 100644
--- a/src/OpenFOAM/meshes/polyMesh/zones/faceZone/faceZone.C
+++ b/src/OpenFOAM/meshes/polyMesh/zones/faceZone/faceZone.C
@@ -463,9 +463,9 @@ bool Foam::faceZone::checkParallelSync(const bool report) const
             }
         }
         boolList myZoneFace(neiZoneFace);
-        syncTools::swapBoundaryFaceList(mesh, neiZoneFace, false);
+        syncTools::swapBoundaryFaceList(mesh, neiZoneFace);
         boolList myZoneFlip(neiZoneFlip);
-        syncTools::swapBoundaryFaceList(mesh, neiZoneFlip, false);
+        syncTools::swapBoundaryFaceList(mesh, neiZoneFlip);
 
         forAll(*this, i)
         {
diff --git a/src/dynamicFvMesh/dynamicRefineFvMesh/dynamicRefineFvMesh.C b/src/dynamicFvMesh/dynamicRefineFvMesh/dynamicRefineFvMesh.C
index a8b9ec79878a31c5b47a63b74aecd1690ba01b3d..5ecd3efdb9f28220ca7aa12b46ea7a021982ddf4 100644
--- a/src/dynamicFvMesh/dynamicRefineFvMesh/dynamicRefineFvMesh.C
+++ b/src/dynamicFvMesh/dynamicRefineFvMesh/dynamicRefineFvMesh.C
@@ -84,7 +84,7 @@ void Foam::dynamicRefineFvMesh::calculateProtectedCells
     {
         neiLevel[faceI-nInternalFaces()] = cellLevel[faceOwner()[faceI]];
     }
-    syncTools::swapBoundaryFaceList(*this, neiLevel, false);
+    syncTools::swapBoundaryFaceList(*this, neiLevel);
 
 
     while (true)
@@ -122,7 +122,7 @@ void Foam::dynamicRefineFvMesh::calculateProtectedCells
             }
         }
 
-        syncTools::syncFaceList(*this, seedFace, orEqOp<bool>(), false);
+        syncTools::syncFaceList(*this, seedFace, orEqOp<bool>());
 
 
         // Extend unrefineableCell
@@ -846,7 +846,7 @@ void Foam::dynamicRefineFvMesh::extendMarkedCells
         }
     }
 
-    syncTools::syncFaceList(*this, markedFace, orEqOp<bool>(), false);
+    syncTools::syncFaceList(*this, markedFace, orEqOp<bool>());
 
     // Update cells using any markedFace
     for (label faceI = 0; faceI < nInternalFaces(); faceI++)
@@ -933,7 +933,7 @@ Foam::dynamicRefineFvMesh::dynamicRefineFvMesh(const IOobject& io)
         {
             neiLevel[faceI] = cellLevel[faceOwner()[faceI]];
         }
-        syncTools::swapFaceList(*this, neiLevel, false);
+        syncTools::swapFaceList(*this, neiLevel);
 
 
         boolList protectedFace(nFaces(), false);
@@ -965,13 +965,7 @@ Foam::dynamicRefineFvMesh::dynamicRefineFvMesh(const IOobject& io)
             }
         }
 
-        syncTools::syncFaceList
-        (
-            *this,
-            protectedFace,
-            orEqOp<bool>(),
-            false
-        );
+        syncTools::syncFaceList(*this, protectedFace, orEqOp<bool>());
 
         for (label faceI = 0; faceI < nInternalFaces(); faceI++)
         {
diff --git a/src/dynamicMesh/fvMeshDistribute/fvMeshDistribute.C b/src/dynamicMesh/fvMeshDistribute/fvMeshDistribute.C
index 889f15c5f23633b45d0a32a1083855aab09fae73..7524a0723f47b55974130d83e02616c9e8720cfb 100644
--- a/src/dynamicMesh/fvMeshDistribute/fvMeshDistribute.C
+++ b/src/dynamicMesh/fvMeshDistribute/fvMeshDistribute.C
@@ -29,6 +29,9 @@ License
 #include "faceCoupleInfo.H"
 #include "processorFvPatchField.H"
 #include "processorFvsPatchField.H"
+#include "processorCyclicPolyPatch.H"
+#include "processorCyclicFvPatchField.H"
+#include "processorCyclicFvsPatchField.H"
 #include "polyTopoChange.H"
 #include "removeCells.H"
 #include "polyModifyFace.H"
@@ -128,6 +131,7 @@ void Foam::fvMeshDistribute::printMeshInfo(const fvMesh& mesh)
 {
     Pout<< "Primitives:" << nl
         << "    points       :" << mesh.nPoints() << nl
+        << "    bb           :" << boundBox(mesh.points(), false) << nl
         << "    internalFaces:" << mesh.nInternalFaces() << nl
         << "    faces        :" << mesh.nFaces() << nl
         << "    cells        :" << mesh.nCells() << nl;
@@ -187,7 +191,8 @@ void Foam::fvMeshDistribute::printCoupleInfo
     const primitiveMesh& mesh,
     const labelList& sourceFace,
     const labelList& sourceProc,
-    const labelList& sourceNewProc
+    const labelList& sourcePatch,
+    const labelList& sourceNewNbrProc
 )
 {
     Pout<< nl
@@ -202,7 +207,7 @@ void Foam::fvMeshDistribute::printCoupleInfo
             << " fc:" << mesh.faceCentres()[meshFaceI]
             << " connects to proc:" << sourceProc[bFaceI]
             << "/face:" << sourceFace[bFaceI]
-            << " which will move to proc:" << sourceNewProc[bFaceI]
+            << " which will move to proc:" << sourceNewNbrProc[bFaceI]
             << endl;
     }
 }
@@ -270,32 +275,87 @@ Foam::label Foam::fvMeshDistribute::findNonEmptyPatch() const
 }
 
 
-// Appends processorPolyPatch. Returns patchID.
-Foam::label Foam::fvMeshDistribute::addProcPatch
-(
-    const word& patchName,
-    const label nbrProc
-)
+//// Appends processorPolyPatch. Returns patchID.
+//Foam::label Foam::fvMeshDistribute::addProcPatch
+//(
+//    const word& patchName,
+//    const label nbrProc
+//)
+//{
+//    // Clear local fields and e.g. polyMesh globalMeshData.
+//    mesh_.clearOut();
+//
+//
+//    polyBoundaryMesh& polyPatches =
+//        const_cast<polyBoundaryMesh&>(mesh_.boundaryMesh());
+//    fvBoundaryMesh& fvPatches = const_cast<fvBoundaryMesh&>(mesh_.boundary());
+//
+//    if (polyPatches.findPatchID(patchName) != -1)
+//    {
+//        FatalErrorIn("fvMeshDistribute::addProcPatch(const word&, const label)")
+//            << "Cannot create patch " << patchName << " since already exists."
+//            << nl
+//            << "Current patch names:" << polyPatches.names()
+//            << exit(FatalError);
+//    }
+//
+//
+//
+//    // Add the patch
+//    // ~~~~~~~~~~~~~
+//
+//    label sz = polyPatches.size();
+//
+//    // Add polyPatch
+//    polyPatches.setSize(sz+1);
+//    polyPatches.set
+//    (
+//        sz,
+//        new processorPolyPatch
+//        (
+//            patchName,
+//            0,              // size
+//            mesh_.nFaces(),
+//            sz,
+//            mesh_.boundaryMesh(),
+//            Pstream::myProcNo(),
+//            nbrProc
+//        )
+//    );
+//    fvPatches.setSize(sz+1);
+//    fvPatches.set
+//    (
+//        sz,
+//        fvPatch::New
+//        (
+//            polyPatches[sz],  // point to newly added polyPatch
+//            mesh_.boundary()
+//        )
+//    );
+//
+//    return sz;
+//}
+
+
+// Appends polyPatch. Returns patchID.
+Foam::label Foam::fvMeshDistribute::addPatch(polyPatch* patchPtr)
 {
     // Clear local fields and e.g. polyMesh globalMeshData.
     mesh_.clearOut();
 
-
     polyBoundaryMesh& polyPatches =
         const_cast<polyBoundaryMesh&>(mesh_.boundaryMesh());
     fvBoundaryMesh& fvPatches = const_cast<fvBoundaryMesh&>(mesh_.boundary());
 
-    if (polyPatches.findPatchID(patchName) != -1)
+    if (polyPatches.findPatchID(patchPtr->name()) != -1)
     {
-        FatalErrorIn("fvMeshDistribute::addProcPatch(const word&, const label)")
-            << "Cannot create patch " << patchName << " since already exists."
-            << nl
-            << "Current patch names:" << polyPatches.names()
-            << exit(FatalError);
+        FatalErrorIn("fvMeshDistribute::addPatch(polyPatch*)")
+            << "Cannot create patch " << patchPtr->name()
+            << " since already exists." << nl
+            << "Current patch names:" << polyPatches.names() << exit(FatalError);
     }
 
 
-
     // Add the patch
     // ~~~~~~~~~~~~~
 
@@ -303,20 +363,7 @@ Foam::label Foam::fvMeshDistribute::addProcPatch
 
     // Add polyPatch
     polyPatches.setSize(sz+1);
-    polyPatches.set
-    (
-        sz,
-        new processorPolyPatch
-        (
-            patchName,
-            0,              // size
-            mesh_.nFaces(),
-            sz,
-            mesh_.boundaryMesh(),
-            Pstream::myProcNo(),
-            nbrProc
-        )
-    );
+    polyPatches.set(sz, patchPtr);
     fvPatches.setSize(sz+1);
     fvPatches.set
     (
@@ -624,25 +671,27 @@ void Foam::fvMeshDistribute::getNeighbourData
     const labelList& distribution,
     labelList& sourceFace,
     labelList& sourceProc,
-    labelList& sourceNewProc
+    labelList& sourcePatch,
+    labelList& sourceNewNbrProc
 ) const
 {
     label nBnd = mesh_.nFaces() - mesh_.nInternalFaces();
     sourceFace.setSize(nBnd);
     sourceProc.setSize(nBnd);
-    sourceNewProc.setSize(nBnd);
+    sourcePatch.setSize(nBnd);
+    sourceNewNbrProc.setSize(nBnd);
 
     const polyBoundaryMesh& patches = mesh_.boundaryMesh();
 
     // Get neighbouring meshFace labels and new processor of coupled boundaries.
     labelList nbrFaces(nBnd, -1);
-    labelList nbrNewProc(nBnd, -1);
+    labelList nbrNewNbrProc(nBnd, -1);
 
     forAll(patches, patchI)
     {
         const polyPatch& pp = patches[patchI];
 
-        if (isA<processorPolyPatch>(pp))
+        if (pp.coupled())
         {
             label offset = pp.start() - mesh_.nInternalFaces();
 
@@ -654,7 +703,7 @@ void Foam::fvMeshDistribute::getNeighbourData
             }
 
             // Which processor they will end up on
-            SubList<label>(nbrNewProc, pp.size(), offset).assign
+            SubList<label>(nbrNewNbrProc, pp.size(), offset).assign
             (
                 UIndirectList<label>(distribution, pp.faceCells())()
             );
@@ -663,8 +712,8 @@ void Foam::fvMeshDistribute::getNeighbourData
 
 
     // Exchange the boundary data
-    syncTools::swapBoundaryFaceList(mesh_, nbrFaces, false);
-    syncTools::swapBoundaryFaceList(mesh_, nbrNewProc, false);
+    syncTools::swapBoundaryFaceList(mesh_, nbrFaces);
+    syncTools::swapBoundaryFaceList(mesh_, nbrNewNbrProc);
 
 
     forAll(patches, patchI)
@@ -679,7 +728,7 @@ void Foam::fvMeshDistribute::getNeighbourData
 
             // Check which of the two faces we store.
 
-            if (Pstream::myProcNo() < procPatch.neighbProcNo())
+            if (procPatch.owner())
             {
                 // Use my local face labels
                 forAll(pp, i)
@@ -687,7 +736,7 @@ void Foam::fvMeshDistribute::getNeighbourData
                     label bndI = offset + i;
                     sourceFace[bndI] = pp.start()+i;
                     sourceProc[bndI] = Pstream::myProcNo();
-                    sourceNewProc[bndI] = nbrNewProc[bndI];
+                    sourceNewNbrProc[bndI] = nbrNewNbrProc[bndI];
                 }
             }
             else
@@ -698,7 +747,50 @@ void Foam::fvMeshDistribute::getNeighbourData
                     label bndI = offset + i;
                     sourceFace[bndI] = nbrFaces[bndI];
                     sourceProc[bndI] = procPatch.neighbProcNo();
-                    sourceNewProc[bndI] = nbrNewProc[bndI];
+                    sourceNewNbrProc[bndI] = nbrNewNbrProc[bndI];
+                }
+            }
+
+
+            label patchI = -1;
+            if (isA<processorCyclicPolyPatch>(pp))
+            {
+                patchI = refCast<const processorCyclicPolyPatch>
+                (
+                    pp
+                ).referPatchID();
+            }
+
+            forAll(pp, i)
+            {
+                label bndI = offset + i;
+                sourcePatch[bndI] = patchI;
+            }
+        }
+        else if (isA<cyclicPolyPatch>(pp))
+        {
+            const cyclicPolyPatch& cpp = refCast<const cyclicPolyPatch>(pp);
+
+            if (cpp.owner())
+            {
+                forAll(pp, i)
+                {
+                    label bndI = offset + i;
+                    sourceFace[bndI] = pp.start()+i;
+                    sourceProc[bndI] = Pstream::myProcNo();
+                    sourcePatch[bndI] = patchI;
+                    sourceNewNbrProc[bndI] = nbrNewNbrProc[bndI];
+                }
+            }
+            else
+            {
+                forAll(pp, i)
+                {
+                    label bndI = offset + i;
+                    sourceFace[bndI] = nbrFaces[bndI];
+                    sourceProc[bndI] = Pstream::myProcNo();
+                    sourcePatch[bndI] = patchI;
+                    sourceNewNbrProc[bndI] = nbrNewNbrProc[bndI];
                 }
             }
         }
@@ -708,9 +800,10 @@ void Foam::fvMeshDistribute::getNeighbourData
             forAll(pp, i)
             {
                 label bndI = offset + i;
-                sourceFace[bndI] = patchI;
+                sourceFace[bndI] = -1;
                 sourceProc[bndI] = -1;
-                sourceNewProc[bndI] = -1;
+                sourcePatch[bndI] = patchI;
+                sourceNewNbrProc[bndI] = -1;
             }
         }
     }
@@ -731,16 +824,19 @@ void Foam::fvMeshDistribute::subsetBoundaryData
 
     const labelList& sourceFace,
     const labelList& sourceProc,
-    const labelList& sourceNewProc,
+    const labelList& sourcePatch,
+    const labelList& sourceNewNbrProc,
 
     labelList& subFace,
     labelList& subProc,
-    labelList& subNewProc
+    labelList& subPatch,
+    labelList& subNewNbrProc
 )
 {
     subFace.setSize(mesh.nFaces() - mesh.nInternalFaces());
     subProc.setSize(mesh.nFaces() - mesh.nInternalFaces());
-    subNewProc.setSize(mesh.nFaces() - mesh.nInternalFaces());
+    subPatch.setSize(mesh.nFaces() - mesh.nInternalFaces());
+    subNewNbrProc.setSize(mesh.nFaces() - mesh.nInternalFaces());
 
     forAll(subFace, newBFaceI)
     {
@@ -753,6 +849,7 @@ void Foam::fvMeshDistribute::subsetBoundaryData
         {
             subFace[newBFaceI] = oldFaceI;
             subProc[newBFaceI] = Pstream::myProcNo();
+            subPatch[newBFaceI] = -1;
 
             label oldOwn = oldFaceOwner[oldFaceI];
             label oldNei = oldFaceNeighbour[oldFaceI];
@@ -760,12 +857,12 @@ void Foam::fvMeshDistribute::subsetBoundaryData
             if (oldOwn == cellMap[mesh.faceOwner()[newFaceI]])
             {
                 // We kept the owner side. Where does the neighbour move to?
-                subNewProc[newBFaceI] = oldDistribution[oldNei];
+                subNewNbrProc[newBFaceI] = oldDistribution[oldNei];
             }
             else
             {
                 // We kept the neighbour side.
-                subNewProc[newBFaceI] = oldDistribution[oldOwn];
+                subNewNbrProc[newBFaceI] = oldDistribution[oldOwn];
             }
         }
         else
@@ -775,7 +872,8 @@ void Foam::fvMeshDistribute::subsetBoundaryData
 
             subFace[newBFaceI] = sourceFace[oldBFaceI];
             subProc[newBFaceI] = sourceProc[oldBFaceI];
-            subNewProc[newBFaceI] = sourceNewProc[oldBFaceI];
+            subPatch[newBFaceI] = sourcePatch[oldBFaceI];
+            subNewNbrProc[newBFaceI] = sourceNewNbrProc[oldBFaceI];
         }
     }
 }
@@ -788,11 +886,13 @@ void Foam::fvMeshDistribute::findCouples
     const primitiveMesh& mesh,
     const labelList& sourceFace,
     const labelList& sourceProc,
+    const labelList& sourcePatch,
 
     const label domain,
     const primitiveMesh& domainMesh,
     const labelList& domainFace,
     const labelList& domainProc,
+    const labelList& domainPatch,
 
     labelList& masterCoupledFaces,
     labelList& slaveCoupledFaces
@@ -802,9 +902,16 @@ void Foam::fvMeshDistribute::findCouples
     // with same face+proc.
     HashTable<label, labelPair, labelPair::Hash<> > map(domainFace.size());
 
-    forAll(domainFace, bFaceI)
+    forAll(domainProc, bFaceI)
     {
-        map.insert(labelPair(domainFace[bFaceI], domainProc[bFaceI]), bFaceI);
+        if (domainProc[bFaceI] != -1 && domainPatch[bFaceI] == -1)
+        {
+            map.insert
+            (
+                labelPair(domainFace[bFaceI], domainProc[bFaceI]),
+                bFaceI
+            );
+        }
     }
 
 
@@ -816,7 +923,7 @@ void Foam::fvMeshDistribute::findCouples
 
     forAll(sourceFace, bFaceI)
     {
-        if (sourceProc[bFaceI] != -1)
+        if (sourceProc[bFaceI] != -1 && sourcePatch[bFaceI] == -1)
         {
             labelPair myData(sourceFace[bFaceI], sourceProc[bFaceI]);
 
@@ -934,105 +1041,202 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::fvMeshDistribute::doRemoveCells
 // the processor patchID.
 void Foam::fvMeshDistribute::addProcPatches
 (
-    const labelList& neighbourNewProc,   // processor that neighbour is on
-    labelList& procPatchID
+    const labelList& nbrProc,       // processor that neighbour is now on
+    const labelList& referPatchID,  // patchID (or -1) I originated from
+    List<Map<label> >& procPatchID
 )
 {
-    // Now use the neighbourFace/Proc to repatch the mesh. These two lists
+    // Now use the neighbourFace/Proc to repatch the mesh. These lists
     // contain for all current boundary faces the global patchID (for non-proc
     // patch) or the processor.
 
-    labelList procPatchSizes(Pstream::nProcs(), 0);
-
-    forAll(neighbourNewProc, bFaceI)
-    {
-        if (neighbourNewProc[bFaceI] != -1)
-        {
-            procPatchSizes[neighbourNewProc[bFaceI]]++;
-        }
-    }
-
-    // Per neighbour processor the label of the processor patch
     procPatchID.setSize(Pstream::nProcs());
 
-    forAll(procPatchSizes, procI)
+    forAll(nbrProc, bFaceI)
     {
-        if (procPatchSizes[procI] > 0)
-        {
-            const word patchName =
-                "procBoundary"
-              + name(Pstream::myProcNo())
-              + "to"
-              + name(procI);
+        label procI = nbrProc[bFaceI];
 
-
-            procPatchID[procI] = addProcPatch(patchName, procI);
-            addPatchFields<volScalarField>
-            (
-                processorFvPatchField<scalar>::typeName
-            );
-            addPatchFields<volVectorField>
-            (
-                processorFvPatchField<vector>::typeName
-            );
-            addPatchFields<volSphericalTensorField>
-            (
-                processorFvPatchField<sphericalTensor>::typeName
-            );
-            addPatchFields<volSymmTensorField>
-            (
-                processorFvPatchField<symmTensor>::typeName
-            );
-            addPatchFields<volTensorField>
-            (
-                processorFvPatchField<tensor>::typeName
-            );
-
-            addPatchFields<surfaceScalarField>
-            (
-                processorFvPatchField<scalar>::typeName
-            );
-            addPatchFields<surfaceVectorField>
-            (
-                processorFvPatchField<vector>::typeName
-            );
-            addPatchFields<surfaceSphericalTensorField>
-            (
-                processorFvPatchField<sphericalTensor>::typeName
-            );
-            addPatchFields<surfaceSymmTensorField>
-            (
-                processorFvPatchField<symmTensor>::typeName
-            );
-            addPatchFields<surfaceTensorField>
-            (
-                processorFvPatchField<tensor>::typeName
-            );
-        }
-        else
+        if (procI != -1 && procI != Pstream::myProcNo())
         {
-            procPatchID[procI] = -1;
+            if (!procPatchID[procI].found(referPatchID[bFaceI]))
+            {
+                // No patch for neighbour yet. Is either a normal processor
+                // patch or a processorCyclic patch.
+
+                if (referPatchID[bFaceI] == -1)
+                {
+                    // Ordinary processor boundary
+
+                    const word patchName =
+                        "procBoundary"
+                      + name(Pstream::myProcNo())
+                      + "to"
+                      + name(procI);
+
+                    procPatchID[procI].insert
+                    (
+                        referPatchID[bFaceI],
+                        addPatch
+                        (
+                            new processorPolyPatch
+                            (
+                                patchName,
+                                0,              // size
+                                mesh_.nFaces(),
+                                mesh_.boundaryMesh().size(),
+                                mesh_.boundaryMesh(),
+                                Pstream::myProcNo(),
+                                nbrProc[bFaceI]
+                            )
+                        )
+                    );
+
+                    addPatchFields<volScalarField>
+                    (
+                        processorFvPatchField<scalar>::typeName
+                    );
+                    addPatchFields<volVectorField>
+                    (
+                        processorFvPatchField<vector>::typeName
+                    );
+                    addPatchFields<volSphericalTensorField>
+                    (
+                        processorFvPatchField<sphericalTensor>::typeName
+                    );
+                    addPatchFields<volSymmTensorField>
+                    (
+                        processorFvPatchField<symmTensor>::typeName
+                    );
+                    addPatchFields<volTensorField>
+                    (
+                        processorFvPatchField<tensor>::typeName
+                    );
+
+                    addPatchFields<surfaceScalarField>
+                    (
+                        processorFvPatchField<scalar>::typeName
+                    );
+                    addPatchFields<surfaceVectorField>
+                    (
+                        processorFvPatchField<vector>::typeName
+                    );
+                    addPatchFields<surfaceSphericalTensorField>
+                    (
+                        processorFvPatchField<sphericalTensor>::typeName
+                    );
+                    addPatchFields<surfaceSymmTensorField>
+                    (
+                        processorFvPatchField<symmTensor>::typeName
+                    );
+                    addPatchFields<surfaceTensorField>
+                    (
+                        processorFvPatchField<tensor>::typeName
+                    );
+                }
+                else
+                {
+                    // Processor boundary originating from cyclic
+                    const word& cycName = mesh_.boundaryMesh()
+                    [
+                        referPatchID[bFaceI]
+                    ].name();
+
+                    const word patchName =
+                        "procBoundary"
+                      + name(Pstream::myProcNo())
+                      + "to"
+                      + name(procI)
+                      + "through"
+                      + cycName;
+
+                    procPatchID[procI].insert
+                    (
+                        referPatchID[bFaceI],
+                        addPatch
+                        (
+                            new processorCyclicPolyPatch
+                            (
+                                patchName,
+                                0,              // size
+                                mesh_.nFaces(),
+                                mesh_.boundaryMesh().size(),
+                                mesh_.boundaryMesh(),
+                                Pstream::myProcNo(),
+                                nbrProc[bFaceI],
+                                cycName
+                            )
+                        )
+                    );
+
+                    addPatchFields<volScalarField>
+                    (
+                        processorCyclicFvPatchField<scalar>::typeName
+                    );
+                    addPatchFields<volVectorField>
+                    (
+                        processorCyclicFvPatchField<vector>::typeName
+                    );
+                    addPatchFields<volSphericalTensorField>
+                    (
+                        processorCyclicFvPatchField<sphericalTensor>::typeName
+                    );
+                    addPatchFields<volSymmTensorField>
+                    (
+                        processorCyclicFvPatchField<symmTensor>::typeName
+                    );
+                    addPatchFields<volTensorField>
+                    (
+                        processorCyclicFvPatchField<tensor>::typeName
+                    );
+
+                    addPatchFields<surfaceScalarField>
+                    (
+                        processorCyclicFvPatchField<scalar>::typeName
+                    );
+                    addPatchFields<surfaceVectorField>
+                    (
+                        processorCyclicFvPatchField<vector>::typeName
+                    );
+                    addPatchFields<surfaceSphericalTensorField>
+                    (
+                        processorCyclicFvPatchField<sphericalTensor>::typeName
+                    );
+                    addPatchFields<surfaceSymmTensorField>
+                    (
+                        processorCyclicFvPatchField<symmTensor>::typeName
+                    );
+                    addPatchFields<surfaceTensorField>
+                    (
+                        processorCyclicFvPatchField<tensor>::typeName
+                    );
+                }
+            }
         }
     }
 }
 
 
 // Get boundary faces to be repatched. Is -1 or new patchID
-Foam::labelList Foam::fvMeshDistribute::getProcBoundaryPatch
+Foam::labelList Foam::fvMeshDistribute::getBoundaryPatch
 (
-    const labelList& neighbourNewProc,  // new processor per boundary face
-    const labelList& procPatchID        // patchID
+    const labelList& nbrProc,               // new processor per boundary face
+    const labelList& referPatchID,          // patchID (or -1) I originated from
+    const List<Map<label> >& procPatchID    // per proc the new procPatches
 )
 {
-    labelList patchIDs(neighbourNewProc);
+    labelList patchIDs(nbrProc);
 
-    forAll(neighbourNewProc, bFaceI)
+    forAll(nbrProc, bFaceI)
     {
-        if (neighbourNewProc[bFaceI] != -1)
+        if (nbrProc[bFaceI] == Pstream::myProcNo())
         {
-            label nbrProc = neighbourNewProc[bFaceI];
-
-            patchIDs[bFaceI] = procPatchID[nbrProc];
+            label origPatchI = referPatchID[bFaceI];
+            patchIDs[bFaceI] = origPatchI;
+        }
+        else if (nbrProc[bFaceI] != -1)
+        {
+            label origPatchI = referPatchID[bFaceI];
+            patchIDs[bFaceI] = procPatchID[nbrProc[bFaceI]][origPatchI];
         }
         else
         {
@@ -1055,7 +1259,8 @@ void Foam::fvMeshDistribute::sendMesh
 
     const labelList& sourceFace,
     const labelList& sourceProc,
-    const labelList& sourceNewProc,
+    const labelList& sourcePatch,
+    const labelList& sourceNewNbrProc,
     UOPstream& toDomain
 )
 {
@@ -1191,7 +1396,8 @@ void Foam::fvMeshDistribute::sendMesh
 
         << sourceFace
         << sourceProc
-        << sourceNewProc;
+        << sourcePatch
+        << sourceNewNbrProc;
 
 
     if (debug)
@@ -1212,7 +1418,8 @@ Foam::autoPtr<Foam::fvMesh> Foam::fvMeshDistribute::receiveMesh
     const Time& runTime,
     labelList& domainSourceFace,
     labelList& domainSourceProc,
-    labelList& domainSourceNewProc,
+    labelList& domainSourcePatch,
+    labelList& domainSourceNewNbrProc,
     UIPstream& fromNbr
 )
 {
@@ -1230,7 +1437,8 @@ Foam::autoPtr<Foam::fvMesh> Foam::fvMeshDistribute::receiveMesh
     fromNbr
         >> domainSourceFace
         >> domainSourceProc
-        >> domainSourceNewProc;
+        >> domainSourcePatch
+        >> domainSourceNewNbrProc;
 
     // Construct fvMesh
     autoPtr<fvMesh> domainMeshPtr
@@ -1448,16 +1656,37 @@ Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::fvMeshDistribute::distribute
 
     // physical boundary:
     //     sourceProc = -1
-    //     sourceNewProc = -1
-    //     sourceFace = patchID
-    // coupled boundary:
-    //     sourceProc = proc
-    //     sourceNewProc = distribution[cell on proc]
-    //     sourceFace = face
+    //     sourceNewNbrProc = -1
+    //     sourceFace = -1
+    //     sourcePatch = patchID
+    // processor boundary:
+    //     sourceProc = proc (on owner side)
+    //     sourceNewNbrProc = distribution of coupled cell
+    //     sourceFace = face (on owner side)
+    //     sourcePatch = -1
+    // ?cyclic:
+    // ?    sourceProc = proc
+    // ?    sourceNewNbrProc = distribution of coupled cell
+    // ?    sourceFace = face (on owner side)
+    // ?    sourcePatch = patchID 
+    // processor-cyclic boundary:
+    //     sourceProc = proc (on owner side)
+    //     sourceNewNbrProc = distribution of coupled cell
+    //     sourceFace = face (on owner side)
+    //     sourcePatch = patchID
+
+    labelList sourcePatch;
     labelList sourceFace;
     labelList sourceProc;
-    labelList sourceNewProc;
-    getNeighbourData(distribution, sourceFace, sourceProc, sourceNewProc);
+    labelList sourceNewNbrProc;
+    getNeighbourData
+    (
+        distribution,
+        sourceFace,
+        sourceProc,
+        sourcePatch,
+        sourceNewNbrProc
+    );
 
 
     // Remove meshPhi. Since this would otherwise disappear anyway
@@ -1529,7 +1758,8 @@ Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::fvMeshDistribute::distribute
 
         inplaceReorder(bFaceMap, sourceFace);
         inplaceReorder(bFaceMap, sourceProc);
-        inplaceReorder(bFaceMap, sourceNewProc);
+        inplaceReorder(bFaceMap, sourcePatch);
+        inplaceReorder(bFaceMap, sourceNewNbrProc);
     }
 
 
@@ -1632,7 +1862,8 @@ Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::fvMeshDistribute::distribute
             // Subset the boundary fields (owner/neighbour/processor)
             labelList procSourceFace;
             labelList procSourceProc;
-            labelList procSourceNewProc;
+            labelList procSourcePatch;
+            labelList procSourceNewNbrProc;
 
             subsetBoundaryData
             (
@@ -1647,11 +1878,13 @@ Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::fvMeshDistribute::distribute
 
                 sourceFace,
                 sourceProc,
-                sourceNewProc,
+                sourcePatch,
+                sourceNewNbrProc,
 
                 procSourceFace,
                 procSourceProc,
-                procSourceNewProc
+                procSourcePatch,
+                procSourceNewNbrProc
             );
 
 
@@ -1668,7 +1901,8 @@ Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::fvMeshDistribute::distribute
 
                 procSourceFace,
                 procSourceProc,
-                procSourceNewProc,
+                procSourcePatch,
+                procSourceNewNbrProc,
                 str
             );
             sendFields<volScalarField>(recvProc, volScalars, subsetter, str);
@@ -1771,7 +2005,8 @@ Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::fvMeshDistribute::distribute
         // fields
         labelList domainSourceFace;
         labelList domainSourceProc;
-        labelList domainSourceNewProc;
+        labelList domainSourcePatch;
+        labelList domainSourceNewNbrProc;
 
         subsetBoundaryData
         (
@@ -1786,16 +2021,19 @@ Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::fvMeshDistribute::distribute
 
             sourceFace,
             sourceProc,
-            sourceNewProc,
+            sourcePatch,
+            sourceNewNbrProc,
 
             domainSourceFace,
             domainSourceProc,
-            domainSourceNewProc
+            domainSourcePatch,
+            domainSourceNewNbrProc
         );
 
         sourceFace.transfer(domainSourceFace);
         sourceProc.transfer(domainSourceProc);
-        sourceNewProc.transfer(domainSourceNewProc);
+        sourcePatch.transfer(domainSourcePatch);
+        sourceNewNbrProc.transfer(domainSourceNewNbrProc);
     }
 
 
@@ -1848,7 +2086,8 @@ Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::fvMeshDistribute::distribute
             // Receive from sendProc
             labelList domainSourceFace;
             labelList domainSourceProc;
-            labelList domainSourceNewProc;
+            labelList domainSourcePatch;
+            labelList domainSourceNewNbrProc;
 
             autoPtr<fvMesh> domainMeshPtr;
             PtrList<volScalarField> vsf;
@@ -1874,10 +2113,14 @@ Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::fvMeshDistribute::distribute
                     const_cast<Time&>(mesh_.time()),
                     domainSourceFace,
                     domainSourceProc,
-                    domainSourceNewProc,
+                    domainSourcePatch,
+                    domainSourceNewNbrProc,
                     str
                 );
                 fvMesh& domainMesh = domainMeshPtr();
+                // Force construction of various on mesh.
+                //(void)domainMesh.globalData();
+
 
                 // Receive fields. Read as single dictionary because
                 // of problems reading consecutive fields from single stream.
@@ -2006,11 +2249,13 @@ Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::fvMeshDistribute::distribute
 
                 sourceFace,
                 sourceProc,
+                sourcePatch,
 
                 sendProc,
                 domainMesh,
                 domainSourceFace,
                 domainSourceProc,
+                domainSourcePatch,
 
                 masterCoupledFaces,
                 slaveCoupledFaces
@@ -2045,33 +2290,38 @@ Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::fvMeshDistribute::distribute
             // Update mesh data: sourceFace,sourceProc for added
             // mesh.
 
-            sourceFace =
-                mapBoundaryData
-                (
-                    mesh_,
-                    map(),
-                    sourceFace,
-                    domainMesh.nInternalFaces(),
-                    domainSourceFace
-                );
-            sourceProc =
-                mapBoundaryData
-                (
-                    mesh_,
-                    map(),
-                    sourceProc,
-                    domainMesh.nInternalFaces(),
-                    domainSourceProc
-                );
-            sourceNewProc =
-                mapBoundaryData
-                (
-                    mesh_,
-                    map(),
-                    sourceNewProc,
-                    domainMesh.nInternalFaces(),
-                    domainSourceNewProc
-                );
+            sourceFace = mapBoundaryData
+            (
+                mesh_,
+                map(),
+                sourceFace,
+                domainMesh.nInternalFaces(),
+                domainSourceFace
+            );
+            sourceProc = mapBoundaryData
+            (
+                mesh_,
+                map(),
+                sourceProc,
+                domainMesh.nInternalFaces(),
+                domainSourceProc
+            );
+            sourcePatch = mapBoundaryData
+            (
+                mesh_,
+                map(),
+                sourcePatch,
+                domainMesh.nInternalFaces(),
+                domainSourcePatch
+            );
+            sourceNewNbrProc = mapBoundaryData
+            (
+                mesh_,
+                map(),
+                sourceNewNbrProc,
+                domainMesh.nInternalFaces(),
+                domainSourceNewNbrProc
+            );
 
             // Update all addressing so xxProcAddressing points to correct item
             // in masterMesh.
@@ -2141,11 +2391,13 @@ Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::fvMeshDistribute::distribute
     // Add processorPatches
     // ~~~~~~~~~~~~~~~~~~~~
 
-    // Per neighbour processor the patchID to it (or -1).
-    labelList procPatchID;
+    // Per neighbour processor, per originating patch, the patchID
+    // For faces resulting from internal faces or normal processor patches
+    // the originating patch is -1. For cyclics this is the cyclic patchID.
+    List<Map<label> > procPatchID;
 
-    // Add processor patches.
-    addProcPatches(sourceNewProc, procPatchID);
+    // Add processor and processorCyclic patches.
+    addProcPatches(sourceNewNbrProc, sourcePatch, procPatchID);
 
     // Put faces into correct patch. Note that we now have proper
     // processorPolyPatches again so repatching will take care of coupled face
@@ -2154,9 +2406,10 @@ Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::fvMeshDistribute::distribute
     // Get boundary faces to be repatched. Is -1 or new patchID
     labelList newPatchID
     (
-        getProcBoundaryPatch
+        getBoundaryPatch
         (
-            sourceNewProc,
+            sourceNewNbrProc,
+            sourcePatch,
             procPatchID
         )
     );
diff --git a/src/dynamicMesh/fvMeshDistribute/fvMeshDistribute.H b/src/dynamicMesh/fvMeshDistribute/fvMeshDistribute.H
index 5af95fb1076fd2d8bc791a95c80cb3a9f8e66058..f85e1b53acd501a06bdcb72e48cf90287fc90bab 100644
--- a/src/dynamicMesh/fvMeshDistribute/fvMeshDistribute.H
+++ b/src/dynamicMesh/fvMeshDistribute/fvMeshDistribute.H
@@ -102,8 +102,8 @@ class fvMeshDistribute
             //- Find patch to put exposed faces into.
             label findNonEmptyPatch() const;
 
-            //- Appends processorPolyPatch. Returns patchID.
-            label addProcPatch(const word& patchName, const label nbrProc);
+            //- Appends polyPatch. Returns patchID.
+            label addPatch(polyPatch*);
 
             //- Add patch field
             template<class GeoField>
@@ -169,6 +169,7 @@ class fvMeshDistribute
                 const labelList& distribution,
                 labelList& sourceFace,
                 labelList& sourceProc,
+                labelList& sourcePatch,
                 labelList& sourceNewProc
             ) const;
 
@@ -186,10 +187,12 @@ class fvMeshDistribute
 
                 const labelList& sourceFace,
                 const labelList& sourceProc,
+                const labelList& sourcePatch,
                 const labelList& sourceNewProc,
 
                 labelList& subFace,
                 labelList& subProc,
+                labelList& subPatch,
                 labelList& subNewProc
             );
 
@@ -200,11 +203,13 @@ class fvMeshDistribute
                 const primitiveMesh&,
                 const labelList& sourceFace,
                 const labelList& sourceProc,
+                const labelList& sourcePatch,
 
                 const label domain,
                 const primitiveMesh& domainMesh,
                 const labelList& domainFace,
                 const labelList& domainProc,
+                const labelList& domainPatch,
 
                 labelList& masterCoupledFaces,
                 labelList& slaveCoupledFaces
@@ -235,15 +240,17 @@ class fvMeshDistribute
             //  proc the processor patchID.
             void addProcPatches
             (
-                const labelList&, // processor that neighbour is on
-                labelList& procPatchID
+                const labelList&, // processor that neighbour is now on
+                const labelList&, // -1 or patch that face originated from 
+                List<Map<label> >& procPatchID
             );
 
             //- Get boundary faces to be repatched. Is -1 or new patchID
-            static labelList getProcBoundaryPatch
+            static labelList getBoundaryPatch
             (
-                const labelList& neighbourNewProc,// new processor per b. face
-                const labelList& procPatchID      // patchID
+                const labelList& neighbourNewProc,  // new processor per b. face
+                const labelList& referPatchID,      // -1 or original patch
+                const List<Map<label> >& procPatchID// patchID
             );
 
             //- Send mesh and coupling data.
@@ -256,6 +263,7 @@ class fvMeshDistribute
                 const wordList& cellZoneNames,
                 const labelList& sourceFace,
                 const labelList& sourceProc,
+                const labelList& sourcePatch,
                 const labelList& sourceNewProc,
                 UOPstream& toDomain
             );
@@ -279,6 +287,7 @@ class fvMeshDistribute
                 const Time& runTime,
                 labelList& domainSourceFace,
                 labelList& domainSourceProc,
+                labelList& domainSourcePatch,
                 labelList& domainSourceNewProc,
                 UIPstream& fromNbr
             );
@@ -328,6 +337,7 @@ public:
                 const primitiveMesh&,
                 const labelList&,
                 const labelList&,
+                const labelList&,
                 const labelList&
             );
 
diff --git a/src/dynamicMesh/motionSmoother/motionSmoother.C b/src/dynamicMesh/motionSmoother/motionSmoother.C
index 5c3d79a97856578e87810318dd51ab95edf347f5..9cb0eff0754e184dc3e0b3aa3bad90b0aedeecb2 100644
--- a/src/dynamicMesh/motionSmoother/motionSmoother.C
+++ b/src/dynamicMesh/motionSmoother/motionSmoother.C
@@ -40,6 +40,80 @@ defineTypeNameAndDebug(Foam::motionSmoother, 0);
 
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
+void Foam::motionSmoother::testSyncPositions
+(
+    const pointField& fld,
+    const scalar maxMag
+) const
+{
+    pointField syncedFld(fld);
+
+    syncTools::syncPointPositions
+    (
+        mesh_,
+        syncedFld,
+        minEqOp<point>(),           // combine op
+        point(GREAT,GREAT,GREAT)    // null
+    );
+
+    forAll(syncedFld, i)
+    {
+        if (mag(syncedFld[i] - fld[i]) > maxMag)
+        {
+            FatalErrorIn
+            (
+                "motionSmoother::testSyncPositions(const pointField&)"
+            )   << "On point " << i << " point:" << fld[i]
+                << " synchronised point:" << syncedFld[i]
+                << abort(FatalError);
+        }
+    }    
+}
+
+
+//Foam::tmp<Foam::scalarField> Foam::motionSmoother::sumWeights
+//(
+//    const scalarField& edgeWeight
+//) const
+//{
+//    tmp<scalarField> tsumWeight
+//    (
+//        new scalarField
+//        (
+//            mesh_.nPoints(),
+//            0.0
+//        )
+//    );
+//    scalarField& sumWeight = tsumWeight();
+//
+//    const edgeList& edges = mesh_.edges();
+//
+//    forAll(edges, edgeI)
+//    {
+//        if (isMasterEdge_.get(edgeI) == 1)
+//        {
+//            const edge& e = edges[edgeI];
+//            const scalar w = edgeWeight[edgeI];
+//            sumWeight[e[0]] += w;
+//            sumWeight[e[1]] += w;
+//        }
+//    }
+//
+//
+//    // Add coupled contributions
+//    // ~~~~~~~~~~~~~~~~~~~~~~~~~
+//    syncTools::syncPointList
+//    (
+//        mesh,
+//        sumWeight,
+//        plusEqOp<scalar>(),
+//        scalar(0)               // null value
+//    );
+//
+//    return tsumWeight;
+//}
+
+
 // From pointPatchInterpolation
 void Foam::motionSmoother::makePatchPatchAddressing()
 {
@@ -209,8 +283,7 @@ void Foam::motionSmoother::minSmooth
     tmp<pointScalarField> tavgFld = avg
     (
         fld,
-        scalarField(mesh_.nEdges(), 1.0),   // uniform weighting
-        false                               // fld is not position.
+        scalarField(mesh_.nEdges(), 1.0)    // uniform weighting
     );
     const pointScalarField& avgFld = tavgFld();
 
@@ -243,8 +316,7 @@ void Foam::motionSmoother::minSmooth
     tmp<pointScalarField> tavgFld = avg
     (
         fld,
-        scalarField(mesh_.nEdges(), 1.0),   // uniform weighting
-        false                               // fld is not position.
+        scalarField(mesh_.nEdges(), 1.0)    // uniform weighting
     );
     const pointScalarField& avgFld = tavgFld();
 
@@ -612,8 +684,7 @@ void Foam::motionSmoother::setDisplacement(pointField& patchDisp)
         mesh_,
         displacement_,
         maxMagEqOp(),   // combine op
-        vector::zero,   // null value
-        false           // no separation
+        vector::zero    // null value
     );
 
     // Adapt the fixedValue bc's (i.e. copy internal point data to
@@ -718,8 +789,7 @@ void Foam::motionSmoother::correctBoundaryConditions
         mesh_,
         displacement,
         maxMagEqOp(),           // combine op
-        vector::zero,           // null value
-        false                   // no separation
+        vector::zero            // null value
     );
 }
 
@@ -769,14 +839,7 @@ Foam::tmp<Foam::scalarField> Foam::motionSmoother::movePoints
     {
         Pout<< "motionSmoother::movePoints : testing sync of newPoints."
             << endl;
-        testSyncField
-        (
-            newPoints,
-            minEqOp<point>(),           // combine op
-            vector(GREAT,GREAT,GREAT),  // null
-            true,                       // separation
-            1E-6*mesh_.bounds().mag()
-        );
+        testSyncPositions(newPoints, 1E-6*mesh_.bounds().mag());
     }
 
     tmp<scalarField> tsweptVol = mesh_.movePoints(newPoints);
@@ -894,8 +957,7 @@ bool Foam::motionSmoother::scaleMesh
         mesh_,
         displacement_,
         maxMagEqOp(),
-        vector::zero,   // null value
-        false           // no separation
+        vector::zero    // null value
     );
 
     // Set newPoints as old + scale*displacement
@@ -926,7 +988,6 @@ bool Foam::motionSmoother::scaleMesh
                 totalDisplacement,
                 maxMagEqOp(),
                 vector::zero,   // null value
-                false,          // separation
                 1E-6*mesh_.bounds().mag()
             );
         }
@@ -1056,8 +1117,7 @@ bool Foam::motionSmoother::scaleMesh
             mesh_,
             scale_,
             maxEqOp<scalar>(),
-            -GREAT,             // null value
-            false               // no separation
+            -GREAT              // null value
         );
 
 
diff --git a/src/dynamicMesh/motionSmoother/motionSmoother.H b/src/dynamicMesh/motionSmoother/motionSmoother.H
index ee306dd3c9a2eed2ba5dd137897ff9a7a38c370a..729cbb28a558890cbfd4d50547c7be6019ac1b56 100644
--- a/src/dynamicMesh/motionSmoother/motionSmoother.H
+++ b/src/dynamicMesh/motionSmoother/motionSmoother.H
@@ -183,8 +183,15 @@ class motionSmoother
         tmp<GeometricField<Type, pointPatchField, pointMesh> > avg
         (
             const GeometricField<Type, pointPatchField, pointMesh>& fld,
-            const scalarField& edgeWeight,
-            const bool separation
+            const scalarField& edgeWeight
+        ) const;
+
+        //- Average postion of connected points.
+        template <class Type>
+        tmp<GeometricField<Type, pointPatchField, pointMesh> > avgPositions
+        (
+            const GeometricField<Type, pointPatchField, pointMesh>& fld,
+            const scalarField& edgeWeight
         ) const;
 
         //- Check constraints
@@ -201,17 +208,19 @@ class motionSmoother
             GeometricField<Type, pointPatchField, pointMesh>&
         ) const;
 
-        //- Test synchronisation of pointField
+        //- Test synchronisation of generic field (not positions!) on points
         template<class Type, class CombineOp>
         void testSyncField
         (
             const Field<Type>&,
             const CombineOp& cop,
             const Type& zero,
-            const bool separation,
             const scalar maxMag
         ) const;
 
+        //- Test synchronisation of points
+        void testSyncPositions(const pointField&, const scalar maxMag) const;
+
         //- Assemble tensors for multi-patch constraints
         void makePatchPatchAddressing();
 
@@ -476,14 +485,13 @@ public:
 
             // Helper functions to manipulate displacement vector.
 
-                //- Fully explicit smoothing of internal points with varying
-                //  diffusivity.
+                //- Fully explicit smoothing of fields (not positions)
+                //  of internal points with varying diffusivity.
                 template <class Type>
                 void smooth
                 (
                     const GeometricField<Type, pointPatchField, pointMesh>& fld,
                     const scalarField& edgeWeight,
-                    const bool separation,
                     GeometricField<Type, pointPatchField, pointMesh>& newFld
                 ) const;
 };
diff --git a/src/dynamicMesh/motionSmoother/motionSmootherTemplates.C b/src/dynamicMesh/motionSmoother/motionSmootherTemplates.C
index 1660a29e18decf00024f479d9a6a8bf5f50c700f..a444276c195136a0cf2883e493dfd7b8a7ca2464 100644
--- a/src/dynamicMesh/motionSmoother/motionSmootherTemplates.C
+++ b/src/dynamicMesh/motionSmoother/motionSmootherTemplates.C
@@ -155,11 +155,10 @@ void Foam::motionSmoother::applyCornerConstraints
 // Average of connected points.
 template <class Type>
 Foam::tmp<Foam::GeometricField<Type, Foam::pointPatchField, Foam::pointMesh> >
- Foam::motionSmoother::avg
+Foam::motionSmoother::avg
 (
     const GeometricField<Type, pointPatchField, pointMesh>& fld,
-    const scalarField& edgeWeight,
-    const bool separation
+    const scalarField& edgeWeight
 ) const
 {
     tmp<GeometricField<Type, pointPatchField, pointMesh> > tres
@@ -172,7 +171,8 @@ Foam::tmp<Foam::GeometricField<Type, Foam::pointPatchField, Foam::pointMesh> >
                 fld.time().timeName(),
                 fld.db(),
                 IOobject::NO_READ,
-                IOobject::NO_WRITE
+                IOobject::NO_WRITE,
+                false
             ),
             fld.mesh(),
             dimensioned<Type>("zero", fld.dimensions(), pTraits<Type>::zero)
@@ -217,17 +217,14 @@ Foam::tmp<Foam::GeometricField<Type, Foam::pointPatchField, Foam::pointMesh> >
         mesh,
         res,
         plusEqOp<Type>(),
-        pTraits<Type>::zero,    // null value
-        separation              // separation
+        pTraits<Type>::zero     // null value
     );
-
     syncTools::syncPointList
     (
         mesh,
         sumWeight,
         plusEqOp<scalar>(),
-        scalar(0),              // null value
-        false                   // separation
+        scalar(0)               // null value
     );
 
 
@@ -260,16 +257,10 @@ void Foam::motionSmoother::smooth
 (
     const GeometricField<Type, pointPatchField, pointMesh>& fld,
     const scalarField& edgeWeight,
-    const bool separation,
     GeometricField<Type, pointPatchField, pointMesh>& newFld
 ) const
 {
-    tmp<pointVectorField> tavgFld = avg
-    (
-        fld,
-        edgeWeight, // weighting
-        separation  // whether to apply separation vector
-    );
+    tmp<pointVectorField> tavgFld = avg(fld, edgeWeight);
     const pointVectorField& avgFld = tavgFld();
 
     forAll(fld, pointI)
@@ -285,14 +276,13 @@ void Foam::motionSmoother::smooth
 }
 
 
-//- Test synchronisation of pointField
+//- Test synchronisation of generic field (not positions!) on points
 template<class Type, class CombineOp>
 void Foam::motionSmoother::testSyncField
 (
     const Field<Type>& fld,
     const CombineOp& cop,
     const Type& zero,
-    const bool separation,
     const scalar maxMag
 ) const
 {
@@ -309,13 +299,11 @@ void Foam::motionSmoother::testSyncField
         mesh_,
         syncedFld,
         cop,
-        zero,       // null value
-        separation  // separation
+        zero
     );
 
     forAll(syncedFld, i)
     {
-        if (syncedFld[i] != fld[i])
         if (mag(syncedFld[i] - fld[i]) > maxMag)
         {
             FatalErrorIn
diff --git a/src/dynamicMesh/motionSmoother/polyMeshGeometry/polyMeshGeometry.C b/src/dynamicMesh/motionSmoother/polyMeshGeometry/polyMeshGeometry.C
index a4c05fe4126d17e91ed75ae242aa65cfa34c5155..b79089bf044879ac87613037f6485e3d6d746e72 100644
--- a/src/dynamicMesh/motionSmoother/polyMeshGeometry/polyMeshGeometry.C
+++ b/src/dynamicMesh/motionSmoother/polyMeshGeometry/polyMeshGeometry.C
@@ -425,13 +425,13 @@ bool Foam::polyMeshGeometry::checkFaceDotProduct
 
 
     // Calculate coupled cell centre
-    vectorField neiCc(mesh.nFaces()-mesh.nInternalFaces());
+    pointField neiCc(mesh.nFaces()-mesh.nInternalFaces());
 
     for (label faceI = mesh.nInternalFaces(); faceI < mesh.nFaces(); faceI++)
     {
         neiCc[faceI-mesh.nInternalFaces()] = cellCentres[own[faceI]];
     }
-    syncTools::swapBoundaryFaceList(mesh, neiCc, true);
+    syncTools::swapBoundaryFacePositions(mesh, neiCc);
 
 
     scalar minDDotS = GREAT;
@@ -927,13 +927,13 @@ bool Foam::polyMeshGeometry::checkFaceSkewness
     const polyBoundaryMesh& patches = mesh.boundaryMesh();
 
     // Calculate coupled cell centre
-    vectorField neiCc(mesh.nFaces()-mesh.nInternalFaces());
+    pointField neiCc(mesh.nFaces()-mesh.nInternalFaces());
 
     for (label faceI = mesh.nInternalFaces(); faceI < mesh.nFaces(); faceI++)
     {
         neiCc[faceI-mesh.nInternalFaces()] = cellCentres[own[faceI]];
     }
-    syncTools::swapBoundaryFaceList(mesh, neiCc, true);
+    syncTools::swapBoundaryFacePositions(mesh, neiCc);
 
 
     scalar maxSkew = 0;
@@ -1135,13 +1135,13 @@ bool Foam::polyMeshGeometry::checkFaceWeights
     const polyBoundaryMesh& patches = mesh.boundaryMesh();
 
     // Calculate coupled cell centre
-    vectorField neiCc(mesh.nFaces()-mesh.nInternalFaces());
+    pointField neiCc(mesh.nFaces()-mesh.nInternalFaces());
 
     for (label faceI = mesh.nInternalFaces(); faceI < mesh.nFaces(); faceI++)
     {
         neiCc[faceI-mesh.nInternalFaces()] = cellCentres[own[faceI]];
     }
-    syncTools::swapBoundaryFaceList(mesh, neiCc, true);
+    syncTools::swapBoundaryFacePositions(mesh, neiCc);
 
 
     scalar minWeight = GREAT;
@@ -1298,7 +1298,7 @@ bool Foam::polyMeshGeometry::checkVolRatio
     {
         neiVols[faceI-mesh.nInternalFaces()] = cellVolumes[own[faceI]];
     }
-    syncTools::swapBoundaryFaceList(mesh, neiVols, true);
+    syncTools::swapBoundaryFaceList(mesh, neiVols);
 
 
     scalar minRatio = GREAT;
@@ -1641,13 +1641,13 @@ bool Foam::polyMeshGeometry::checkFaceTwist
     const polyBoundaryMesh& patches = mesh.boundaryMesh();
 
     // Calculate coupled cell centre
-    vectorField neiCc(mesh.nFaces()-mesh.nInternalFaces());
+    pointField neiCc(mesh.nFaces()-mesh.nInternalFaces());
 
     for (label faceI = mesh.nInternalFaces(); faceI < mesh.nFaces(); faceI++)
     {
         neiCc[faceI-mesh.nInternalFaces()] = cellCentres[own[faceI]];
     }
-    syncTools::swapBoundaryFaceList(mesh, neiCc, true);
+    syncTools::swapBoundaryFacePositions(mesh, neiCc);
 
     forAll(checkFaces, i)
     {
diff --git a/src/dynamicMesh/polyTopoChange/polyTopoChange/addPatchCellLayer.C b/src/dynamicMesh/polyTopoChange/polyTopoChange/addPatchCellLayer.C
index 9105db90237a277097b97aeccc2f756c138f2621..170052341d98007089273d72455e50e3d3d707c6 100644
--- a/src/dynamicMesh/polyTopoChange/polyTopoChange/addPatchCellLayer.C
+++ b/src/dynamicMesh/polyTopoChange/polyTopoChange/addPatchCellLayer.C
@@ -34,6 +34,7 @@ License
 #include "polyModifyFace.H"
 #include "polyAddCell.H"
 #include "globalIndex.H"
+#include "dummyTransform.H"
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
@@ -103,8 +104,8 @@ Foam::labelListList Foam::addPatchCellLayer::calcGlobalEdgeFaces
         mesh,
         globalEdgeFaces,
         uniqueEqOp(),
-        labelList(),    // null value
-        false           // no separation
+        labelList(),            // null value
+        Foam::dummyTransform()  // dummy transform
     );
 
     // Extract pp part
@@ -636,7 +637,7 @@ void Foam::addPatchCellLayer::setRefinement
         {
             labelList n(mesh_.nPoints(), 0);
             UIndirectList<label>(n, meshPoints) = nPointLayers;
-            syncTools::syncPointList(mesh_, n, maxEqOp<label>(), 0, false);
+            syncTools::syncPointList(mesh_, n, maxEqOp<label>(), 0);
 
             // Non-synced
             forAll(meshPoints, i)
@@ -680,8 +681,7 @@ void Foam::addPatchCellLayer::setRefinement
                 mesh_,
                 nFromFace,
                 maxEqOp<label>(),
-                0,
-                false
+                0
             );
 
             forAll(nPointLayers, i)
@@ -718,8 +718,7 @@ void Foam::addPatchCellLayer::setRefinement
                 mesh_,
                 d,
                 minEqOp<vector>(),
-                vector::max,
-                false
+                vector::max
             );
 
             forAll(meshPoints, i)
@@ -1190,8 +1189,7 @@ void Foam::addPatchCellLayer::setRefinement
             mesh_,
             meshEdgeLayers,
             maxEqOp<label>(),
-            0,                  // initial value
-            false               // no separation
+            0                   // initial value
         );
 
         forAll(meshEdges, edgeI)
diff --git a/src/dynamicMesh/polyTopoChange/polyTopoChange/combineFaces.C b/src/dynamicMesh/polyTopoChange/polyTopoChange/combineFaces.C
index 5dc59ad815b8ff84bfb64c6f72d18cad81a90377..83414d1c98c0d16290c3e8d218290642346b576f 100644
--- a/src/dynamicMesh/polyTopoChange/polyTopoChange/combineFaces.C
+++ b/src/dynamicMesh/polyTopoChange/polyTopoChange/combineFaces.C
@@ -708,8 +708,7 @@ void Foam::combineFaces::setRefinement
         mesh_,
         nPointFaces,
         plusEqOp<label>(),
-        0,                  // null value
-        false               // no separation
+        0                   // null value
     );
 
     // Remove all unused points. Store position if undoable.
diff --git a/src/dynamicMesh/polyTopoChange/polyTopoChange/hexRef8.C b/src/dynamicMesh/polyTopoChange/polyTopoChange/hexRef8.C
index 5a5e108134e953f6564de1328637da534cbe471d..ea2479c07edb42dac165c64dbe1f385b0f6626c0 100644
--- a/src/dynamicMesh/polyTopoChange/polyTopoChange/hexRef8.C
+++ b/src/dynamicMesh/polyTopoChange/polyTopoChange/hexRef8.C
@@ -412,8 +412,7 @@ Foam::scalar Foam::hexRef8::getLevel0EdgeLength() const
             mesh_,
             edgeLevel,
             ifEqEqOp<labelMax>(),
-            labelMin,
-            false               // no separation
+            labelMin
         );
 
         // Now use the edgeLevel with a valid value to determine the
@@ -1618,7 +1617,7 @@ Foam::label Foam::hexRef8::faceConsistentRefinement
     }
 
     // Swap to neighbour
-    syncTools::swapBoundaryFaceList(mesh_, neiLevel, false);
+    syncTools::swapBoundaryFaceList(mesh_, neiLevel);
 
     // Now we have neighbour value see which cells need refinement
     forAll(neiLevel, i)
@@ -1700,7 +1699,7 @@ void Foam::hexRef8::checkWantedRefinementLevels
     }
 
     // Swap to neighbour
-    syncTools::swapBoundaryFaceList(mesh_, neiLevel, false);
+    syncTools::swapBoundaryFaceList(mesh_, neiLevel);
 
     // Now we have neighbour value see which cells need refinement
     forAll(neiLevel, i)
@@ -2369,8 +2368,7 @@ Foam::labelList Foam::hexRef8::consistentSlowRefinement
             mesh_,
             maxPointCount,
             maxEqOp<label>(),
-            labelMin,           // null value
-            false               // no separation
+            labelMin            // null value
         );
 
         // Update allFaceInfo from maxPointCount for all points to check
@@ -2509,9 +2507,9 @@ Foam::labelList Foam::hexRef8::consistentSlowRefinement
         }
 
         // Swap to neighbour
-        syncTools::swapBoundaryFaceList(mesh_, neiLevel, false);
-        syncTools::swapBoundaryFaceList(mesh_, neiCount, false);
-        syncTools::swapBoundaryFaceList(mesh_, neiRefCount, false);
+        syncTools::swapBoundaryFaceList(mesh_, neiLevel);
+        syncTools::swapBoundaryFaceList(mesh_, neiCount);
+        syncTools::swapBoundaryFaceList(mesh_, neiRefCount);
 
         // Now we have neighbour value see which cells need refinement
         forAll(neiLevel, i)
@@ -3156,8 +3154,7 @@ Foam::labelListList Foam::hexRef8::setRefinement
         mesh_,
         edgeMidPoint,
         maxEqOp<label>(),
-        labelMin,
-        false               // no separation
+        labelMin
     );
 
 
@@ -3179,13 +3176,12 @@ Foam::labelListList Foam::hexRef8::setRefinement
                 edgeMids[edgeI] = mesh_.edges()[edgeI].centre(mesh_.points());
             }
         }
-        syncTools::syncEdgeList
+        syncTools::syncEdgePositions
         (
             mesh_,
             edgeMids,
             maxEqOp<vector>(),
-            point(-GREAT, -GREAT, -GREAT),
-            true               // apply separation
+            point(-GREAT, -GREAT, -GREAT)
         );
 
 
@@ -3310,7 +3306,7 @@ Foam::labelListList Foam::hexRef8::setRefinement
         }
 
         // Swap.
-        syncTools::swapBoundaryFaceList(mesh_, newNeiLevel, false);
+        syncTools::swapBoundaryFaceList(mesh_, newNeiLevel);
 
         // So now we have information on the neighbour.
 
@@ -3342,8 +3338,7 @@ Foam::labelListList Foam::hexRef8::setRefinement
     (
         mesh_,
         faceMidPoint,
-        maxEqOp<label>(),
-        false
+        maxEqOp<label>()
     );
 
 
@@ -3369,12 +3364,11 @@ Foam::labelListList Foam::hexRef8::setRefinement
                 bFaceMids[i] = mesh_.faceCentres()[faceI];
             }
         }
-        syncTools::syncBoundaryFaceList
+        syncTools::syncBoundaryFacePositions
         (
             mesh_,
             bFaceMids,
-            maxEqOp<vector>(),
-            true               // apply separation
+            maxEqOp<vector>()
         );
 
         forAll(faceMidPoint, faceI)
@@ -4404,7 +4398,7 @@ void Foam::hexRef8::checkMesh() const
         }
 
         // Replace data on coupled patches with their neighbour ones.
-        syncTools::swapBoundaryFaceList(mesh_, nei, false);
+        syncTools::swapBoundaryFaceList(mesh_, nei);
 
         const polyBoundaryMesh& patches = mesh_.boundaryMesh();
 
@@ -4459,7 +4453,7 @@ void Foam::hexRef8::checkMesh() const
         }
 
         // Replace data on coupled patches with their neighbour ones.
-        syncTools::swapBoundaryFaceList(mesh_, neiFaceAreas, false);
+        syncTools::swapBoundaryFaceList(mesh_, neiFaceAreas);
 
         forAll(neiFaceAreas, i)
         {
@@ -4502,7 +4496,7 @@ void Foam::hexRef8::checkMesh() const
         }
 
         // Replace data on coupled patches with their neighbour ones.
-        syncTools::swapBoundaryFaceList(mesh_, nVerts, false);
+        syncTools::swapBoundaryFaceList(mesh_, nVerts);
 
         forAll(nVerts, i)
         {
@@ -4551,7 +4545,7 @@ void Foam::hexRef8::checkMesh() const
         // Replace data on coupled patches with their neighbour ones. Apply
         // rotation transformation (but not separation since is relative vector
         // to point on same face.
-        syncTools::swapBoundaryFaceList(mesh_, anchorPoints, false);
+        syncTools::swapBoundaryFaceList(mesh_, anchorPoints);
 
         forAll(anchorPoints, i)
         {
@@ -4656,7 +4650,7 @@ void Foam::hexRef8::checkRefinementLevels
         }
 
         // No separation
-        syncTools::swapBoundaryFaceList(mesh_, neiLevel, false);
+        syncTools::swapBoundaryFaceList(mesh_, neiLevel);
 
         forAll(neiLevel, i)
         {
@@ -4698,8 +4692,7 @@ void Foam::hexRef8::checkRefinementLevels
             mesh_,
             syncPointLevel,
             minEqOp<label>(),
-            labelMax,
-            false               // no separation
+            labelMax
         );
 
 
@@ -4746,8 +4739,7 @@ void Foam::hexRef8::checkRefinementLevels
             mesh_,
             maxPointLevel,
             maxEqOp<label>(),
-            labelMin,           // null value
-            false               // no separation
+            labelMin            // null value
         );
 
         // Check 2:1 across boundary points
@@ -5197,7 +5189,7 @@ Foam::labelList Foam::hexRef8::consistentUnrefinement
         }
 
         // Swap to neighbour
-        syncTools::swapBoundaryFaceList(mesh_, neiLevel, false);
+        syncTools::swapBoundaryFaceList(mesh_, neiLevel);
 
         forAll(neiLevel, i)
         {
diff --git a/src/dynamicMesh/polyTopoChange/polyTopoChange/localPointRegion.C b/src/dynamicMesh/polyTopoChange/polyTopoChange/localPointRegion.C
index ab83b55415688f9c757244feea1d83aaefad583e..e7028e6424054c5fa04e5be905c32bd1780c007d 100644
--- a/src/dynamicMesh/polyTopoChange/polyTopoChange/localPointRegion.C
+++ b/src/dynamicMesh/polyTopoChange/polyTopoChange/localPointRegion.C
@@ -29,6 +29,7 @@ License
 #include "mapPolyMesh.H"
 #include "globalIndex.H"
 #include "indirectPrimitivePatch.H"
+#include "dummyTransform.H"
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
@@ -57,15 +58,6 @@ public:
     };
 };
 
-
-// Dummy transform for faces. Used in synchronisation
-void transformList
-(
-    const tensorField& rotTensor,
-    UList<face>& field
-)
-{};
-
 }
 
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
@@ -263,8 +255,7 @@ void Foam::localPointRegion::calcPointRegions
         mesh,
         candidatePoint,
         orEqOp<bool>(),
-        false,              // nullValue
-        false               // applySeparation
+        false               // nullValue
     );
 
 
@@ -419,12 +410,18 @@ void Foam::localPointRegion::calcPointRegions
         // Transport minimum across coupled faces
         // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-        syncTools::syncFaceList
+        SubList<face> l
         (
-            mesh,
             minRegion,
+            mesh.nFaces()-mesh.nInternalFaces(),
+            mesh.nInternalFaces()
+        );
+        syncTools::syncBoundaryFaceList
+        (
+            mesh,
+            l,
             minEqOpFace(),
-            false               // applySeparation
+            Foam::dummyTransform()  // dummy transformation
         );
     }
 
diff --git a/src/dynamicMesh/polyTopoChange/polyTopoChange/removeCells.C b/src/dynamicMesh/polyTopoChange/polyTopoChange/removeCells.C
index 2560de3471afd4ef7844ae518b7389d68903389f..c778b65d0ad80c05578883c09ca4dbce0f35ae5c 100644
--- a/src/dynamicMesh/polyTopoChange/polyTopoChange/removeCells.C
+++ b/src/dynamicMesh/polyTopoChange/polyTopoChange/removeCells.C
@@ -130,8 +130,7 @@ Foam::labelList Foam::removeCells::getExposedFaces
         (
             mesh_,
             nCellsUsingFace,
-            plusEqOp<label>(),
-            false
+            plusEqOp<label>()
         );
     }
 
diff --git a/src/dynamicMesh/polyTopoChange/polyTopoChange/removeFaces.C b/src/dynamicMesh/polyTopoChange/polyTopoChange/removeFaces.C
index 7b01c6dbcc4b0112098206ce93e67a3453938c2a..e6eebc5c3f1609af59ffa30d311daec906831440 100644
--- a/src/dynamicMesh/polyTopoChange/polyTopoChange/removeFaces.C
+++ b/src/dynamicMesh/polyTopoChange/polyTopoChange/removeFaces.C
@@ -1084,8 +1084,7 @@ void Foam::removeFaces::setRefinement
             mesh_,
             nFacesPerEdge,
             maxEqOp<label>(),
-            labelMin,               // guaranteed to be overridden by maxEqOp
-            false                   // no separation
+            labelMin                // guaranteed to be overridden by maxEqOp
         );
 
         // Convert to labelHashSet
@@ -1187,8 +1186,7 @@ void Foam::removeFaces::setRefinement
         syncTools::swapFaceList
         (
             mesh_,
-            nbrFaceRegion,
-            false                   // no separation
+            nbrFaceRegion
         );
 
         labelList toNbrRegion(nRegions, -1);
@@ -1305,8 +1303,7 @@ void Foam::removeFaces::setRefinement
             mesh_,
             nEdgesPerPoint,
             maxEqOp<label>(),
-            labelMin,
-            false                   // no separation
+            labelMin 
         );
 
         forAll(nEdgesPerPoint, pointI)
diff --git a/src/dynamicMesh/polyTopoChange/polyTopoChange/removePoints.C b/src/dynamicMesh/polyTopoChange/polyTopoChange/removePoints.C
index 92ba164bb82de00df1319b2d2f31f5a869585d7c..e793d9ea33c6626d33f833ad4fd9799ca9d2d57c 100644
--- a/src/dynamicMesh/polyTopoChange/polyTopoChange/removePoints.C
+++ b/src/dynamicMesh/polyTopoChange/polyTopoChange/removePoints.C
@@ -33,6 +33,7 @@ License
 #include "polyModifyFace.H"
 #include "syncTools.H"
 #include "faceSet.H"
+#include "dummyTransform.H"
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
@@ -41,6 +42,55 @@ namespace Foam
 
 defineTypeNameAndDebug(removePoints, 0);
 
+//- Combine-reduce operator to combine data on faces. Takes care
+//  of reverse orientation on coupled face.
+template <class T, template<class> class CombineOp>
+class faceEqOp
+{
+
+public:
+
+    void operator()(List<T>& x, const List<T>& y) const
+    {
+        if (y.size() > 0)
+        {
+            if (x.size() == 0)
+            {
+                x = y;
+            }
+            else
+            {
+                label j = 0;
+                forAll(x, i)
+                {
+                    CombineOp<T>()(x[i], y[j]);
+                    j = y.rcIndex(j);
+                }
+            }
+        }
+    }
+};
+
+
+//// Dummy transform for List. Used in synchronisation.
+//template <class T>
+//class dummyTransformList
+//{
+//public:
+//    void operator()(const coupledPolyPatch&, Field<List<T> >&) const
+//    {}
+//};
+//// Dummy template specialisation. Used in synchronisation.
+//template<>
+//class pTraits<boolList>
+//{
+//public:
+//
+//    //- Component type
+//    typedef label cmptType;
+//};
+
+
 }
 
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
@@ -247,8 +297,7 @@ Foam::label Foam::removePoints::countPointUsage
         mesh_,
         pointCanBeDeleted,
         andEqOp<bool>(),
-        true,               // null value
-        false               // no separation
+        true                // null value
     );
 
     return returnReduce(nDeleted, sumOp<label>());
@@ -662,7 +711,7 @@ void Foam::removePoints::getUnrefimentSet
             mesh_,
             faceVertexRestore,
             faceEqOp<bool, orEqOp>(),   // special operator to handle faces
-            false                       // no separation
+            Foam::dummyTransform()      // no transformation
         );
 
         // So now if any of the points-to-restore is used by any coupled face
diff --git a/src/dynamicMesh/polyTopoChange/polyTopoChange/removePoints.H b/src/dynamicMesh/polyTopoChange/polyTopoChange/removePoints.H
index d9fd959a2c9ad6c2ee7ab8c1073ba8eb4e2a467a..f44e57684d04807b2061d9b23c75f10abdfb3780 100644
--- a/src/dynamicMesh/polyTopoChange/polyTopoChange/removePoints.H
+++ b/src/dynamicMesh/polyTopoChange/polyTopoChange/removePoints.H
@@ -59,38 +59,6 @@ class face;
 class removePoints
 {
 
-    // Private classes
-
-        //- Combine-reduce operator to combine data on faces. Takes care
-        //  of reverse orientation on coupled face.
-        template <class T, template<class> class CombineOp>
-        class faceEqOp
-        {
-
-        public:
-
-            void operator()(List<T>& x, const List<T>& y) const
-            {
-                if (y.size() > 0)
-                {
-                    if (x.empty())
-                    {
-                        x = y;
-                    }
-                    else
-                    {
-                        label j = 0;
-                        forAll(x, i)
-                        {
-                            CombineOp<T>()(x[i], y[j]);
-                            j = y.rcIndex(j);
-                        }
-                    }
-                }
-            }
-        };
-
-
     // Private data
 
         //- Reference to mesh
diff --git a/src/finiteVolume/Make/files b/src/finiteVolume/Make/files
index 2d1b6effb07c56e11d577f8a6dbcad0737b6af23..85714b5f9cf76bbded048864bc6a4440d2e44741 100644
--- a/src/finiteVolume/Make/files
+++ b/src/finiteVolume/Make/files
@@ -21,6 +21,7 @@ $(constraintFvPatches)/symmetry/symmetryFvPatch.C
 $(constraintFvPatches)/wedge/wedgeFvPatch.C
 $(constraintFvPatches)/cyclic/cyclicFvPatch.C
 $(constraintFvPatches)/processor/processorFvPatch.C
+$(constraintFvPatches)/processorCyclic/processorCyclicFvPatch.C
 
 derivedFvPatches = $(fvPatches)/derived
 $(derivedFvPatches)/wall/wallFvPatch.C
@@ -99,6 +100,8 @@ $(constraintFvPatchFields)/empty/emptyFvPatchFields.C
 $(constraintFvPatchFields)/jumpCyclic/jumpCyclicFvPatchFields.C
 $(constraintFvPatchFields)/processor/processorFvPatchFields.C
 $(constraintFvPatchFields)/processor/processorFvPatchScalarField.C
+$(constraintFvPatchFields)/processorCyclic/processorCyclicFvPatchFields.C
+$(constraintFvPatchFields)/processorCyclic/processorCyclicFvPatchScalarField.C
 $(constraintFvPatchFields)/symmetry/symmetryFvPatchFields.C
 $(constraintFvPatchFields)/wedge/wedgeFvPatchFields.C
 $(constraintFvPatchFields)/wedge/wedgeFvPatchScalarField.C
@@ -106,6 +109,7 @@ $(constraintFvPatchFields)/wedge/wedgeFvPatchScalarField.C
 derivedFvPatchFields = $(fvPatchFields)/derived
 $(derivedFvPatchFields)/activeBaffleVelocity/activeBaffleVelocityFvPatchVectorField.C
 $(derivedFvPatchFields)/advective/advectiveFvPatchFields.C
+
 $(derivedFvPatchFields)/directMappedFixedValue/directMappedFixedValueFvPatchFields.C
 $(derivedFvPatchFields)/directMappedVelocityFluxFixedValue/directMappedVelocityFluxFixedValueFvPatchField.C
 $(derivedFvPatchFields)/fan/fanFvPatchFields.C
@@ -165,6 +169,7 @@ constraintFvsPatchFields = $(fvsPatchFields)/constraint
 $(constraintFvsPatchFields)/cyclic/cyclicFvsPatchFields.C
 $(constraintFvsPatchFields)/empty/emptyFvsPatchFields.C
 $(constraintFvsPatchFields)/processor/processorFvsPatchFields.C
+$(constraintFvsPatchFields)/processorCyclic/processorCyclicFvsPatchFields.C
 $(constraintFvsPatchFields)/symmetry/symmetryFvsPatchFields.C
 $(constraintFvsPatchFields)/wedge/wedgeFvsPatchFields.C
 
diff --git a/src/finiteVolume/fields/fvPatchFields/constraint/cyclic/cyclicFvPatchField.C b/src/finiteVolume/fields/fvPatchFields/constraint/cyclic/cyclicFvPatchField.C
index 77ad9595b2769d74fd5c26b434105dca7e20a7b2..b0faf1caac38176e3d8f607545c3483793a170dd 100644
--- a/src/finiteVolume/fields/fvPatchFields/constraint/cyclic/cyclicFvPatchField.C
+++ b/src/finiteVolume/fields/fvPatchFields/constraint/cyclic/cyclicFvPatchField.C
@@ -24,6 +24,7 @@ License
 \*---------------------------------------------------------------------------*/
 
 #include "cyclicFvPatchField.H"
+#include "transformField.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -141,34 +142,28 @@ template<class Type>
 tmp<Field<Type> > cyclicFvPatchField<Type>::patchNeighbourField() const
 {
     const Field<Type>& iField = this->internalField();
-    const unallocLabelList& faceCells = cyclicPatch_.faceCells();
+    const unallocLabelList& nbrFaceCells =
+        cyclicPatch().cyclicPatch().neighbPatch().faceCells();
 
     tmp<Field<Type> > tpnf(new Field<Type>(this->size()));
     Field<Type>& pnf = tpnf();
 
-    label sizeby2 = this->size()/2;
 
     if (doTransform())
     {
-        for (label facei=0; facei<sizeby2; facei++)
+        forAll(pnf, facei)
         {
             pnf[facei] = transform
             (
-                forwardT()[0], iField[faceCells[facei + sizeby2]]
-            );
-
-            pnf[facei + sizeby2] = transform
-            (
-                reverseT()[0], iField[faceCells[facei]]
+                forwardT()[0], iField[nbrFaceCells[facei]]
             );
         }
     }
     else
     {
-        for (label facei=0; facei<sizeby2; facei++)
+        forAll(pnf, facei)
         {
-            pnf[facei] = iField[faceCells[facei + sizeby2]];
-            pnf[facei + sizeby2] = iField[faceCells[facei]];
+            pnf[facei] = iField[nbrFaceCells[facei]];
         }
     }
 
@@ -189,19 +184,20 @@ void cyclicFvPatchField<Type>::updateInterfaceMatrix
 {
     scalarField pnf(this->size());
 
-    label sizeby2 = this->size()/2;
-    const unallocLabelList& faceCells = cyclicPatch_.faceCells();
+    const unallocLabelList& nbrFaceCells =
+        cyclicPatch().cyclicPatch().neighbPatch().faceCells();
 
-    for (label facei=0; facei<sizeby2; facei++)
+    forAll(pnf, facei)
     {
-        pnf[facei] = psiInternal[faceCells[facei + sizeby2]];
-        pnf[facei + sizeby2] = psiInternal[faceCells[facei]];
+        pnf[facei] = psiInternal[nbrFaceCells[facei]];
     }
 
     // Transform according to the transformation tensors
     transformCoupleField(pnf, cmpt);
 
     // Multiply the field by coefficients and add into the result
+    const unallocLabelList& faceCells = cyclicPatch_.faceCells();
+
     forAll(faceCells, elemI)
     {
         result[faceCells[elemI]] -= coeffs[elemI]*pnf[elemI];
diff --git a/src/finiteVolume/fields/fvPatchFields/constraint/jumpCyclic/jumpCyclicFvPatchField.C b/src/finiteVolume/fields/fvPatchFields/constraint/jumpCyclic/jumpCyclicFvPatchField.C
index 4b6b4660ffb6aa7d9d2a9c211604563e7dbfdecc..1c4d5f84a39dac075cc5f2c70dd56cdddcac0993 100644
--- a/src/finiteVolume/fields/fvPatchFields/constraint/jumpCyclic/jumpCyclicFvPatchField.C
+++ b/src/finiteVolume/fields/fvPatchFields/constraint/jumpCyclic/jumpCyclicFvPatchField.C
@@ -99,37 +99,34 @@ template<class Type>
 tmp<Field<Type> > jumpCyclicFvPatchField<Type>::patchNeighbourField() const
 {
     const Field<Type>& iField = this->internalField();
-    const unallocLabelList& faceCells = this->cyclicPatch().faceCells();
+    const unallocLabelList& nbrFaceCells =
+        this->cyclicPatch().neighbFvPatch().faceCells();
 
     tmp<Field<Type> > tpnf(new Field<Type>(this->size()));
     Field<Type>& pnf = tpnf();
 
     tmp<Field<scalar> > tjf = jump();
+    if (!this->cyclicPatch().owner())
+    {
+        tjf = -tjf;
+    }
     const Field<scalar>& jf = tjf();
 
-    label sizeby2 = this->size()/2;
-
     if (this->doTransform())
     {
-        for (label facei=0; facei<sizeby2; facei++)
+        forAll(*this, facei)
         {
             pnf[facei] = transform
             (
-                this->forwardT()[0], iField[faceCells[facei + sizeby2]]
+                this->forwardT()[0], iField[nbrFaceCells[facei]]
             ) - jf[facei];
-
-            pnf[facei + sizeby2] = transform
-            (
-                this->reverseT()[0], iField[faceCells[facei]] + jf[facei]
-            );
         }
     }
     else
     {
-        for (label facei=0; facei<sizeby2; facei++)
+        forAll(*this, facei)
         {
-            pnf[facei] = iField[faceCells[facei + sizeby2]] - jf[facei];
-            pnf[facei + sizeby2] = iField[faceCells[facei]] + jf[facei];
+            pnf[facei] = iField[nbrFaceCells[facei]] - jf[facei];
         }
     }
 
@@ -150,26 +147,28 @@ void jumpCyclicFvPatchField<Type>::updateInterfaceMatrix
 {
     scalarField pnf(this->size());
 
-    label sizeby2 = this->size()/2;
-    const unallocLabelList& faceCells = this->cyclicPatch().faceCells();
+    const unallocLabelList& nbrFaceCells =
+        this->cyclicPatch().neighbFvPatch().faceCells();
 
     if (&psiInternal == &this->internalField())
     {
         tmp<Field<scalar> > tjf = jump();
+        if (!this->cyclicPatch().owner())
+        {
+            tjf = -tjf;
+        }
         const Field<scalar>& jf = tjf();
 
-        for (label facei=0; facei<sizeby2; facei++)
+        forAll(*this, facei)
         {
-            pnf[facei] = psiInternal[faceCells[facei + sizeby2]] - jf[facei];
-            pnf[facei + sizeby2] = psiInternal[faceCells[facei]] + jf[facei];
+            pnf[facei] = psiInternal[nbrFaceCells[facei]] - jf[facei];
         }
     }
     else
     {
-        for (label facei=0; facei<sizeby2; facei++)
+        forAll(*this, facei)
         {
-            pnf[facei] = psiInternal[faceCells[facei + sizeby2]];
-            pnf[facei + sizeby2] = psiInternal[faceCells[facei]];
+            pnf[facei] = psiInternal[nbrFaceCells[facei]];
         }
     }
 
@@ -177,6 +176,7 @@ void jumpCyclicFvPatchField<Type>::updateInterfaceMatrix
     this->transformCoupleField(pnf, cmpt);
 
     // Multiply the field by coefficients and add into the result
+    const unallocLabelList& faceCells = this->cyclicPatch().faceCells();
     forAll(faceCells, elemI)
     {
         result[faceCells[elemI]] -= coeffs[elemI]*pnf[elemI];
diff --git a/src/finiteVolume/fields/fvPatchFields/constraint/processor/processorFvPatchField.C b/src/finiteVolume/fields/fvPatchFields/constraint/processor/processorFvPatchField.C
index 1e4e55637dd4d5cb0c1a176fbb2b379b27d3a276..9b287f8fa7431c39f323c8f5c60a03122a6152ff 100644
--- a/src/finiteVolume/fields/fvPatchFields/constraint/processor/processorFvPatchField.C
+++ b/src/finiteVolume/fields/fvPatchFields/constraint/processor/processorFvPatchField.C
@@ -73,7 +73,7 @@ processorFvPatchField<Type>::processorFvPatchField
     coupledFvPatchField<Type>(ptf, p, iF, mapper),
     procPatch_(refCast<const processorFvPatch>(p))
 {
-    if (!isType<processorFvPatch>(this->patch()))
+    if (!isA<processorFvPatch>(this->patch()))
     {
         FatalErrorIn
         (
@@ -105,7 +105,7 @@ processorFvPatchField<Type>::processorFvPatchField
     coupledFvPatchField<Type>(p, iF, dict),
     procPatch_(refCast<const processorFvPatch>(p))
 {
-    if (!isType<processorFvPatch>(p))
+    if (!isA<processorFvPatch>(p))
     {
         FatalIOErrorIn
         (
diff --git a/src/finiteVolume/fields/fvPatchFields/constraint/processorCyclic/processorCyclicFvPatchField.C b/src/finiteVolume/fields/fvPatchFields/constraint/processorCyclic/processorCyclicFvPatchField.C
new file mode 100644
index 0000000000000000000000000000000000000000..4b688ee853df447a38a8453883ced394ca969992
--- /dev/null
+++ b/src/finiteVolume/fields/fvPatchFields/constraint/processorCyclic/processorCyclicFvPatchField.C
@@ -0,0 +1,266 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
+     \\/     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 2 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, write to the Free Software Foundation,
+    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+\*---------------------------------------------------------------------------*/
+
+#include "processorCyclicFvPatchField.H"
+#include "processorCyclicFvPatch.H"
+#include "demandDrivenData.H"
+#include "transformField.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
+
+template<class Type>
+processorCyclicFvPatchField<Type>::processorCyclicFvPatchField
+(
+    const fvPatch& p,
+    const DimensionedField<Type, volMesh>& iF
+)
+:
+    processorFvPatchField<Type>(p, iF),
+    procPatch_(refCast<const processorCyclicFvPatch>(p))
+{}
+
+
+template<class Type>
+processorCyclicFvPatchField<Type>::processorCyclicFvPatchField
+(
+    const fvPatch& p,
+    const DimensionedField<Type, volMesh>& iF,
+    const Field<Type>& f
+)
+:
+    //coupledFvPatchField<Type>(p, iF, f),
+    processorFvPatchField<Type>(p, iF, f),
+    procPatch_(refCast<const processorCyclicFvPatch>(p))
+{}
+
+
+// Construct by mapping given processorCyclicFvPatchField<Type>
+template<class Type>
+processorCyclicFvPatchField<Type>::processorCyclicFvPatchField
+(
+    const processorCyclicFvPatchField<Type>& ptf,
+    const fvPatch& p,
+    const DimensionedField<Type, volMesh>& iF,
+    const fvPatchFieldMapper& mapper
+)
+:
+    //coupledFvPatchField<Type>(ptf, p, iF, mapper),
+    processorFvPatchField<Type>(ptf, p, iF, mapper),
+    procPatch_(refCast<const processorCyclicFvPatch>(p))
+{
+    if (!isType<processorCyclicFvPatch>(this->patch()))
+    {
+        FatalErrorIn
+        (
+            "processorCyclicFvPatchField<Type>::processorCyclicFvPatchField\n"
+            "(\n"
+            "    const processorCyclicFvPatchField<Type>& ptf,\n"
+            "    const fvPatch& p,\n"
+            "    const DimensionedField<Type, volMesh>& iF,\n"
+            "    const fvPatchFieldMapper& mapper\n"
+            ")\n"
+        )   << "\n    patch type '" << p.type()
+            << "' not constraint type '" << typeName << "'"
+            << "\n    for patch " << p.name()
+            << " of field " << this->dimensionedInternalField().name()
+            << " in file " << this->dimensionedInternalField().objectPath()
+            << exit(FatalIOError);
+    }
+}
+
+
+template<class Type>
+processorCyclicFvPatchField<Type>::processorCyclicFvPatchField
+(
+    const fvPatch& p,
+    const DimensionedField<Type, volMesh>& iF,
+    const dictionary& dict
+)
+:
+    //coupledFvPatchField<Type>(p, iF, dict),
+    processorFvPatchField<Type>(p, iF, dict),
+    procPatch_(refCast<const processorCyclicFvPatch>(p))
+{
+    if (!isType<processorCyclicFvPatch>(p))
+    {
+        FatalIOErrorIn
+        (
+            "processorCyclicFvPatchField<Type>::processorCyclicFvPatchField\n"
+            "(\n"
+            "    const fvPatch& p,\n"
+            "    const Field<Type>& field,\n"
+            "    const dictionary& dict\n"
+            ")\n",
+            dict
+        )   << "\n    patch type '" << p.type()
+            << "' not constraint type '" << typeName << "'"
+            << "\n    for patch " << p.name()
+            << " of field " << this->dimensionedInternalField().name()
+            << " in file " << this->dimensionedInternalField().objectPath()
+            << exit(FatalIOError);
+    }
+}
+
+
+template<class Type>
+processorCyclicFvPatchField<Type>::processorCyclicFvPatchField
+(
+    const processorCyclicFvPatchField<Type>& ptf
+)
+:
+    //processorLduInterfaceField(),
+    //coupledFvPatchField<Type>(ptf),
+    processorFvPatchField<Type>(ptf),
+    procPatch_(refCast<const processorCyclicFvPatch>(ptf.patch()))
+{}
+
+
+template<class Type>
+processorCyclicFvPatchField<Type>::processorCyclicFvPatchField
+(
+    const processorCyclicFvPatchField<Type>& ptf,
+    const DimensionedField<Type, volMesh>& iF
+)
+:
+    //coupledFvPatchField<Type>(ptf, iF),
+    processorFvPatchField<Type>(ptf, iF),
+    procPatch_(refCast<const processorCyclicFvPatch>(ptf.patch()))
+{}
+
+
+// * * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * //
+
+template<class Type>
+processorCyclicFvPatchField<Type>::~processorCyclicFvPatchField()
+{}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+//template<class Type>
+//tmp<Field<Type> > processorCyclicFvPatchField<Type>::patchNeighbourField() const
+//{
+//    return *this;
+//}
+//
+//
+//template<class Type>
+//void processorCyclicFvPatchField<Type>::initEvaluate
+//(
+//    const Pstream::commsTypes commsType
+//)
+//{
+//    if (Pstream::parRun())
+//    {
+//        procPatch_.compressedSend(commsType, this->patchInternalField()());
+//    }
+//}
+//
+//
+//template<class Type>
+//void processorCyclicFvPatchField<Type>::evaluate
+//(
+//    const Pstream::commsTypes commsType
+//)
+//{
+//    if (Pstream::parRun())
+//    {
+//        procPatch_.compressedReceive<Type>(commsType, *this);
+//
+//        if (doTransform())
+//        {
+//            transform(*this, procPatch_.forwardT(), *this);
+//        }
+//    }
+//}
+//
+//
+//template<class Type>
+//tmp<Field<Type> > processorCyclicFvPatchField<Type>::snGrad() const
+//{
+//    return this->patch().deltaCoeffs()*(*this - this->patchInternalField());
+//}
+//
+//
+//template<class Type>
+//void processorCyclicFvPatchField<Type>::initInterfaceMatrixUpdate
+//(
+//    const scalarField& psiInternal,
+//    scalarField&,
+//    const lduMatrix&,
+//    const scalarField&,
+//    const direction,
+//    const Pstream::commsTypes commsType
+//) const
+//{
+//    procPatch_.compressedSend
+//    (
+//        commsType,
+//        this->patch().patchInternalField(psiInternal)()
+//    );
+//}
+//
+//
+//template<class Type>
+//void processorCyclicFvPatchField<Type>::updateInterfaceMatrix
+//(
+//    const scalarField&,
+//    scalarField& result,
+//    const lduMatrix&,
+//    const scalarField& coeffs,
+//    const direction cmpt,
+//    const Pstream::commsTypes commsType
+//) const
+//{
+//    scalarField pnf
+//    (
+//        procPatch_.compressedReceive<scalar>(commsType, this->size())()
+//    );
+//
+//    // Transform according to the transformation tensor
+//    transformCoupleField(pnf, cmpt);
+//
+//    // Multiply the field by coefficients and add into the result
+//
+//    const unallocLabelList& faceCells = this->patch().faceCells();
+//
+//    forAll(faceCells, elemI)
+//    {
+//        result[faceCells[elemI]] -= coeffs[elemI]*pnf[elemI];
+//    }
+//}
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// ************************************************************************* //
diff --git a/src/finiteVolume/fields/fvPatchFields/constraint/processorCyclic/processorCyclicFvPatchField.H b/src/finiteVolume/fields/fvPatchFields/constraint/processorCyclic/processorCyclicFvPatchField.H
new file mode 100644
index 0000000000000000000000000000000000000000..3df31b88a756073b6df63d0dae421840e702290e
--- /dev/null
+++ b/src/finiteVolume/fields/fvPatchFields/constraint/processorCyclic/processorCyclicFvPatchField.H
@@ -0,0 +1,338 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
+     \\/     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 2 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, write to the Free Software Foundation,
+    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+Class
+    Foam::processorCyclicFvPatchField
+
+Description
+    Foam::processorCyclicFvPatchField
+
+SourceFiles
+    processorCyclicFvPatchField.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef processorCyclicFvPatchField_H
+#define processorCyclicFvPatchField_H
+
+//#include "coupledFvPatchField.H"
+//#include "processorLduInterfaceField.H"
+#include "processorCyclicFvPatch.H"
+#include "processorFvPatchField.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+                      Class processorCyclicFvPatch Declaration
+\*---------------------------------------------------------------------------*/
+
+template<class Type>
+class processorCyclicFvPatchField
+:
+//    public processorLduInterfaceField,
+//    public coupledFvPatchField<Type>
+    public processorFvPatchField<Type>
+{
+    // Private data
+
+        //- Local reference cast into the processor patch
+        const processorCyclicFvPatch& procPatch_;
+
+    // Private Member Functions
+
+//        //- Get other patchfield
+//        const coupledFvPatchField<Type>& patchField(const label patchID) const;
+public:
+
+    //- Runtime type information
+    TypeName(processorCyclicFvPatch::typeName_());
+
+
+    // Constructors
+
+        //- Construct from patch and internal field
+        processorCyclicFvPatchField
+        (
+            const fvPatch&,
+            const DimensionedField<Type, volMesh>&
+        );
+
+        //- Construct from patch and internal field and patch field
+        processorCyclicFvPatchField
+        (
+            const fvPatch&,
+            const DimensionedField<Type, volMesh>&,
+            const Field<Type>&
+        );
+
+        //- Construct from patch, internal field and dictionary
+        processorCyclicFvPatchField
+        (
+            const fvPatch&,
+            const DimensionedField<Type, volMesh>&,
+            const dictionary&
+        );
+
+        //- Construct by mapping given processorCyclicFvPatchField onto a
+        //  new patch
+        processorCyclicFvPatchField
+        (
+            const processorCyclicFvPatchField<Type>&,
+            const fvPatch&,
+            const DimensionedField<Type, volMesh>&,
+            const fvPatchFieldMapper&
+        );
+
+        //- Construct as copy
+        processorCyclicFvPatchField(const processorCyclicFvPatchField<Type>&);
+
+        //- Construct and return a clone
+        virtual tmp<fvPatchField<Type> > clone() const
+        {
+            return tmp<fvPatchField<Type> >
+            (
+                new processorCyclicFvPatchField<Type>(*this)
+            );
+        }
+
+        //- Construct as copy setting internal field reference
+        processorCyclicFvPatchField
+        (
+            const processorCyclicFvPatchField<Type>&,
+            const DimensionedField<Type, volMesh>&
+        );
+
+        //- Construct and return a clone setting internal field reference
+        virtual tmp<fvPatchField<Type> > clone
+        (
+            const DimensionedField<Type, volMesh>& iF
+        ) const
+        {
+            return tmp<fvPatchField<Type> >
+            (
+                new processorCyclicFvPatchField<Type>(*this, iF)
+            );
+        }
+
+
+    // Destructor
+
+        ~processorCyclicFvPatchField();
+
+
+    // Member functions
+
+        // Access
+
+//            //- Return true if running parallel
+//            virtual bool coupled() const
+//            {
+//                if (Pstream::parRun())
+//                {
+//                    return true;
+//                }
+//                else
+//                {
+//                    return false;
+//                }
+//            }
+//
+//            //- Return neighbour field given internal field
+//            tmp<Field<Type> > patchNeighbourField() const;
+//
+//
+//        // Evaluation functions
+//
+//            //- Initialise the evaluation of the patch field
+//            virtual void initEvaluate(const Pstream::commsTypes commsType);
+//
+//            //- Evaluate the patch field
+//            virtual void evaluate(const Pstream::commsTypes commsType);
+//
+//            //- Return patch-normal gradient
+//            virtual tmp<Field<Type> > snGrad() const;
+//
+//            //- Initialise neighbour matrix update
+//            virtual void initInterfaceMatrixUpdate
+//            (
+//                const scalarField& psiInternal,
+//                scalarField& result,
+//                const lduMatrix& m,
+//                const scalarField& coeffs,
+//                const direction cmpt,
+//                const Pstream::commsTypes commsType
+//            ) const;
+//
+//            //- Update result field based on interface functionality
+//            virtual void updateInterfaceMatrix
+//            (
+//                const scalarField& psiInternal,
+//                scalarField& result,
+//                const lduMatrix& m,
+//                const scalarField& coeffs,
+//                const direction cmpt,
+//                const Pstream::commsTypes commsType
+//            ) const;
+//
+//        //- Processor coupled interface functions
+//
+//            //- Return processor number
+//            virtual int myProcNo() const
+//            {
+//                return procPatch_.myProcNo();
+//            }
+//
+//            //- Return neigbour processor number
+//            virtual int neighbProcNo() const
+//            {
+//                return procPatch_.neighbProcNo();
+//            }
+
+            //- Does the patch field perform the transfromation
+            virtual bool doTransform() const
+            {
+                return !(procPatch_.parallel() || pTraits<Type>::rank == 0);
+            }
+
+            //- Return face transformation tensor
+            virtual const tensorField& forwardT() const
+            {
+                return procPatch_.forwardT();
+            }
+
+//            //- Return rank of component for transform
+//            virtual int rank() const
+//            {
+//                return pTraits<Type>::rank;
+//            }
+
+//            //- Transform given patch component field
+//            void transformCoupleField
+//            (
+//                scalarField& f,
+//                const direction cmpt
+//            ) const;
+
+//        // Referred-patch functionality. Get called with a slice (size, start)
+//        // of a patch that supplies fields and geometry/topology.
+//
+//            //- Get patch-normal gradient
+//            virtual void snGrad
+//            (
+//                Field<Type>& exchangeBuf,
+//                const Field<Type>& subFld,
+//                const coupledFvPatch& referringPatch,
+//                const label size,
+//                const label start
+//            ) const
+//            {
+//                notImplemented("processorCyclicFvPatchField::snGrad(..)");
+//            }
+//
+//            //- Initialise the evaluation of the patch field.
+//            virtual void initEvaluate
+//            (
+//                Field<Type>& exchangeBuf,
+//                const coupledFvPatch& referringPatch,
+//                const label size,
+//                const label start
+//            ) const
+//            {
+//                notImplemented("processorCyclicFvPatchField::initEvaluate(..)");
+//            }
+//
+//            //- Evaluate the patch field.
+//            virtual void evaluate
+//            (
+//                Field<Type>& exchangeBuf,
+//                const coupledFvPatch& referringPatch,
+//                const label size,
+//                const label start
+//            ) const
+//            {
+//                notImplemented("processorCyclicFvPatchField::evaluate(..)");
+//            }
+//
+//            //- Initialise neighbour matrix update
+//            virtual void initInterfaceMatrixUpdate
+//            (
+//                const scalarField& psiInternal,
+//                scalarField& result,
+//                const lduMatrix& m,
+//                const scalarField& coeffs,
+//                const direction cmpt,
+//                const coupledFvPatch& referringPatch,
+//                const label size,
+//                const label start,
+//                scalarField& exchangeBuf
+//            ) const
+//            {
+//                notImplemented
+//                (
+//                    "processorCyclicFvPatchField::initInterfaceMatrixUpdate(..)"
+//                );
+//            }
+//
+//            //- Update result field based on interface functionality
+//            virtual void updateInterfaceMatrix
+//            (
+//                const scalarField& psiInternal,
+//                scalarField& result,
+//                const lduMatrix&,
+//                const scalarField& coeffs,
+//                const direction,
+//                const coupledFvPatch& referringPatch,
+//                const label size,
+//                const label start,
+//                scalarField& exchangeBuf
+//            ) const
+//            {
+//                notImplemented
+//                (
+//                    "processorCyclicFvPatchField::updateInterfaceMatrix(..)"
+//                );
+//            }
+
+
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#ifdef NoRepository
+#   include "processorCyclicFvPatchField.C"
+#endif
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/finiteVolume/fields/fvPatchFields/constraint/processorCyclic/processorCyclicFvPatchFields.C b/src/finiteVolume/fields/fvPatchFields/constraint/processorCyclic/processorCyclicFvPatchFields.C
new file mode 100644
index 0000000000000000000000000000000000000000..3f11c04ce8286b82a02f1133308b060ebc36a860
--- /dev/null
+++ b/src/finiteVolume/fields/fvPatchFields/constraint/processorCyclic/processorCyclicFvPatchFields.C
@@ -0,0 +1,45 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
+     \\/     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 2 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, write to the Free Software Foundation,
+    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+\*---------------------------------------------------------------------------*/
+
+#include "processorCyclicFvPatchFields.H"
+#include "addToRunTimeSelectionTable.H"
+#include "volFields.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+makePatchFields(processorCyclic);
+//makePatchTypeField(fvPatchScalarField, processorCyclicFvPatchScalarField);
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// ************************************************************************* //
diff --git a/src/finiteVolume/fields/fvPatchFields/constraint/processorCyclic/processorCyclicFvPatchFields.H b/src/finiteVolume/fields/fvPatchFields/constraint/processorCyclic/processorCyclicFvPatchFields.H
new file mode 100644
index 0000000000000000000000000000000000000000..e4ea110ee83a2b1169c39fa870c44df60781e3c7
--- /dev/null
+++ b/src/finiteVolume/fields/fvPatchFields/constraint/processorCyclic/processorCyclicFvPatchFields.H
@@ -0,0 +1,50 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
+     \\/     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 2 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, write to the Free Software Foundation,
+    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef processorCyclicFvPatchFields_H
+#define processorCyclicFvPatchFields_H
+
+#include "processorCyclicFvPatchScalarField.H"
+#include "fieldTypes.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+makePatchTypeFieldTypedefs(processorCyclic)
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/finiteVolume/fields/fvPatchFields/constraint/processorCyclic/processorCyclicFvPatchFieldsFwd.H b/src/finiteVolume/fields/fvPatchFields/constraint/processorCyclic/processorCyclicFvPatchFieldsFwd.H
new file mode 100644
index 0000000000000000000000000000000000000000..32465f89bdfb4a9b637d133d6017f593f4aa1313
--- /dev/null
+++ b/src/finiteVolume/fields/fvPatchFields/constraint/processorCyclic/processorCyclicFvPatchFieldsFwd.H
@@ -0,0 +1,51 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
+     \\/     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 2 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, write to the Free Software Foundation,
+    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef processorCyclicFvPatchFieldsFwd_H
+#define processorCyclicFvPatchFieldsFwd_H
+
+#include "fieldTypes.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+template<class Type> class processorCyclicFvPatchField;
+
+makePatchTypeFieldTypedefs(processor)
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/finiteVolume/fields/fvPatchFields/constraint/processorCyclic/processorCyclicFvPatchScalarField.C b/src/finiteVolume/fields/fvPatchFields/constraint/processorCyclic/processorCyclicFvPatchScalarField.C
new file mode 100644
index 0000000000000000000000000000000000000000..9283a96691bb30e1dece847435cc51b0872e7026
--- /dev/null
+++ b/src/finiteVolume/fields/fvPatchFields/constraint/processorCyclic/processorCyclicFvPatchScalarField.C
@@ -0,0 +1,84 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
+     \\/     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 2 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, write to the Free Software Foundation,
+    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+\*---------------------------------------------------------------------------*/
+
+#include "processorCyclicFvPatchScalarField.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+//template<>
+//void processorCyclicFvPatchField<scalar>::initInterfaceMatrixUpdate
+//(
+//    const scalarField& psiInternal,
+//    scalarField&,
+//    const lduMatrix&,
+//    const scalarField&,
+//    const direction,
+//    const Pstream::commsTypes commsType
+//) const
+//{
+//    procPatch_.compressedSend
+//    (
+//        commsType,
+//        patch().patchInternalField(psiInternal)()
+//    );
+//}
+//
+//
+//template<>
+//void processorCyclicFvPatchField<scalar>::updateInterfaceMatrix
+//(
+//    const scalarField&,
+//    scalarField& result,
+//    const lduMatrix&,
+//    const scalarField& coeffs,
+//    const direction,
+//    const Pstream::commsTypes commsType
+//) const
+//{
+//    scalarField pnf
+//    (
+//        procPatch_.compressedReceive<scalar>(commsType, this->size())()
+//    );
+//
+//    const unallocLabelList& faceCells = patch().faceCells();
+//
+//    forAll(faceCells, facei)
+//    {
+//        result[faceCells[facei]] -= coeffs[facei]*pnf[facei];
+//    }
+//}
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// ************************************************************************* //
diff --git a/src/finiteVolume/fields/fvPatchFields/constraint/processorCyclic/processorCyclicFvPatchScalarField.H b/src/finiteVolume/fields/fvPatchFields/constraint/processorCyclic/processorCyclicFvPatchScalarField.H
new file mode 100644
index 0000000000000000000000000000000000000000..ddbe013dc44b4945bf9e8e2d115e60fa7d65afdc
--- /dev/null
+++ b/src/finiteVolume/fields/fvPatchFields/constraint/processorCyclic/processorCyclicFvPatchScalarField.H
@@ -0,0 +1,72 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
+     \\/     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 2 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, write to the Free Software Foundation,
+    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef processorCyclicFvPatchScalarField_H
+#define processorCyclicFvPatchScalarField_H
+
+#include "processorCyclicFvPatchField.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+//template<>
+//void processorCyclicFvPatchField<scalar>::initInterfaceMatrixUpdate
+//(
+//    const scalarField&,
+//    scalarField&,
+//    const lduMatrix&,
+//    const scalarField&,
+//    const direction,
+//    const Pstream::commsTypes commsType
+//) const;
+//
+//
+//template<>
+//void processorCyclicFvPatchField<scalar>::updateInterfaceMatrix
+//(
+//    const scalarField&,
+//    scalarField& result,
+//    const lduMatrix&,
+//    const scalarField& coeffs,
+//    const direction,
+//    const Pstream::commsTypes commsType
+//) const;
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/finiteVolume/fields/fvPatchFields/derived/activeBaffleVelocity/activeBaffleVelocityFvPatchVectorField.C b/src/finiteVolume/fields/fvPatchFields/derived/activeBaffleVelocity/activeBaffleVelocityFvPatchVectorField.C
index 2b9fd7434944c31bcf4384cd6500c7d61d0c6f24..c7288f621f1fb8778b4aef14310fe5a8b3bf3e20 100644
--- a/src/finiteVolume/fields/fvPatchFields/derived/activeBaffleVelocity/activeBaffleVelocityFvPatchVectorField.C
+++ b/src/finiteVolume/fields/fvPatchFields/derived/activeBaffleVelocity/activeBaffleVelocityFvPatchVectorField.C
@@ -27,6 +27,7 @@ License
 #include "addToRunTimeSelectionTable.H"
 #include "volFields.H"
 #include "surfaceFields.H"
+#include "cyclicFvPatch.H"
 
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
@@ -44,6 +45,7 @@ activeBaffleVelocityFvPatchVectorField
     orientation_(1),
     initWallSf_(0),
     initCyclicSf_(0),
+    nbrCyclicSf_(0),
     openFraction_(0),
     openingTime_(0),
     maxOpenFractionDelta_(0),
@@ -67,6 +69,7 @@ activeBaffleVelocityFvPatchVectorField
     orientation_(ptf.orientation_),
     initWallSf_(ptf.initWallSf_),
     initCyclicSf_(ptf.initCyclicSf_),
+    nbrCyclicSf_(ptf.nbrCyclicSf_),
     openFraction_(ptf.openFraction_),
     openingTime_(ptf.openingTime_),
     maxOpenFractionDelta_(ptf.maxOpenFractionDelta_),
@@ -89,6 +92,13 @@ activeBaffleVelocityFvPatchVectorField
     orientation_(readLabel(dict.lookup("orientation"))),
     initWallSf_(p.Sf()),
     initCyclicSf_(p.boundaryMesh()[cyclicPatchLabel_].Sf()),
+    nbrCyclicSf_
+    (
+        refCast<const cyclicFvPatch>
+        (
+            p.boundaryMesh()[cyclicPatchLabel_]
+        ).neighbFvPatch().Sf()
+    ),
     openFraction_(readScalar(dict.lookup("openFraction"))),
     openingTime_(readScalar(dict.lookup("openingTime"))),
     maxOpenFractionDelta_(readScalar(dict.lookup("maxOpenFractionDelta"))),
@@ -111,6 +121,7 @@ activeBaffleVelocityFvPatchVectorField
     orientation_(ptf.orientation_),
     initWallSf_(ptf.initWallSf_),
     initCyclicSf_(ptf.initCyclicSf_),
+    nbrCyclicSf_(ptf.nbrCyclicSf_),
     openFraction_(ptf.openFraction_),
     openingTime_(ptf.openingTime_),
     maxOpenFractionDelta_(ptf.maxOpenFractionDelta_),
@@ -132,6 +143,7 @@ activeBaffleVelocityFvPatchVectorField
     orientation_(ptf.orientation_),
     initWallSf_(ptf.initWallSf_),
     initCyclicSf_(ptf.initCyclicSf_),
+    nbrCyclicSf_(ptf.nbrCyclicSf_),
     openFraction_(ptf.openFraction_),
     openingTime_(ptf.openingTime_),
     maxOpenFractionDelta_(ptf.maxOpenFractionDelta_),
@@ -160,6 +172,13 @@ void Foam::activeBaffleVelocityFvPatchVectorField::autoMap
     [
         cyclicPatchLabel_
     ].patchSlice(areas);
+    nbrCyclicSf_ = refCast<const cyclicFvPatch>
+    (
+        patch().boundaryMesh()
+        [
+            cyclicPatchLabel_
+        ]
+    ).neighbFvPatch().patch().patchSlice(areas);
 }
 
 void Foam::activeBaffleVelocityFvPatchVectorField::rmap
@@ -177,6 +196,13 @@ void Foam::activeBaffleVelocityFvPatchVectorField::rmap
     [
         cyclicPatchLabel_
     ].patchSlice(areas);
+    nbrCyclicSf_ = refCast<const cyclicFvPatch>
+    (
+        patch().boundaryMesh()
+        [
+            cyclicPatchLabel_
+        ]
+    ).neighbFvPatch().patch().patchSlice(areas);
 }
 
 
@@ -197,19 +223,24 @@ void Foam::activeBaffleVelocityFvPatchVectorField::updateCoeffs()
 
         const fvPatch& cyclicPatch = patch().boundaryMesh()[cyclicPatchLabel_];
         const labelList& cyclicFaceCells = cyclicPatch.patch().faceCells();
-        label nCyclicFaces = cyclicFaceCells.size();
-        label nCyclicFacesPerSide = nCyclicFaces/2;
+        const fvPatch& nbrPatch = refCast<const cyclicFvPatch>
+        (
+            cyclicPatch
+        ).neighbFvPatch();
+        const labelList& nbrFaceCells = nbrPatch.patch().faceCells();
 
         scalar forceDiff = 0;
 
-        for (label facei=0; facei<nCyclicFacesPerSide; facei++)
+        // Add this side
+        forAll(cyclicFaceCells, facei)
         {
             forceDiff += p[cyclicFaceCells[facei]]*mag(initCyclicSf_[facei]);
         }
 
-        for (label facei=nCyclicFacesPerSide; facei<nCyclicFaces; facei++)
+        // Remove other side
+        forAll(nbrFaceCells, facei)
         {
-            forceDiff -= p[cyclicFaceCells[facei]]*mag(initCyclicSf_[facei]);
+            forceDiff -= p[nbrFaceCells[facei]]*mag(nbrCyclicSf_[facei]);
         }
 
         openFraction_ =
@@ -239,10 +270,16 @@ void Foam::activeBaffleVelocityFvPatchVectorField::updateCoeffs()
         }
         const_cast<scalarField&>(patch().magSf()) = mag(patch().Sf());
 
+        // Update owner side of cyclic
         const_cast<vectorField&>(cyclicPatch.Sf()) =
             openFraction_*initCyclicSf_;
         const_cast<scalarField&>(cyclicPatch.magSf()) =
             mag(cyclicPatch.Sf());
+        // Update neighbour side of cyclic
+        const_cast<vectorField&>(nbrPatch.Sf()) =
+            openFraction_*nbrCyclicSf_;
+        const_cast<scalarField&>(nbrPatch.magSf()) =
+            mag(nbrPatch.Sf());
 
         curTimeIndex_ = this->db().time().timeIndex();
     }
diff --git a/src/finiteVolume/fields/fvPatchFields/derived/activeBaffleVelocity/activeBaffleVelocityFvPatchVectorField.H b/src/finiteVolume/fields/fvPatchFields/derived/activeBaffleVelocity/activeBaffleVelocityFvPatchVectorField.H
index c35cbc058e40b58c381be0f8ff9de77810f1f754..2bc39eedefbf8395f23989a6fbbf8d69c60e8fca 100644
--- a/src/finiteVolume/fields/fvPatchFields/derived/activeBaffleVelocity/activeBaffleVelocityFvPatchVectorField.H
+++ b/src/finiteVolume/fields/fvPatchFields/derived/activeBaffleVelocity/activeBaffleVelocityFvPatchVectorField.H
@@ -71,9 +71,12 @@ class activeBaffleVelocityFvPatchVectorField
         //- Initial wall patch areas
         vectorField initWallSf_;
 
-        //- Initial cyclic patch areas
+        //- Initial this-side cyclic patch areas
         vectorField initCyclicSf_;
 
+        //- Initial neighbour-side cyclic patch areas
+        vectorField nbrCyclicSf_;
+
         //- Current fraction of the active baffle which is open
         scalar openFraction_;
 
diff --git a/src/finiteVolume/fields/fvPatchFields/derived/fan/fanFvPatchField.C b/src/finiteVolume/fields/fvPatchFields/derived/fan/fanFvPatchField.C
index 19181e0f4ed9929c055dabf723124d3f53c71616..e5bfc0c7f5db0dc8d5055168812144fceb3ddc73 100644
--- a/src/finiteVolume/fields/fvPatchFields/derived/fan/fanFvPatchField.C
+++ b/src/finiteVolume/fields/fvPatchFields/derived/fan/fanFvPatchField.C
@@ -42,7 +42,7 @@ fanFvPatchField<Type>::fanFvPatchField
 :
     jumpCyclicFvPatchField<Type>(p, iF),
     f_(0),
-    jump_(this->size()/2, 0.0)
+    jump_(this->size(), 0.0)
 {}
 
 
@@ -71,12 +71,14 @@ fanFvPatchField<Type>::fanFvPatchField
 :
     jumpCyclicFvPatchField<Type>(p, iF),
     f_(),
-    jump_(this->size()/2, 0.0)
+    jump_(this->size(), 0.0)
 {
     {
         Istream& is = dict.lookup("f");
         is.format(IOstream::ASCII);
         is >> f_;
+
+        // Check that f_ table is same on both sides.?
     }
 
     if (dict.found("value"))
@@ -128,21 +130,7 @@ void fanFvPatchField<Type>::autoMap
 )
 {
     jumpCyclicFvPatchField<Type>::autoMap(m);
-
-    // Jump is half size. Expand to full size, map and truncate.
-    if (jump_.size() && jump_.size() == this->size()/2)
-    {
-        label oldSize = jump_.size();
-        jump_.setSize(this->size());
-
-        for (label i = oldSize; i < jump_.size(); i++)
-        {
-            jump_[i] = jump_[i-oldSize];
-        }
-
-        jump_.autoMap(m);
-        jump_.setSize(oldSize);
-    }
+    jump_.autoMap(m);
 }
 
 
@@ -155,24 +143,9 @@ void fanFvPatchField<Type>::rmap
 {
     jumpCyclicFvPatchField<Type>::rmap(ptf, addr);
 
-    // Jump is half size. Expand to full size, map and truncate.
-    if (jump_.size() && jump_.size() == this->size()/2)
-    {
-        label oldSize = jump_.size();
-        jump_.setSize(this->size());
-
-        for (label i = oldSize; i < jump_.size(); i++)
-        {
-            jump_[i] = jump_[i-oldSize];
-        }
-
-        const fanFvPatchField<Type>& tiptf =
-            refCast<const fanFvPatchField<Type> >(ptf);
-
-        jump_.rmap(tiptf.jump_, addr);
-
-        jump_.setSize(oldSize);
-    }
+    const fanFvPatchField<Type>& tiptf =
+        refCast<const fanFvPatchField<Type> >(ptf);
+    jump_.rmap(tiptf.jump_, addr);
 }
 
 
diff --git a/src/finiteVolume/fields/fvPatchFields/derived/fan/fanFvPatchField.H b/src/finiteVolume/fields/fvPatchFields/derived/fan/fanFvPatchField.H
index ed19c47d689e23f0f8c5523dbd4a17096e00ba2b..5fbd932690dec303f86674ae731e57f48aa89a28 100644
--- a/src/finiteVolume/fields/fvPatchFields/derived/fan/fanFvPatchField.H
+++ b/src/finiteVolume/fields/fvPatchFields/derived/fan/fanFvPatchField.H
@@ -131,7 +131,13 @@ public:
 
         // Access
 
-            //- Return the "jump" across the patch as a "half" field
+            //- Return the polynomial coefficients
+            const List<scalar>& f() const
+            {
+                return f_;
+            }
+
+            //- Return the "jump" across the patch.
             virtual tmp<Field<Type> > jump() const
             {
                 return jump_;
diff --git a/src/finiteVolume/fields/fvPatchFields/derived/fan/fanFvPatchFields.C b/src/finiteVolume/fields/fvPatchFields/derived/fan/fanFvPatchFields.C
index f7371a7360f58a3f6f887958bdd0de9df6b51c29..a27f526741bd7fe9004f74c909489a427ddfc99a 100644
--- a/src/finiteVolume/fields/fvPatchFields/derived/fan/fanFvPatchFields.C
+++ b/src/finiteVolume/fields/fvPatchFields/derived/fan/fanFvPatchFields.C
@@ -46,6 +46,7 @@ void Foam::fanFvPatchField<Foam::scalar>::updateCoeffs()
         return;
     }
 
+    // Constant
     jump_ = f_[0];
 
     if (f_.size() > 1)
@@ -56,21 +57,11 @@ void Foam::fanFvPatchField<Foam::scalar>::updateCoeffs()
         const fvsPatchField<scalar>& phip =
             patch().patchField<surfaceScalarField, scalar>(phi);
 
-        scalarField Un = max
-        (
-            scalarField::subField(phip, size()/2)
-           /scalarField::subField(patch().magSf(), size()/2),
-            scalar(0)
-        );
+        scalarField Un = max(phip/patch().magSf(), scalar(0));
 
         if (phi.dimensions() == dimDensity*dimVelocity*dimArea)
         {
-            Un /=
-                scalarField::subField
-                (
-                    patch().lookupPatchField<volScalarField, scalar>("rho"),
-                    size()/2
-                );
+            Un /= patch().lookupPatchField<volScalarField, scalar>("rho");
         }
 
         for (label i=1; i<f_.size(); i++)
diff --git a/src/finiteVolume/fields/fvsPatchFields/constraint/processorCyclic/processorCyclicFvsPatchField.C b/src/finiteVolume/fields/fvsPatchFields/constraint/processorCyclic/processorCyclicFvsPatchField.C
new file mode 100644
index 0000000000000000000000000000000000000000..918c7731196179a68e365b4869f07b8a14612d5b
--- /dev/null
+++ b/src/finiteVolume/fields/fvsPatchFields/constraint/processorCyclic/processorCyclicFvsPatchField.C
@@ -0,0 +1,157 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
+     \\/     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 2 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, write to the Free Software Foundation,
+    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+\*---------------------------------------------------------------------------*/
+
+#include "processorCyclicFvsPatchField.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
+
+template<class Type>
+processorCyclicFvsPatchField<Type>::processorCyclicFvsPatchField
+(
+    const fvPatch& p,
+    const DimensionedField<Type, surfaceMesh>& iF
+)
+:
+    coupledFvsPatchField<Type>(p, iF),
+    procPatch_(refCast<const processorCyclicFvPatch>(p))
+{}
+
+
+template<class Type>
+processorCyclicFvsPatchField<Type>::processorCyclicFvsPatchField
+(
+    const fvPatch& p,
+    const DimensionedField<Type, surfaceMesh>& iF,
+    const Field<Type>& f
+)
+:
+    coupledFvsPatchField<Type>(p, iF, f),
+    procPatch_(refCast<const processorCyclicFvPatch>(p))
+{}
+
+
+// Construct by mapping given processorCyclicFvsPatchField<Type>
+template<class Type>
+processorCyclicFvsPatchField<Type>::processorCyclicFvsPatchField
+(
+    const processorCyclicFvsPatchField<Type>& ptf,
+    const fvPatch& p,
+    const DimensionedField<Type, surfaceMesh>& iF,
+    const fvPatchFieldMapper& mapper
+)
+:
+    coupledFvsPatchField<Type>(ptf, p, iF, mapper),
+    procPatch_(refCast<const processorCyclicFvPatch>(p))
+{
+    if (!isType<processorCyclicFvPatch>(this->patch()))
+    {
+        FatalErrorIn
+        (
+            "processorCyclicFvsPatchField<Type>::processorCyclicFvsPatchField\n"
+            "(\n"
+            "    const processorCyclicFvsPatchField<Type>& ptf,\n"
+            "    const fvPatch& p,\n"
+            "    const DimensionedField<Type, surfaceMesh>& iF,\n"
+            "    const fvPatchFieldMapper& mapper\n"
+            ")\n"
+        )   << "Field type does not correspond to patch type for patch "
+            << this->patch().index() << "." << endl
+            << "Field type: " << typeName << endl
+            << "Patch type: " << this->patch().type()
+            << exit(FatalError);
+    }
+}
+
+
+template<class Type>
+processorCyclicFvsPatchField<Type>::processorCyclicFvsPatchField
+(
+    const fvPatch& p,
+    const DimensionedField<Type, surfaceMesh>& iF,
+    const dictionary& dict
+)
+:
+    coupledFvsPatchField<Type>(p, iF, dict),
+    procPatch_(refCast<const processorCyclicFvPatch>(p))
+{
+    if (!isType<processorCyclicFvPatch>(p))
+    {
+        FatalIOErrorIn
+        (
+            "processorCyclicFvsPatchField<Type>::processorCyclicFvsPatchField\n"
+            "(\n"
+            "    const fvPatch& p,\n"
+            "    const Field<Type>& field,\n"
+            "    const dictionary& dict\n"
+            ")\n",
+            dict
+        )   << "patch " << this->patch().index() << " not processor type. "
+            << "Patch type = " << p.type()
+            << exit(FatalIOError);
+    }
+}
+
+
+template<class Type>
+processorCyclicFvsPatchField<Type>::processorCyclicFvsPatchField
+(
+    const processorCyclicFvsPatchField<Type>& ptf
+)
+:
+    coupledFvsPatchField<Type>(ptf),
+    procPatch_(refCast<const processorCyclicFvPatch>(ptf.patch()))
+{}
+
+
+template<class Type>
+processorCyclicFvsPatchField<Type>::processorCyclicFvsPatchField
+(
+    const processorCyclicFvsPatchField<Type>& ptf,
+    const DimensionedField<Type, surfaceMesh>& iF
+)
+:
+    coupledFvsPatchField<Type>(ptf, iF),
+    procPatch_(refCast<const processorCyclicFvPatch>(ptf.patch()))
+{}
+
+
+// * * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * //
+
+template<class Type>
+processorCyclicFvsPatchField<Type>::~processorCyclicFvsPatchField()
+{}
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// ************************************************************************* //
diff --git a/src/finiteVolume/fields/fvsPatchFields/constraint/processorCyclic/processorCyclicFvsPatchField.H b/src/finiteVolume/fields/fvsPatchFields/constraint/processorCyclic/processorCyclicFvsPatchField.H
new file mode 100644
index 0000000000000000000000000000000000000000..b418bd7aa9e4129c22d7bd9b7c8fcead7d7b6f43
--- /dev/null
+++ b/src/finiteVolume/fields/fvsPatchFields/constraint/processorCyclic/processorCyclicFvsPatchField.H
@@ -0,0 +1,173 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
+     \\/     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 2 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, write to the Free Software Foundation,
+    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+Class
+    Foam::processorCyclicFvsPatchField
+
+Description
+    Foam::processorCyclicFvsPatchField
+
+SourceFiles
+    processorCyclicFvsPatchField.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef processorCyclicFvsPatchField_H
+#define processorCyclicFvsPatchField_H
+
+#include "coupledFvsPatchField.H"
+#include "processorCyclicFvPatch.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+                      Class processorCyclicFvsPatch Declaration
+\*---------------------------------------------------------------------------*/
+
+template<class Type>
+class processorCyclicFvsPatchField
+:
+    public coupledFvsPatchField<Type>
+{
+    // Private data
+
+        //- Local reference cast into the processor patch
+        const processorCyclicFvPatch& procPatch_;
+
+
+public:
+
+    //- Runtime type information
+    TypeName(processorCyclicFvPatch::typeName_());
+
+
+    // Constructors
+
+        //- Construct from patch and internal field
+        processorCyclicFvsPatchField
+        (
+            const fvPatch&,
+            const DimensionedField<Type, surfaceMesh>&
+        );
+
+        //- Construct from patch and internal field and patch field
+        processorCyclicFvsPatchField
+        (
+            const fvPatch&,
+            const DimensionedField<Type, surfaceMesh>&,
+            const Field<Type>&
+        );
+
+        //- Construct from patch, internal field and dictionary
+        processorCyclicFvsPatchField
+        (
+            const fvPatch&,
+            const DimensionedField<Type, surfaceMesh>&,
+            const dictionary&
+        );
+
+        //- Construct by mapping given processorCyclicFvsPatchField onto a
+        //  new patch
+        processorCyclicFvsPatchField
+        (
+            const processorCyclicFvsPatchField<Type>&,
+            const fvPatch&,
+            const DimensionedField<Type, surfaceMesh>&,
+            const fvPatchFieldMapper&
+        );
+
+        //- Construct as copy
+        processorCyclicFvsPatchField(const processorCyclicFvsPatchField<Type>&);
+
+        //- Construct and return a clone
+        virtual tmp<fvsPatchField<Type> > clone() const
+        {
+            return tmp<fvsPatchField<Type> >
+            (
+                new processorCyclicFvsPatchField<Type>(*this)
+            );
+        }
+
+        //- Construct as copy setting internal field reference
+        processorCyclicFvsPatchField
+        (
+            const processorCyclicFvsPatchField<Type>&,
+            const DimensionedField<Type, surfaceMesh>&
+        );
+
+        //- Construct and return a clone setting internal field reference
+        virtual tmp<fvsPatchField<Type> > clone
+        (
+            const DimensionedField<Type, surfaceMesh>& iF
+        ) const
+        {
+            return tmp<fvsPatchField<Type> >
+            (
+                new processorCyclicFvsPatchField<Type>(*this, iF)
+            );
+        }
+
+
+    // Destructor
+
+        ~processorCyclicFvsPatchField();
+
+
+    // Member functions
+
+        // Access
+
+            //- Return true if running parallel
+            virtual bool coupled() const
+            {
+                if (Pstream::parRun())
+                {
+                    return true;
+                }
+                else
+                {
+                    return false;
+                }
+            }
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#ifdef NoRepository
+#   include "processorCyclicFvsPatchField.C"
+#endif
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/finiteVolume/fields/fvsPatchFields/constraint/processorCyclic/processorCyclicFvsPatchFields.C b/src/finiteVolume/fields/fvsPatchFields/constraint/processorCyclic/processorCyclicFvsPatchFields.C
new file mode 100644
index 0000000000000000000000000000000000000000..9ac8157e92c317a52f9ce7cf5ce245e031221c0c
--- /dev/null
+++ b/src/finiteVolume/fields/fvsPatchFields/constraint/processorCyclic/processorCyclicFvsPatchFields.C
@@ -0,0 +1,44 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
+     \\/     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 2 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, write to the Free Software Foundation,
+    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+\*---------------------------------------------------------------------------*/
+
+#include "processorCyclicFvsPatchFields.H"
+#include "fvsPatchFields.H"
+#include "addToRunTimeSelectionTable.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+makeFvsPatchFields(processorCyclic);
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// ************************************************************************* //
diff --git a/src/finiteVolume/fields/fvsPatchFields/constraint/processorCyclic/processorCyclicFvsPatchFields.H b/src/finiteVolume/fields/fvsPatchFields/constraint/processorCyclic/processorCyclicFvsPatchFields.H
new file mode 100644
index 0000000000000000000000000000000000000000..5e4684c48080c4fd378848b182e08e91f89cef71
--- /dev/null
+++ b/src/finiteVolume/fields/fvsPatchFields/constraint/processorCyclic/processorCyclicFvsPatchFields.H
@@ -0,0 +1,50 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
+     \\/     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 2 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, write to the Free Software Foundation,
+    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef processorCyclicFvsPatchFields_H
+#define processorCyclicFvsPatchFields_H
+
+#include "processorCyclicFvsPatchField.H"
+#include "fieldTypes.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+makeFvsPatchTypeFieldTypedefs(processorCyclic)
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/finiteVolume/fields/fvsPatchFields/constraint/processorCyclic/processorCyclicFvsPatchFieldsFwd.H b/src/finiteVolume/fields/fvsPatchFields/constraint/processorCyclic/processorCyclicFvsPatchFieldsFwd.H
new file mode 100644
index 0000000000000000000000000000000000000000..ad19f47e4e56ed30f8fb28627520cbda5620c569
--- /dev/null
+++ b/src/finiteVolume/fields/fvsPatchFields/constraint/processorCyclic/processorCyclicFvsPatchFieldsFwd.H
@@ -0,0 +1,51 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
+     \\/     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 2 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, write to the Free Software Foundation,
+    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef processorCyclicFvsPatchFieldsFwd_H
+#define processorCyclicFvsPatchFieldsFwd_H
+
+#include "fieldTypes.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+template<class Type> class processorCyclicFvsPatchField;
+
+makeFvsPatchTypeFieldTypedefs(processor)
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/finiteVolume/fvMatrices/solvers/MULES/MULESTemplates.C b/src/finiteVolume/fvMatrices/solvers/MULES/MULESTemplates.C
index 2fe12f0317b013b5daa1d850119614ffb9778354..d99aa43eb1f14c0ed1b8e3dad53f8b3e30c752d3 100644
--- a/src/finiteVolume/fvMatrices/solvers/MULES/MULESTemplates.C
+++ b/src/finiteVolume/fvMatrices/solvers/MULES/MULESTemplates.C
@@ -590,7 +590,7 @@ void Foam::MULES::limiter
             }
         }
 
-        syncTools::syncFaceList(mesh, allLambda, minEqOp<scalar>(), false);
+        syncTools::syncFaceList(mesh, allLambda, minEqOp<scalar>());
     }
 }
 
diff --git a/src/finiteVolume/fvMesh/extendedStencil/cellToCell/fullStencils/CECCellToCellStencil.C b/src/finiteVolume/fvMesh/extendedStencil/cellToCell/fullStencils/CECCellToCellStencil.C
index aed12722c9df675808d81a141776df43854fb890..eb0f4303e175c79c55b92bf795680c1c4ca653ab 100644
--- a/src/finiteVolume/fvMesh/extendedStencil/cellToCell/fullStencils/CECCellToCellStencil.C
+++ b/src/finiteVolume/fvMesh/extendedStencil/cellToCell/fullStencils/CECCellToCellStencil.C
@@ -25,6 +25,7 @@ License
 
 #include "CECCellToCellStencil.H"
 #include "syncTools.H"
+#include "dummyTransform.H"
 
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
@@ -56,13 +57,7 @@ void Foam::CECCellToCellStencil::calcEdgeBoundaryData
         );
     }
 
-    syncTools::syncEdgeMap
-    (
-        mesh(),
-        neiGlobal,
-        unionEqOp(),
-        false           // apply separation
-    );
+    syncTools::syncEdgeMap(mesh(), neiGlobal, unionEqOp(), dummyTransform());
 }
 
 
diff --git a/src/finiteVolume/fvMesh/extendedStencil/cellToCell/fullStencils/CFCCellToCellStencil.C b/src/finiteVolume/fvMesh/extendedStencil/cellToCell/fullStencils/CFCCellToCellStencil.C
index b121eb29c1c5914364eacb851ac1ced008f9ae1f..c5d0eaec92cce92b304112c603cde071dde898da 100644
--- a/src/finiteVolume/fvMesh/extendedStencil/cellToCell/fullStencils/CFCCellToCellStencil.C
+++ b/src/finiteVolume/fvMesh/extendedStencil/cellToCell/fullStencils/CFCCellToCellStencil.C
@@ -78,7 +78,7 @@ void Foam::CFCCellToCellStencil::calcFaceBoundaryData
             }
         }
     }
-    syncTools::swapBoundaryFaceList(mesh(), neiGlobal, false);
+    syncTools::swapBoundaryFaceList(mesh(), neiGlobal);
 }
 
 
diff --git a/src/finiteVolume/fvMesh/extendedStencil/cellToCell/fullStencils/CPCCellToCellStencil.C b/src/finiteVolume/fvMesh/extendedStencil/cellToCell/fullStencils/CPCCellToCellStencil.C
index bae45472a9d4df140049a6e37e5973cbb0998306..a4f757505402ff4a04be40cf40561d7bc0210f90 100644
--- a/src/finiteVolume/fvMesh/extendedStencil/cellToCell/fullStencils/CPCCellToCellStencil.C
+++ b/src/finiteVolume/fvMesh/extendedStencil/cellToCell/fullStencils/CPCCellToCellStencil.C
@@ -25,6 +25,7 @@ License
 
 #include "CPCCellToCellStencil.H"
 #include "syncTools.H"
+#include "dummyTransform.H"
 
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
@@ -61,7 +62,7 @@ void Foam::CPCCellToCellStencil::calcPointBoundaryData
         mesh(),
         neiGlobal,
         unionEqOp(),
-        false           // apply separation
+        Foam::dummyTransform()      // dummy transformation
     );
 }
 
diff --git a/src/finiteVolume/fvMesh/extendedStencil/cellToFace/extendedUpwindCellToFaceStencil.C b/src/finiteVolume/fvMesh/extendedStencil/cellToFace/extendedUpwindCellToFaceStencil.C
index a2259bfc723c16f1c679c731fa425f2bc31f614c..82e91bcd4e64c52af211e09fa6d958a3f224e174 100644
--- a/src/finiteVolume/fvMesh/extendedStencil/cellToFace/extendedUpwindCellToFaceStencil.C
+++ b/src/finiteVolume/fvMesh/extendedStencil/cellToFace/extendedUpwindCellToFaceStencil.C
@@ -27,6 +27,7 @@ License
 #include "cellToFaceStencil.H"
 #include "syncTools.H"
 #include "SortableList.H"
+#include "dummyTransform.H"
 
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
@@ -315,7 +316,15 @@ void Foam::extendedUpwindCellToFaceStencil::transportStencils
     {
         neiBndStencil[faceI-mesh_.nInternalFaces()] = ownStencil[faceI];
     }
-    syncTools::swapBoundaryFaceList(mesh_, neiBndStencil, false);
+    //syncTools::swapBoundaryFaceList(mesh_, neiBndStencil);
+    syncTools::syncBoundaryFaceList
+    (
+        mesh_,
+        neiBndStencil,
+        eqOp<labelList>(),
+        dummyTransform()
+    );
+
 
 
     // Do the neighbour side
diff --git a/src/finiteVolume/fvMesh/extendedStencil/cellToFace/fullStencils/FECCellToFaceStencil.C b/src/finiteVolume/fvMesh/extendedStencil/cellToFace/fullStencils/FECCellToFaceStencil.C
index 048ef4391b077a1d4e7e0f1e24561b4852acf788..52a7ad6a57cef3d733abc295fcfb44b6377debcf 100644
--- a/src/finiteVolume/fvMesh/extendedStencil/cellToFace/fullStencils/FECCellToFaceStencil.C
+++ b/src/finiteVolume/fvMesh/extendedStencil/cellToFace/fullStencils/FECCellToFaceStencil.C
@@ -26,9 +26,7 @@ License
 #include "FECCellToFaceStencil.H"
 #include "syncTools.H"
 #include "emptyPolyPatch.H"
-//#include "meshTools.H"
-//#include "OFstream.H"
-//#include "Time.H"
+#include "dummyTransform.H"
 
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
@@ -60,13 +58,7 @@ void Foam::FECCellToFaceStencil::calcEdgeBoundaryData
         );
     }
 
-    syncTools::syncEdgeMap
-    (
-        mesh(),
-        neiGlobal,
-        unionEqOp(),
-        false           // apply separation
-    );
+    syncTools::syncEdgeMap(mesh(), neiGlobal, unionEqOp(), dummyTransform());
 }
 
 
@@ -104,7 +96,7 @@ void Foam::FECCellToFaceStencil::calcFaceStencil
             }
         }
     }
-    syncTools::swapBoundaryFaceList(mesh(), neiGlobalCell, false);
+    syncTools::swapBoundaryFaceList(mesh(), neiGlobalCell);
 
 
 
diff --git a/src/finiteVolume/fvMesh/extendedStencil/cellToFace/fullStencils/cellToFaceStencil.C b/src/finiteVolume/fvMesh/extendedStencil/cellToFace/fullStencils/cellToFaceStencil.C
index d2289a721fc38f2be98201b25b9fed6436154fd8..e6d68f87dc9ce8578a86362d3ecd09e5426337ff 100644
--- a/src/finiteVolume/fvMesh/extendedStencil/cellToFace/fullStencils/cellToFaceStencil.C
+++ b/src/finiteVolume/fvMesh/extendedStencil/cellToFace/fullStencils/cellToFaceStencil.C
@@ -24,9 +24,10 @@ License
 \*---------------------------------------------------------------------------*/
 
 #include "cellToFaceStencil.H"
-#include "syncTools.H"
 #include "SortableList.H"
 #include "emptyPolyPatch.H"
+#include "syncTools.H"
+#include "dummyTransform.H"
 
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
@@ -370,7 +371,14 @@ void Foam::cellToFaceStencil::calcFaceStencil
             }
         }
     }
-    syncTools::swapBoundaryFaceList(mesh_, neiGlobalCellCells, false);
+    //syncTools::swapBoundaryFaceList(mesh_, neiGlobalCellCells);
+    syncTools::syncBoundaryFaceList
+    (
+        mesh_,
+        neiGlobalCellCells,
+        eqOp<labelList>(),
+        dummyTransform()
+    );
 
 
 
diff --git a/src/finiteVolume/fvMesh/extendedStencil/faceToCell/fullStencils/CFCFaceToCellStencil.C b/src/finiteVolume/fvMesh/extendedStencil/faceToCell/fullStencils/CFCFaceToCellStencil.C
index 91d4f9ed5d05de7766502b3857cb06928a6490e8..12a46a28e797241fa3dbafaa5108cd46c6bbb76b 100644
--- a/src/finiteVolume/fvMesh/extendedStencil/faceToCell/fullStencils/CFCFaceToCellStencil.C
+++ b/src/finiteVolume/fvMesh/extendedStencil/faceToCell/fullStencils/CFCFaceToCellStencil.C
@@ -26,6 +26,7 @@ License
 #include "CFCFaceToCellStencil.H"
 #include "syncTools.H"
 #include "emptyPolyPatch.H"
+#include "dummyTransform.H"
 
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
@@ -80,7 +81,14 @@ void Foam::CFCFaceToCellStencil::calcFaceBoundaryData
             // Do nothing since face itself already in stencil
         }
     }
-    syncTools::swapBoundaryFaceList(mesh(), neiGlobal, false);
+    //syncTools::swapBoundaryFaceList(mesh(), neiGlobal);
+    syncTools::syncBoundaryFaceList
+    (
+        mesh(),
+        neiGlobal,
+        eqOp<labelList>(),
+        dummyTransform()
+    );
 }
 
 
diff --git a/src/finiteVolume/fvMesh/fvMeshSubset/fvMeshSubset.C b/src/finiteVolume/fvMesh/fvMeshSubset/fvMeshSubset.C
index 8cd71ce2c206076865c1095c94a7924f0971929a..f6266998a3ef5cfd915ea8aff26641c02175e0cd 100644
--- a/src/finiteVolume/fvMesh/fvMeshSubset/fvMeshSubset.C
+++ b/src/finiteVolume/fvMesh/fvMeshSubset/fvMeshSubset.C
@@ -102,6 +102,8 @@ void Foam::fvMeshSubset::doCoupledPatches
 
     if (syncPar && Pstream::parRun())
     {
+        PstreamBuffers pBufs(Pstream::nonBlocking);
+
         // Send face usage across processor patches
         forAll(oldPatches, oldPatchI)
         {
@@ -112,17 +114,14 @@ void Foam::fvMeshSubset::doCoupledPatches
                 const processorPolyPatch& procPatch =
                     refCast<const processorPolyPatch>(pp);
 
-                OPstream toNeighbour
-                (
-                    Pstream::blocking,
-                    procPatch.neighbProcNo()
-                );
+                UOPstream toNeighbour(procPatch.neighbProcNo(), pBufs);
 
                 toNeighbour
                     << SubList<label>(nCellsUsingFace, pp.size(), pp.start());
             }
         }
 
+        pBufs.finishedSends();
 
         // Receive face usage count and check for faces that become uncoupled.
         forAll(oldPatches, oldPatchI)
@@ -134,11 +133,7 @@ void Foam::fvMeshSubset::doCoupledPatches
                 const processorPolyPatch& procPatch =
                     refCast<const processorPolyPatch>(pp);
 
-                IPstream fromNeighbour
-                (
-                    Pstream::blocking,
-                    procPatch.neighbProcNo()
-                );
+                UIPstream fromNeighbour(procPatch.neighbProcNo(), pBufs);
 
                 labelList nbrCellsUsingFace(fromNeighbour);
 
diff --git a/src/finiteVolume/fvMesh/fvPatches/basic/coupled/coupledFvPatch.H b/src/finiteVolume/fvMesh/fvPatches/basic/coupled/coupledFvPatch.H
index 013c3aa2ac576ae0a60a62c41936f3f811c9c80a..899bebc9ac03e670671fd36feb8b9a5e4356e6f5 100644
--- a/src/finiteVolume/fvMesh/fvPatches/basic/coupled/coupledFvPatch.H
+++ b/src/finiteVolume/fvMesh/fvPatches/basic/coupled/coupledFvPatch.H
@@ -103,23 +103,14 @@ public:
                 return coupledPolyPatch_.coupled();
             }
 
-            //- Return face transformation tensor
-            const tensorField& forwardT() const
-            {
-                return coupledPolyPatch_.forwardT();
-            }
+            //- Are the cyclic planes parallel.
+            virtual bool parallel() const = 0;
 
-            //- Return neighbour-cell transformation tensor
-            const tensorField& reverseT() const
-            {
-                return coupledPolyPatch_.reverseT();
-            }
+            //- Return face transformation tensor.
+            virtual const tensorField& forwardT() const = 0;
 
-            //- Are the cyclic planes parallel
-            bool parallel() const
-            {
-                return coupledPolyPatch_.parallel();
-            }
+            //- Return neighbour-cell transformation tensor.
+            virtual const tensorField& reverseT() const = 0;
 
             //- Return faceCell addressing
             virtual const unallocLabelList& faceCells() const
@@ -140,21 +131,6 @@ public:
                 const unallocLabelList& internalData
             ) const = 0;
 
-            //- Initialise interface data transfer
-            virtual void initTransfer
-            (
-                const Pstream::commsTypes commsType,
-                const unallocLabelList& interfaceData
-            ) const
-            {}
-
-            //- Transfer and return neighbour field
-            virtual tmp<labelField> transfer
-            (
-                const Pstream::commsTypes commsType,
-                const unallocLabelList& interfaceData
-            ) const = 0;
-
             //- Initialise neighbour field transfer
             virtual void initInternalFieldTransfer
             (
diff --git a/src/finiteVolume/fvMesh/fvPatches/constraint/cyclic/cyclicFvPatch.C b/src/finiteVolume/fvMesh/fvPatches/constraint/cyclic/cyclicFvPatch.C
index 19ff7e6e6c6cebc1edb964f30b3109b5da51a364..e6fe565f5c117592483cb5cfcb910f57ac46757b 100644
--- a/src/finiteVolume/fvMesh/fvPatches/constraint/cyclic/cyclicFvPatch.C
+++ b/src/finiteVolume/fvMesh/fvPatches/constraint/cyclic/cyclicFvPatch.C
@@ -26,6 +26,7 @@ License
 #include "cyclicFvPatch.H"
 #include "addToRunTimeSelectionTable.H"
 #include "fvMesh.H"
+#include "transform.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -43,30 +44,31 @@ addToRunTimeSelectionTable(fvPatch, cyclicFvPatch, polyPatch);
 // Make patch weighting factors
 void cyclicFvPatch::makeWeights(scalarField& w) const
 {
+    const cyclicFvPatch& nbrPatch = neighbFvPatch();
+
     const scalarField& magFa = magSf();
+    const scalarField& nbrMagFa = nbrPatch.magSf();
 
     scalarField deltas = nf() & fvPatch::delta();
-    label sizeby2 = deltas.size()/2;
+    scalarField nbrDeltas = nbrPatch.nf() & nbrPatch.fvPatch::delta();
 
-    for (label facei = 0; facei < sizeby2; facei++)
+    forAll(magFa, facei)
     {
-        scalar avFa = (magFa[facei] + magFa[facei + sizeby2])/2.0;
+        scalar avFa = (magFa[facei] + nbrMagFa[facei])/2.0;
 
-        if (mag(magFa[facei] - magFa[facei + sizeby2])/avFa > 1e-4)
+        if (mag(magFa[facei] - nbrMagFa[facei])/avFa > 1e-4)
         {
             FatalErrorIn("cyclicFvPatch::makeWeights(scalarField& w) const")
-                << "face " << facei << " and " << facei + sizeby2
-                <<  " areas do not match by "
-                << 100*mag(magFa[facei] - magFa[facei + sizeby2])/avFa
+                << "face " << facei << " areas do not match by "
+                << 100*mag(magFa[facei] - nbrMagFa[facei])/avFa
                 << "% -- possible face ordering problem"
                 << abort(FatalError);
         }
 
         scalar di = deltas[facei];
-        scalar dni = deltas[facei + sizeby2];
+        scalar dni = nbrDeltas[facei];
 
         w[facei] = dni/(di + dni);
-        w[facei + sizeby2] = 1 - w[facei];
     }
 }
 
@@ -74,16 +76,18 @@ void cyclicFvPatch::makeWeights(scalarField& w) const
 // Make patch face - neighbour cell distances
 void cyclicFvPatch::makeDeltaCoeffs(scalarField& dc) const
 {
+    //const cyclicPolyPatch& nbrPatch = cyclicPolyPatch_.neighbPatch();
+    const cyclicFvPatch& nbrPatch = neighbFvPatch();
+
     scalarField deltas = nf() & fvPatch::delta();
-    label sizeby2 = deltas.size()/2;
+    scalarField nbrDeltas = nbrPatch.nf() & nbrPatch.fvPatch::delta();
 
-    for (label facei = 0; facei < sizeby2; facei++)
+    forAll(deltas, facei)
     {
         scalar di = deltas[facei];
-        scalar dni = deltas[facei + sizeby2];
+        scalar dni = nbrDeltas[facei];
 
         dc[facei] = 1.0/(di + dni);
-        dc[facei + sizeby2] = dc[facei];
     }
 }
 
@@ -92,7 +96,7 @@ void cyclicFvPatch::makeDeltaCoeffs(scalarField& dc) const
 tmp<vectorField> cyclicFvPatch::delta() const
 {
     vectorField patchD = fvPatch::delta();
-    label sizeby2 = patchD.size()/2;
+    vectorField nbrPatchD = neighbFvPatch().fvPatch::delta();
 
     tmp<vectorField> tpdv(new vectorField(patchD.size()));
     vectorField& pdv = tpdv();
@@ -100,24 +104,22 @@ tmp<vectorField> cyclicFvPatch::delta() const
     // To the transformation if necessary
     if (parallel())
     {
-        for (label facei = 0; facei < sizeby2; facei++)
+        forAll(patchD, facei)
         {
             vector ddi = patchD[facei];
-            vector dni = patchD[facei + sizeby2];
+            vector dni = nbrPatchD[facei];
 
             pdv[facei] = ddi - dni;
-            pdv[facei + sizeby2] = -pdv[facei];
         }
     }
     else
     {
-        for (label facei = 0; facei < sizeby2; facei++)
+        forAll(patchD, facei)
         {
             vector ddi = patchD[facei];
-            vector dni = patchD[facei + sizeby2];
+            vector dni = nbrPatchD[facei];
 
             pdv[facei] = ddi - transform(forwardT()[0], dni);
-            pdv[facei + sizeby2] = -transform(reverseT()[0], pdv[facei]);
         }
     }
 
@@ -134,47 +136,13 @@ tmp<labelField> cyclicFvPatch::interfaceInternalField
 }
 
 
-tmp<labelField> cyclicFvPatch::transfer
-(
-    const Pstream::commsTypes,
-    const unallocLabelList& interfaceData
-) const
-{
-    tmp<labelField> tpnf(new labelField(this->size()));
-    labelField& pnf = tpnf();
-
-    label sizeby2 = this->size()/2;
-
-    for (label facei=0; facei<sizeby2; facei++)
-    {
-        pnf[facei] = interfaceData[facei + sizeby2];
-        pnf[facei + sizeby2] = interfaceData[facei];
-    }
-
-    return tpnf;
-}
-
-
 tmp<labelField> cyclicFvPatch::internalFieldTransfer
 (
     const Pstream::commsTypes commsType,
     const unallocLabelList& iF
 ) const
 {
-    const unallocLabelList& faceCells = this->patch().faceCells();
-
-    tmp<labelField> tpnf(new labelField(this->size()));
-    labelField& pnf = tpnf();
-
-    label sizeby2 = this->size()/2;
-
-    for (label facei=0; facei<sizeby2; facei++)
-    {
-        pnf[facei] = iF[faceCells[facei + sizeby2]];
-        pnf[facei + sizeby2] = iF[faceCells[facei]];
-    }
-
-    return tpnf;
+    return neighbFvPatch().patchInternalField(iF);
 }
 
 
diff --git a/src/finiteVolume/fvMesh/fvPatches/constraint/cyclic/cyclicFvPatch.H b/src/finiteVolume/fvMesh/fvPatches/constraint/cyclic/cyclicFvPatch.H
index 66a01caad8b6157d2b4cb0759593b7fbf945a8a0..ca2654c30ff5d0fd042daae7579488035e6d8ce6 100644
--- a/src/finiteVolume/fvMesh/fvPatches/constraint/cyclic/cyclicFvPatch.H
+++ b/src/finiteVolume/fvMesh/fvPatches/constraint/cyclic/cyclicFvPatch.H
@@ -38,6 +38,7 @@ SourceFiles
 #include "coupledFvPatch.H"
 #include "cyclicLduInterface.H"
 #include "cyclicPolyPatch.H"
+#include "fvBoundaryMesh.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -89,21 +90,61 @@ public:
 
         // Access
 
+            //- Return local reference cast into the cyclic patch
+            const cyclicPolyPatch& cyclicPatch() const
+            {
+                return cyclicPolyPatch_;
+            }
+
+            //- Return neighbour
+            virtual label neighbPatchID() const
+            {
+                return cyclicPolyPatch_.neighbPatchID();
+            }
+
+            virtual bool owner() const
+            {
+                return cyclicPolyPatch_.owner();
+            }
+
+            //- Return processor number
+            virtual const cyclicLduInterface& neighbPatch() const
+            {
+                return refCast<const cyclicFvPatch>
+                (
+                    this->boundaryMesh()[cyclicPolyPatch_.neighbPatchID()]
+                );
+            }
+
+            //- Are the cyclic planes parallel
+            virtual bool parallel() const
+            {
+                return cyclicPolyPatch_.parallel();
+            }
+
             //- Return face transformation tensor
-            const tensorField& forwardT() const
+            virtual const tensorField& forwardT() const
             {
-                return coupledFvPatch::forwardT();
+                return cyclicPolyPatch_.forwardT();
             }
 
             //- Return neighbour-cell transformation tensor
-            const tensorField& reverseT() const
+            virtual const tensorField& reverseT() const
             {
-                return coupledFvPatch::reverseT();
+                return cyclicPolyPatch_.reverseT();
+            }
+
+            const cyclicFvPatch& neighbFvPatch() const
+            {
+                return refCast<const cyclicFvPatch>
+                (
+                    this->boundaryMesh()[cyclicPolyPatch_.neighbPatchID()]
+                );
             }
 
 
             //- Return delta (P to N) vectors across coupled patch
-            tmp<vectorField> delta() const;
+            virtual tmp<vectorField> delta() const;
 
 
         // Interface transfer functions
@@ -115,13 +156,6 @@ public:
                 const unallocLabelList& internalData
             ) const;
 
-            //- Transfer and return neighbour field
-            virtual tmp<labelField> transfer
-            (
-                const Pstream::commsTypes commsType,
-                const unallocLabelList& interfaceData
-            ) const;
-
             //- Return neighbour field
             virtual tmp<labelField> internalFieldTransfer
             (
diff --git a/src/finiteVolume/fvMesh/fvPatches/constraint/processor/processorFvPatch.C b/src/finiteVolume/fvMesh/fvPatches/constraint/processor/processorFvPatch.C
index 4c7c55bc8205d014443aede655986b9caa7eecf9..18c5827eec4847e77fd95962f3770720891462e0 100644
--- a/src/finiteVolume/fvMesh/fvPatches/constraint/processor/processorFvPatch.C
+++ b/src/finiteVolume/fvMesh/fvPatches/constraint/processor/processorFvPatch.C
@@ -122,26 +122,6 @@ tmp<labelField> processorFvPatch::interfaceInternalField
 }
 
 
-void processorFvPatch::initTransfer
-(
-    const Pstream::commsTypes commsType,
-    const unallocLabelList& interfaceData
-) const
-{
-    send(commsType, interfaceData);
-}
-
-
-tmp<labelField> processorFvPatch::transfer
-(
-    const Pstream::commsTypes commsType,
-    const unallocLabelList&
-) const
-{
-    return receive<label>(commsType, this->size());
-}
-
-
 void processorFvPatch::initInternalFieldTransfer
 (
     const Pstream::commsTypes commsType,
diff --git a/src/finiteVolume/fvMesh/fvPatches/constraint/processor/processorFvPatch.H b/src/finiteVolume/fvMesh/fvPatches/constraint/processor/processorFvPatch.H
index 300f2434313171d75470aceaacb2fd9fee4b9b17..68bff0e7e1e94b5e94700b7259d2dcb7250331ed 100644
--- a/src/finiteVolume/fvMesh/fvPatches/constraint/processor/processorFvPatch.H
+++ b/src/finiteVolume/fvMesh/fvPatches/constraint/processor/processorFvPatch.H
@@ -99,6 +99,12 @@ public:
             return procPolyPatch_.neighbProcNo();
         }
 
+        //- Return message tag used for sending
+        virtual int tag() const
+        {
+            return UPstream::msgType();
+        }
+
         //- Return true if running parallel
         virtual bool coupled() const
         {
@@ -112,14 +118,31 @@ public:
             }
         }
 
+        const processorPolyPatch& procPolyPatch() const
+        {
+            return procPolyPatch_;
+        }
+
+        //- Are the cyclic planes parallel
+        virtual bool parallel() const
+        {
+            return procPolyPatch_.parallel();
+        }
+
         //- Return face transformation tensor
         virtual const tensorField& forwardT() const
         {
             return procPolyPatch_.forwardT();
         }
 
+        //- Return neighbour-cell transformation tensor.
+        virtual const tensorField& reverseT() const
+        {
+            return procPolyPatch_.reverseT();
+        }
+
         //- Return delta (P to N) vectors across coupled patch
-        tmp<vectorField> delta() const;
+        virtual tmp<vectorField> delta() const;
 
 
         // Interface transfer functions
@@ -131,20 +154,6 @@ public:
                 const unallocLabelList& internalData
             ) const;
 
-            //- Initialise interface data transfer
-            virtual void initTransfer
-            (
-                const Pstream::commsTypes commsType,
-                const unallocLabelList& interfaceData
-            ) const;
-
-            //- Transfer and return neighbour field
-            virtual tmp<labelField> transfer
-            (
-                const Pstream::commsTypes commsType,
-                const unallocLabelList& interfaceData
-            ) const;
-
             //- Initialise neighbour field transfer
             virtual void initInternalFieldTransfer
             (
diff --git a/src/finiteVolume/fvMesh/fvPatches/constraint/processorCyclic/processorCyclicFvPatch.C b/src/finiteVolume/fvMesh/fvPatches/constraint/processorCyclic/processorCyclicFvPatch.C
new file mode 100644
index 0000000000000000000000000000000000000000..e972bcf0b678a95b472d731d7aeffa7e53fafb88
--- /dev/null
+++ b/src/finiteVolume/fvMesh/fvPatches/constraint/processorCyclic/processorCyclicFvPatch.C
@@ -0,0 +1,46 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
+     \\/     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 2 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, write to the Free Software Foundation,
+    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+\*---------------------------------------------------------------------------*/
+
+#include "processorCyclicFvPatch.H"
+#include "addToRunTimeSelectionTable.H"
+#include "transformField.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+defineTypeNameAndDebug(processorCyclicFvPatch, 0);
+addToRunTimeSelectionTable(fvPatch, processorCyclicFvPatch, polyPatch);
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// ************************************************************************* //
diff --git a/src/finiteVolume/fvMesh/fvPatches/constraint/processorCyclic/processorCyclicFvPatch.H b/src/finiteVolume/fvMesh/fvPatches/constraint/processorCyclic/processorCyclicFvPatch.H
new file mode 100644
index 0000000000000000000000000000000000000000..1ff63acc10df69fb199ee26d7f8da7f427c1044a
--- /dev/null
+++ b/src/finiteVolume/fvMesh/fvPatches/constraint/processorCyclic/processorCyclicFvPatch.H
@@ -0,0 +1,117 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
+     \\/     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 2 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, write to the Free Software Foundation,
+    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+Class
+    Foam::processorCyclicFvPatch
+
+Description
+    Processor patch.
+
+SourceFiles
+    processorCyclicFvPatch.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef processorCyclicFvPatch_H
+#define processorCyclicFvPatch_H
+
+#include "processorCyclicPolyPatch.H"
+#include "processorFvPatch.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+                           Class processorCyclicFvPatch Declaration
+\*---------------------------------------------------------------------------*/
+
+class processorCyclicFvPatch
+:
+    public processorFvPatch
+{
+    // Private Data
+
+        const processorCyclicPolyPatch& procPolyPatch_;
+
+public:
+
+    //- Runtime type information
+    TypeName(processorCyclicPolyPatch::typeName_());
+
+
+    // Constructors
+
+        //- Construct from components
+        processorCyclicFvPatch(const polyPatch& patch, const fvBoundaryMesh& bm)
+        :
+            processorFvPatch(patch, bm),
+            procPolyPatch_(refCast<const processorCyclicPolyPatch>(patch))
+        {}
+
+
+    // Member functions
+
+        //- Return message tag used for sending
+        virtual int tag() const
+        {
+            // Allocate from Pstream?
+            return procPolyPatch_.tag();
+        }
+
+        const processorCyclicPolyPatch& procPolyPatch() const
+        {
+            return procPolyPatch_;
+        }
+
+        //- Are the cyclic planes parallel
+        virtual bool parallel() const
+        {
+            return procPolyPatch_.parallel();
+        }
+
+        //- Return face transformation tensor
+        virtual const tensorField& forwardT() const
+        {
+            return procPolyPatch_.forwardT();
+        }
+
+        //- Return neighbour-cell transformation tensor
+        virtual const tensorField& reverseT() const
+        {
+            return procPolyPatch_.reverseT();
+        }
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/finiteVolume/fvMesh/singleCellFvMesh/singleCellFvMesh.C b/src/finiteVolume/fvMesh/singleCellFvMesh/singleCellFvMesh.C
index 4b93d83e5c828dc51371dc8c082202042d6b6b58..86a60d8a7a74ab3ee65de824731a067b7738b9e0 100644
--- a/src/finiteVolume/fvMesh/singleCellFvMesh/singleCellFvMesh.C
+++ b/src/finiteVolume/fvMesh/singleCellFvMesh/singleCellFvMesh.C
@@ -81,7 +81,7 @@ void Foam::singleCellFvMesh::agglomerateMesh
                 }
             }
         }
-        syncTools::swapBoundaryFaceList(mesh, nbrAgglom, false);
+        syncTools::swapBoundaryFaceList(mesh, nbrAgglom);
 
 
         // Get correspondence between this agglomeration and remote one
diff --git a/src/finiteVolume/interpolation/surfaceInterpolation/schemes/UpwindFitScheme/UpwindFitData.C b/src/finiteVolume/interpolation/surfaceInterpolation/schemes/UpwindFitScheme/UpwindFitData.C
index 47a7d69e46aa46d2762c12524f2b2cebc2c2c63c..b28ec8d4a8a2aa27b6c848d37caf69b78b8157cc 100644
--- a/src/finiteVolume/interpolation/surfaceInterpolation/schemes/UpwindFitScheme/UpwindFitData.C
+++ b/src/finiteVolume/interpolation/surfaceInterpolation/schemes/UpwindFitScheme/UpwindFitData.C
@@ -27,7 +27,6 @@ License
 #include "surfaceFields.H"
 #include "volFields.H"
 #include "SVD.H"
-#include "syncTools.H"
 #include "extendedUpwindCellToFaceStencil.H"
 
 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
diff --git a/src/lagrangian/basic/Particle/Particle.C b/src/lagrangian/basic/Particle/Particle.C
index b413211499ef6947f72bf5f701135663e8400808..5717e0c76d6ef84b0d1a9eef37c15357cff4015b 100644
--- a/src/lagrangian/basic/Particle/Particle.C
+++ b/src/lagrangian/basic/Particle/Particle.C
@@ -474,25 +474,27 @@ void Foam::Particle<ParticleType>::hitCyclicPatch
     TrackData&
 )
 {
-    label patchFacei_ = cpp.whichFace(facei_);
+//    label patchFacei_ = cpp.whichFace(facei_);
 
     facei_ = cpp.transformGlobalFace(facei_);
 
     celli_ = cloud_.polyMesh_.faceOwner()[facei_];
 
+    // Now the particle is on the receiving side
+
     if (!cpp.parallel())
     {
-        const tensor& T = cpp.transformT(patchFacei_);
+        const tensor& T = cpp.reverseT()[0];
 
         transformPosition(T);
         static_cast<ParticleType&>(*this).transformProperties(T);
     }
     else if (cpp.separated())
     {
-        position_ += cpp.separation(patchFacei_);
+        position_ += cpp.separation()[0];
         static_cast<ParticleType&>(*this).transformProperties
         (
-            cpp.separation(patchFacei_)
+            cpp.separation()[0]
         );
     }
 }
diff --git a/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriver.C b/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriver.C
index 50942e39c72629a59aa17dd957a4f6c4fa0f487b..20a7e76b66bde027f981a0d594ade30861758963 100644
--- a/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriver.C
+++ b/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriver.C
@@ -487,8 +487,7 @@ Foam::labelList Foam::autoLayerDriver::collectFaces
     (
         mesh,
         selected,
-        orEqOp<bool>(),     // combine operator
-        false               // separation
+        orEqOp<bool>()      // combine operator
     );
 
     labelList selectedFaces(findIndices(selected, true));
@@ -534,8 +533,7 @@ Foam::labelList Foam::autoLayerDriver::growFaceCellFace
     (
         mesh,
         selected,
-        orEqOp<bool>(),     // combine operator
-        false               // separation
+        orEqOp<bool>()      // combine operator
     );
     return findIndices(selected, true);
 }
@@ -1015,8 +1013,7 @@ void Foam::autoLayerDriver::handleFeatureAngle
             mesh,
             edgeNormal,
             nomalsCombine(),
-            point::max,  // null value
-            false                   // no separation
+            point::max          // null value
         );
 
         label vertI = 0;
@@ -1307,8 +1304,7 @@ void Foam::autoLayerDriver::setNumLayers
         pp.meshPoints(),
         maxLayers,
         maxEqOp<label>(),
-        labelMin,           // null value
-        false               // no separation
+        labelMin            // null value
     );
     syncTools::syncPointList
     (
@@ -1316,8 +1312,7 @@ void Foam::autoLayerDriver::setNumLayers
         pp.meshPoints(),
         minLayers,
         minEqOp<label>(),
-        labelMax,           // null value
-        false               // no separation
+        labelMax            // null value
     );
 
     // Unmark any point with different min and max
@@ -1434,8 +1429,7 @@ void Foam::autoLayerDriver::growNoExtrusion
             pp.meshPoints(),
             status,
             minEqOp<label>(),
-            labelMax,           // null value
-            false               // no separation
+            labelMax            // null value
         );
         forAll(status, i)
         {
@@ -1528,8 +1522,7 @@ void Foam::autoLayerDriver::calculateLayerThickness
         pp.meshPoints(),
         expansionRatio,
         minEqOp<scalar>(),
-        GREAT,              // null value
-        false               // no separation
+        GREAT               // null value
     );
     syncTools::syncPointList
     (
@@ -1537,8 +1530,7 @@ void Foam::autoLayerDriver::calculateLayerThickness
         pp.meshPoints(),
         thickness,
         minEqOp<scalar>(),
-        GREAT,              // null value
-        false               // no separation
+        GREAT               // null value
     );
     syncTools::syncPointList
     (
@@ -1546,8 +1538,7 @@ void Foam::autoLayerDriver::calculateLayerThickness
         pp.meshPoints(),
         minThickness,
         minEqOp<scalar>(),
-        GREAT,              // null value
-        false               // no separation
+        GREAT               // null value
     );
 
 
@@ -1594,8 +1585,7 @@ void Foam::autoLayerDriver::calculateLayerThickness
             pp.meshPoints(),
             maxPointLevel,
             maxEqOp<label>(),
-            labelMin,           // null value
-            false               // no separation
+            labelMin            // null value
         );
 
 
@@ -1664,8 +1654,7 @@ void Foam::autoLayerDriver::syncPatchDisplacement
             meshPoints,
             patchDisp,
             minEqOp<vector>(),
-            point::max,          // null value
-            false                           // no separation
+            point::max           // null value
         );
 
         // Unmark if displacement too small
@@ -1697,8 +1686,7 @@ void Foam::autoLayerDriver::syncPatchDisplacement
             meshPoints,
             syncPatchNLayers,
             minEqOp<label>(),
-            labelMax,           // null value
-            false               // no separation
+            labelMax            // null value
         );
 
         // Reset if differs
@@ -1728,8 +1716,7 @@ void Foam::autoLayerDriver::syncPatchDisplacement
             meshPoints,
             syncPatchNLayers,
             maxEqOp<label>(),
-            labelMin,           // null value
-            false               // no separation
+            labelMin            // null value
         );
 
         // Reset if differs
@@ -1815,8 +1802,7 @@ void Foam::autoLayerDriver::getPatchDisplacement
             meshPoints,
             pointNormals,
             plusEqOp<vector>(),
-            vector::zero,       // null value
-            false               // no separation
+            vector::zero        // null value
         );
 
         syncTools::syncPointList
@@ -1825,8 +1811,7 @@ void Foam::autoLayerDriver::getPatchDisplacement
             meshPoints,
             nPointFaces,
             plusEqOp<label>(),
-            0,                  // null value
-            false               // no separation
+            0                   // null value
         );
 
         forAll(pointNormals, i)
@@ -2258,8 +2243,7 @@ void Foam::autoLayerDriver::setupLayerInfoTruncation
                     pp.meshPoints(),
                     foundNeighbour,
                     orEqOp<bool>(),
-                    false,              // null value
-                    false               // no separation
+                    false               // null value
                 );
 
                 forAll(pp.meshPoints(), patchPointI)
@@ -2318,8 +2302,7 @@ void Foam::autoLayerDriver::setupLayerInfoTruncation
             pp.meshPoints(),
             nPatchPointLayers,
             maxEqOp<label>(),
-            0,                  // null value
-            false               // no separation
+            0                   // null value
         );
     }
 }
diff --git a/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriverShrink.C b/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriverShrink.C
index 56597063fcdae8cbca33878009b2471a795fd87f..ae0a2d724d022532afa4129190ed2b4ec872398f 100644
--- a/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriverShrink.C
+++ b/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriverShrink.C
@@ -67,8 +67,7 @@ void Foam::autoLayerDriver::sumWeights
         meshPoints,
         invSumWeight,
         plusEqOp<scalar>(),
-        scalar(0.0),        // null value
-        false               // no separation
+        scalar(0.0)         // null value
     );
 
     forAll(invSumWeight, pointI)
@@ -521,8 +520,7 @@ void Foam::autoLayerDriver::findIsolatedRegions
             pp.meshPoints(),
             keptPoints,
             orEqOp<bool>(),
-            false,              // null value
-            false               // no separation
+            false               // null value
         );
 
         label nChanged = 0;
@@ -589,8 +587,7 @@ void Foam::autoLayerDriver::findIsolatedRegions
         pp.meshPoints(),
         isolatedPoint,
         plusEqOp<label>(),
-        0,       // null value
-        false    // no separation
+        0        // null value
     );
 
     // stop layer growth on isolated faces
@@ -724,8 +721,7 @@ void Foam::autoLayerDriver::medialAxisSmoothingInfo
             meshPoints,
             pointNormals,
             plusEqOp<vector>(),
-            vector::zero,       // null value
-            false               // no separation
+            vector::zero        // null value
         );
 
         syncTools::syncPointList
@@ -734,8 +730,7 @@ void Foam::autoLayerDriver::medialAxisSmoothingInfo
             meshPoints,
             nPointFaces,
             plusEqOp<label>(),
-            0,                  // null value
-            false               // no separation
+            0                   // null value
         );
 
         forAll(pointNormals, i)
diff --git a/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriverTemplates.C b/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriverTemplates.C
index d8784f5d03506db4025e396441197ba969a8fa7e..73f797dd8a29af3b950bbdfb4093909904d1163f 100644
--- a/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriverTemplates.C
+++ b/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriverTemplates.C
@@ -64,8 +64,7 @@ void Foam::autoLayerDriver::averageNeighbours
         meshPoints,
         average,
         plusEqOp<Type>(),
-        pTraits<Type>::zero,    // null value
-        false                   // no separation
+        pTraits<Type>::zero     // null value
     );
 
     average *= invSumWeight;
diff --git a/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoSnapDriver.C b/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoSnapDriver.C
index a73e7bdcf606b1bd05b253cc612da9a159ab4396..0801f4de3e30ad56c349a5be21aa1f57cfb70588 100644
--- a/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoSnapDriver.C
+++ b/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoSnapDriver.C
@@ -274,8 +274,7 @@ Foam::pointField Foam::autoSnapDriver::smoothPatchDisplacement
         pp.meshPoints(),
         avgBoundary,
         plusEqOp<point>(),  // combine op
-        vector::zero,       // null value
-        false               // no separation
+        vector::zero        // null value
     );
     syncTools::syncPointList
     (
@@ -283,8 +282,7 @@ Foam::pointField Foam::autoSnapDriver::smoothPatchDisplacement
         pp.meshPoints(),
         nBoundary,
         plusEqOp<label>(),  // combine op
-        0,                  // null value
-        false               // no separation
+        0                   // null value
     );
 
     forAll(avgBoundary, i)
@@ -322,36 +320,18 @@ Foam::pointField Foam::autoSnapDriver::smoothPatchDisplacement
 
         forAll(patches, patchI)
         {
-            if (Pstream::parRun() && isA<processorPolyPatch>(patches[patchI]))
-            {
-                const processorPolyPatch& pp =
-                    refCast<const processorPolyPatch>(patches[patchI]);
-
-                if (pp.myProcNo() < pp.neighbProcNo())
-                {
-                    const vectorField::subField faceCentres = pp.faceCentres();
-
-                    forAll(pp, i)
-                    {
-                        const face& f = pp[i];
-                        const point& fc = faceCentres[i];
-
-                        forAll(f, fp)
-                        {
-                            globalSum[f[fp]] += fc;
-                            globalNum[f[fp]]++;
-                        }
-                    }
-                }
-            }
-            else if (isA<cyclicPolyPatch>(patches[patchI]))
+            if
+            (
+                patches[patchI].coupled()
+             && refCast<const coupledPolyPatch>(patches[patchI]).owner()
+            )
             {
-                const cyclicPolyPatch& pp =
-                    refCast<const cyclicPolyPatch>(patches[patchI]);
+                const coupledPolyPatch& pp =
+                    refCast<const coupledPolyPatch>(patches[patchI]);
 
                 const vectorField::subField faceCentres = pp.faceCentres();
 
-                for (label i = 0; i < pp.size()/2; i++)
+                forAll(pp, i)
                 {
                     const face& f = pp[i];
                     const point& fc = faceCentres[i];
@@ -370,16 +350,14 @@ Foam::pointField Foam::autoSnapDriver::smoothPatchDisplacement
             mesh,
             globalSum,
             plusEqOp<vector>(), // combine op
-            vector::zero,       // null value
-            false               // no separation
+            vector::zero        // null value
         );
         syncTools::syncPointList
         (
             mesh,
             globalNum,
             plusEqOp<label>(),  // combine op
-            0,                  // null value
-            false               // no separation
+            0                   // null value
         );
 
         avgInternal.setSize(meshPoints.size());
@@ -815,8 +793,7 @@ Foam::scalarField Foam::autoSnapDriver::calcSnapDistance
         pp.meshPoints(),
         maxEdgeLen,
         maxEqOp<scalar>(),  // combine op
-        -GREAT,             // null value
-        false               // no separation
+        -GREAT              // null value
     );
 
     return snapParams.snapTol()*maxEdgeLen;
@@ -1123,8 +1100,7 @@ Foam::vectorField Foam::autoSnapDriver::calcNearestSurface
         pp.meshPoints(),
         patchDisp,
         minMagEqOp(),                   // combine op
-        vector(GREAT, GREAT, GREAT),    // null value
-        false                           // no separation
+        vector(GREAT, GREAT, GREAT)     // null value
     );
 
 
@@ -1178,7 +1154,7 @@ void Foam::autoSnapDriver::smoothDisplacement
         }
         pointVectorField oldDisp(disp);
 
-        meshMover.smooth(oldDisp, edgeGamma, false, disp);
+        meshMover.smooth(oldDisp, edgeGamma, disp);
     }
     Info<< "Displacement smoothed in = "
         << mesh.time().cpuTimeIncrement() << " s\n" << nl << endl;
diff --git a/src/mesh/autoMesh/autoHexMesh/meshRefinement/meshRefinement.C b/src/mesh/autoMesh/autoHexMesh/meshRefinement/meshRefinement.C
index 12298ce6e1669f793ff6050f1c4b6e88af98d469..0622273a4ef922a6342de997919c1a1eefb82a7a 100644
--- a/src/mesh/autoMesh/autoHexMesh/meshRefinement/meshRefinement.C
+++ b/src/mesh/autoMesh/autoHexMesh/meshRefinement/meshRefinement.C
@@ -146,8 +146,8 @@ void Foam::meshRefinement::calcNeighbourData
     }
 
     // Swap coupled boundaries. Apply separation to cc since is coordinate.
-    syncTools::swapBoundaryFaceList(mesh_, neiCc, true);
-    syncTools::swapBoundaryFaceList(mesh_, neiLevel, false);
+    syncTools::swapBoundaryFacePositions(mesh_, neiCc);
+    syncTools::swapBoundaryFaceList(mesh_, neiLevel);
 }
 
 
@@ -235,7 +235,7 @@ void Foam::meshRefinement::updateIntersections(const labelList& changedFaces)
 
     // Make sure both sides have same information. This should be
     // case in general since same vectors but just to make sure.
-    syncTools::syncFaceList(mesh_, surfaceIndex_, maxEqOp<label>(), false);
+    syncTools::syncFaceList(mesh_, surfaceIndex_, maxEqOp<label>());
 
     label nHits = countHits();
     label nTotHits = returnReduce(nHits, sumOp<label>());
@@ -275,11 +275,11 @@ void Foam::meshRefinement::checkData()
 
         // Get neighbouring face centres
         pointField neiBoundaryFc(boundaryFc);
-        syncTools::swapBoundaryFaceList
+        syncTools::syncBoundaryFacePositions
         (
             mesh_,
             neiBoundaryFc,
-            true
+            eqOp<point>()
         );
 
         // Compare
@@ -339,7 +339,7 @@ void Foam::meshRefinement::checkData()
                 mesh_.nInternalFaces()
             )
         );
-        syncTools::swapBoundaryFaceList(mesh_, neiHit, false);
+        syncTools::swapBoundaryFaceList(mesh_, neiHit);
 
         // Check
         forAll(surfaceHit, faceI)
@@ -390,8 +390,7 @@ void Foam::meshRefinement::checkData()
         syncTools::swapBoundaryFaceList
         (
             mesh_,
-            neiBoundarySurface,
-            false
+            neiBoundarySurface
         );
 
         // Compare
@@ -1158,8 +1157,7 @@ Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::meshRefinement::balance
                 (
                     mesh_,
                     blockedFace,
-                    andEqOp<bool>(),    // combine operator
-                    false               // separation
+                    andEqOp<bool>()     // combine operator
                 );
             }
             reduce(nUnblocked, sumOp<label>());
@@ -1527,7 +1525,7 @@ void Foam::meshRefinement::checkCoupledFaceZones(const polyMesh& mesh)
     }
 
     labelList neiFaceToZone(faceToZone);
-    syncTools::swapBoundaryFaceList(mesh, neiFaceToZone, false);
+    syncTools::swapBoundaryFaceList(mesh, neiFaceToZone);
 
     forAll(faceToZone, i)
     {
diff --git a/src/mesh/autoMesh/autoHexMesh/meshRefinement/meshRefinementBaffles.C b/src/mesh/autoMesh/autoHexMesh/meshRefinement/meshRefinementBaffles.C
index 2491f557fb54cbc6e0dc876fae235d183ffff451..0eabd33adc2eaa89dc0f3628f2a3bc0c073284f2 100644
--- a/src/mesh/autoMesh/autoHexMesh/meshRefinement/meshRefinementBaffles.C
+++ b/src/mesh/autoMesh/autoHexMesh/meshRefinement/meshRefinementBaffles.C
@@ -354,8 +354,8 @@ void Foam::meshRefinement::getBafflePatches
     //   might not be owner on the other processor but the neighbour is
     //   not used when creating baffles from proc faces.
     // - tolerances issues occasionally crop up.
-    syncTools::syncFaceList(mesh_, ownPatch, maxEqOp<label>(), false);
-    syncTools::syncFaceList(mesh_, neiPatch, maxEqOp<label>(), false);
+    syncTools::syncFaceList(mesh_, ownPatch, maxEqOp<label>());
+    syncTools::syncFaceList(mesh_, neiPatch, maxEqOp<label>());
 }
 
 
@@ -386,9 +386,9 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::meshRefinement::createBaffles
     if (debug)
     {
         labelList syncedOwnPatch(ownPatch);
-        syncTools::syncFaceList(mesh_, syncedOwnPatch, maxEqOp<label>(), false);
+        syncTools::syncFaceList(mesh_, syncedOwnPatch, maxEqOp<label>());
         labelList syncedNeiPatch(neiPatch);
-        syncTools::syncFaceList(mesh_, syncedNeiPatch, maxEqOp<label>(), false);
+        syncTools::syncFaceList(mesh_, syncedNeiPatch, maxEqOp<label>());
 
         forAll(syncedOwnPatch, faceI)
         {
@@ -669,8 +669,7 @@ Foam::List<Foam::labelPair> Foam::meshRefinement::filterDuplicateFaces
         mesh_,
         nBafflesPerEdge,
         plusEqOp<label>(),  // in-place add
-        0,                  // initial value
-        false               // no separation
+        0                   // initial value
     );
 
 
@@ -1030,7 +1029,7 @@ void Foam::meshRefinement::findCellZoneGeometric
             }
         }
     }
-    syncTools::swapBoundaryFaceList(mesh_, neiCellZone, false);
+    syncTools::swapBoundaryFaceList(mesh_, neiCellZone);
 
     forAll(patches, patchI)
     {
@@ -1058,13 +1057,7 @@ void Foam::meshRefinement::findCellZoneGeometric
     }
 
     // Sync
-    syncTools::syncFaceList
-    (
-        mesh_,
-        namedSurfaceIndex,
-        maxEqOp<label>(),
-        false
-    );
+    syncTools::syncFaceList(mesh_, namedSurfaceIndex, maxEqOp<label>());
 }
 //XXXXXXXXX
 void Foam::meshRefinement::findCellZoneInsideWalk
@@ -1371,7 +1364,7 @@ void Foam::meshRefinement::findCellZoneTopo
                 }
             }
         }
-        syncTools::swapBoundaryFaceList(mesh_, neiCellRegion, false);
+        syncTools::swapBoundaryFaceList(mesh_, neiCellRegion);
 
         // Calculate region to zone from cellRegions on either side of coupled
         // face.
@@ -1492,7 +1485,7 @@ void Foam::meshRefinement::makeConsistentFaceIndex
             }
         }
     }
-    syncTools::swapBoundaryFaceList(mesh_, neiCellZone, false);
+    syncTools::swapBoundaryFaceList(mesh_, neiCellZone);
 
     // Use coupled cellZone to do check
     forAll(patches, patchI)
@@ -1812,7 +1805,7 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::meshRefinement::splitMesh
             blockedFace[faceI] = true;
         }
     }
-    syncTools::syncFaceList(mesh_, blockedFace, orEqOp<bool>(), false);
+    syncTools::syncFaceList(mesh_, blockedFace, orEqOp<bool>());
 
     // Set region per cell based on walking
     regionSplit cellRegion(mesh_, blockedFace);
@@ -1924,8 +1917,7 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::meshRefinement::splitMesh
             mesh_,
             pointBaffle,
             maxEqOp<label>(),
-            -1,                 // null value
-            false               // no separation
+            -1                  // null value
         );
 
 
@@ -1950,7 +1942,7 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::meshRefinement::splitMesh
                 }
             }
         }
-        syncTools::syncFaceList(mesh_, ownPatch, maxEqOp<label>(), false);
+        syncTools::syncFaceList(mesh_, ownPatch, maxEqOp<label>());
 
 
         // 3. From faces to cells (cellRegion) and back to faces (ownPatch)
@@ -1999,7 +1991,7 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::meshRefinement::splitMesh
 
         ownPatch.transfer(newOwnPatch);
 
-        syncTools::syncFaceList(mesh_, ownPatch, maxEqOp<label>(), false);
+        syncTools::syncFaceList(mesh_, ownPatch, maxEqOp<label>());
     }
 
 
@@ -2376,8 +2368,7 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::meshRefinement::zonify
         (
             mesh_,
             namedSurfaceIndex,
-            maxEqOp<label>(),
-            false
+            maxEqOp<label>()
         );
 
         // Print a bit
@@ -2541,7 +2532,7 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::meshRefinement::zonify
             }
         }
     }
-    syncTools::swapBoundaryFaceList(mesh_, neiCellZone, false);
+    syncTools::swapBoundaryFaceList(mesh_, neiCellZone);
 
     // Get per face whether is it master (of a coupled set of faces)
     PackedBoolList isMasterFace(syncTools::getMasterFaces(mesh_));
diff --git a/src/mesh/autoMesh/autoHexMesh/meshRefinement/meshRefinementProblemCells.C b/src/mesh/autoMesh/autoHexMesh/meshRefinement/meshRefinementProblemCells.C
index f4a887279ead27b9f88ca46db27b4e3f11f957c9..5bef117c7f44bb9f61713de43564c6ac3c21a083 100644
--- a/src/mesh/autoMesh/autoHexMesh/meshRefinement/meshRefinementProblemCells.C
+++ b/src/mesh/autoMesh/autoHexMesh/meshRefinement/meshRefinementProblemCells.C
@@ -496,8 +496,7 @@ Foam::labelList Foam::meshRefinement::markFacesOnProblemCells
         mesh_,
         isBoundaryPoint,
         orEqOp<bool>(),
-        false,              // null value
-        false               // no separation
+        false               // null value
     );
 
     syncTools::syncEdgeList
@@ -505,16 +504,14 @@ Foam::labelList Foam::meshRefinement::markFacesOnProblemCells
         mesh_,
         isBoundaryEdge,
         orEqOp<bool>(),
-        false,              // null value
-        false               // no separation
+        false               // null value
     );
 
     syncTools::syncFaceList
     (
         mesh_,
         isBoundaryFace,
-        orEqOp<bool>(),
-        false               // no separation
+        orEqOp<bool>()
     );
 
 
@@ -807,8 +804,7 @@ Foam::labelList Foam::meshRefinement::markFacesOnProblemCells
         mesh_,
         isBoundaryPoint,
         orEqOp<bool>(),
-        false,              // null value
-        false               // no separation
+        false               // null value
     );
 
     syncTools::syncEdgeList
@@ -816,16 +812,14 @@ Foam::labelList Foam::meshRefinement::markFacesOnProblemCells
         mesh_,
         isBoundaryEdge,
         orEqOp<bool>(),
-        false,              // null value
-        false               // no separation
+        false               // null value
     );
 
     syncTools::syncFaceList
     (
         mesh_,
         isBoundaryFace,
-        orEqOp<bool>(),
-        false               // no separation
+        orEqOp<bool>()
     );
 
 
@@ -1109,8 +1103,7 @@ Foam::labelList Foam::meshRefinement::markFacesOnProblemCells
 //    (
 //        mesh_,
 //        facePatch,
-//        maxEqOp<label>(),
-//        false               // no separation
+//        maxEqOp<label>()
 //    );
 //
 //    return facePatch;
diff --git a/src/mesh/autoMesh/autoHexMesh/meshRefinement/meshRefinementRefine.C b/src/mesh/autoMesh/autoHexMesh/meshRefinement/meshRefinementRefine.C
index 23a0bfe6901ab801271d33890eb4e17f4c96c0d5..7a1968500f21020a4402b6a64b61230493d1a0fb 100644
--- a/src/mesh/autoMesh/autoHexMesh/meshRefinement/meshRefinementRefine.C
+++ b/src/mesh/autoMesh/autoHexMesh/meshRefinement/meshRefinementRefine.C
@@ -133,8 +133,7 @@ Foam::labelList Foam::meshRefinement::getChangedFaces
         (
             mesh,
             refinedBoundaryFace,
-            orEqOp<bool>(),
-            false
+            orEqOp<bool>()
         );
 
 
@@ -176,8 +175,7 @@ Foam::labelList Foam::meshRefinement::getChangedFaces
         (
             mesh,
             changedFace,
-            orEqOp<bool>(),
-            false
+            orEqOp<bool>()
         );
 
 
@@ -925,8 +923,8 @@ Foam::label Foam::meshRefinement::markSurfaceCurvatureRefinement
         neiBndMaxLevel[bFaceI] = cellMaxLevel[own];
         neiBndMaxNormal[bFaceI] = cellMaxNormal[own];
     }
-    syncTools::swapBoundaryFaceList(mesh_, neiBndMaxLevel, false);
-    syncTools::swapBoundaryFaceList(mesh_, neiBndMaxNormal, false);
+    syncTools::swapBoundaryFaceList(mesh_, neiBndMaxLevel);
+    syncTools::swapBoundaryFaceList(mesh_, neiBndMaxNormal);
 
     // Loop over all faces. Could only be checkFaces.. except if they're coupled
 
diff --git a/src/mesh/blockMesh/blockMesh/blockMesh.C b/src/mesh/blockMesh/blockMesh/blockMesh.C
index fc79070eee323c8b29c17ac69b2d9a36e820058a..8641c44a717fc9c9ab3e46a7a262e7decbd286e2 100644
--- a/src/mesh/blockMesh/blockMesh/blockMesh.C
+++ b/src/mesh/blockMesh/blockMesh/blockMesh.C
@@ -77,6 +77,24 @@ const Foam::polyMesh& Foam::blockMesh::topology() const
 }
 
 
+Foam::PtrList<Foam::dictionary> Foam::blockMesh::patchDicts() const
+{
+    const polyPatchList& patchTopologies = topology().boundaryMesh();
+
+    PtrList<dictionary> patchDicts(patchTopologies.size());
+
+    forAll(patchTopologies, patchI)
+    {
+        OStringStream os;
+        patchTopologies[patchI].write(os);
+        IStringStream is(os.str());
+        patchDicts.set(patchI, new dictionary(is));
+        patchDicts[patchI].set("name", patchTopologies[patchI].name());
+    }
+    return patchDicts;
+}
+
+
 Foam::scalar Foam::blockMesh::scaleFactor() const
 {
     return scaleFactor_;
@@ -116,22 +134,22 @@ const Foam::faceListList& Foam::blockMesh::patches() const
 }
 
 
-Foam::wordList Foam::blockMesh::patchNames() const
-{
-    return topology().boundaryMesh().names();
-}
-
-
-Foam::wordList Foam::blockMesh::patchTypes() const
-{
-    return topology().boundaryMesh().types();
-}
-
-
-Foam::wordList Foam::blockMesh::patchPhysicalTypes() const
-{
-    return topology().boundaryMesh().physicalTypes();
-}
+//Foam::wordList Foam::blockMesh::patchNames() const
+//{
+//    return topology().boundaryMesh().names();
+//}
+//
+//
+//Foam::wordList Foam::blockMesh::patchTypes() const
+//{
+//    return topology().boundaryMesh().types();
+//}
+//
+//
+//Foam::wordList Foam::blockMesh::patchPhysicalTypes() const
+//{
+//    return topology().boundaryMesh().physicalTypes();
+//}
 
 
 Foam::label Foam::blockMesh::numZonedBlocks() const
diff --git a/src/mesh/blockMesh/blockMesh/blockMesh.H b/src/mesh/blockMesh/blockMesh/blockMesh.H
index 4d1b1deb0aa285ef7234aaa77013cc55222290c1..fa91e40b689352a31ef165fbaef1740b3b4fa516 100644
--- a/src/mesh/blockMesh/blockMesh/blockMesh.H
+++ b/src/mesh/blockMesh/blockMesh/blockMesh.H
@@ -109,6 +109,24 @@ class blockMesh
             const faceList& patchShapes
         ) const;
 
+        bool readPatches
+        (
+            const dictionary& meshDescription,
+            faceListList& tmpBlocksPatches,
+            wordList& patchNames,
+            wordList& patchTypes,
+            wordList& nbrPatchNames
+        );
+
+        bool readBoundary
+        (
+            const dictionary& meshDescription,
+            faceListList& tmpBlocksPatches,
+            PtrList<dictionary>& patchDicts
+        );
+
+        void createCellShapes(cellShapeList& tmpBlockCells);
+
         polyMesh* createTopology(IOdictionary&);
         void checkBlockMesh(const polyMesh&) const;
 
@@ -163,11 +181,15 @@ public:
 
             const faceListList& patches() const;
 
-            wordList patchNames() const;
 
-            wordList patchTypes() const;
+            //- Get patch information from the topology mesh
+            PtrList<dictionary> patchDicts() const;
 
-            wordList patchPhysicalTypes() const;
+//            wordList patchNames() const;
+//
+//            wordList patchTypes() const;
+//
+//            wordList patchPhysicalTypes() const;
 
             //- Number of blocks with specified zones
             label numZonedBlocks() const;
diff --git a/src/mesh/blockMesh/blockMesh/blockMeshTopology.C b/src/mesh/blockMesh/blockMesh/blockMeshTopology.C
index 62d30c38965f862553b9b8bd464c0dbff079853e..9a962483681826ed40c7855855e397b8895527b3 100644
--- a/src/mesh/blockMesh/blockMesh/blockMeshTopology.C
+++ b/src/mesh/blockMesh/blockMesh/blockMeshTopology.C
@@ -27,11 +27,232 @@ License
 #include "Time.H"
 #include "preservePatchTypes.H"
 #include "emptyPolyPatch.H"
+#include "cyclicPolyPatch.H"
+
+
+bool Foam::blockMesh::readPatches
+(
+    const dictionary& meshDescription,
+    faceListList& tmpBlocksPatches,
+    wordList& patchNames,
+    wordList& patchTypes,
+    wordList& nbrPatchNames
+)
+{
+    bool topologyOK = true;
+
+    ITstream& patchStream(meshDescription.lookup("patches"));
+
+    // read number of patches in mesh
+    label nPatches = 0;
+
+    token firstToken(patchStream);
+
+    if (firstToken.isLabel())
+    {
+        nPatches = firstToken.labelToken();
+
+        tmpBlocksPatches.setSize(nPatches);
+        patchNames.setSize(nPatches);
+        patchTypes.setSize(nPatches);
+        nbrPatchNames.setSize(nPatches);
+    }
+    else
+    {
+        patchStream.putBack(firstToken);
+    }
+
+    // Read beginning of blocks
+    patchStream.readBegin("patches");
+
+    nPatches = 0;
+
+    token lastToken(patchStream);
+    while
+    (
+        !(
+            lastToken.isPunctuation()
+            && lastToken.pToken() == token::END_LIST
+        )
+    )
+    {
+        if (tmpBlocksPatches.size() <= nPatches)
+        {
+            tmpBlocksPatches.setSize(nPatches + 1);
+            patchNames.setSize(nPatches + 1);
+            patchTypes.setSize(nPatches + 1);
+            nbrPatchNames.setSize(nPatches + 1);
+        }
+
+        patchStream.putBack(lastToken);
+
+        patchStream
+            >> patchTypes[nPatches]
+            >> patchNames[nPatches];
+
+        // Read patch faces
+        patchStream >> tmpBlocksPatches[nPatches];
+
+
+        // Catch multiple patches asap.
+        for (label i = 0; i < nPatches; i++)
+        {
+            if (patchNames[nPatches] == patchNames[i])
+            {
+                FatalErrorIn
+                (
+                    "blockMesh::createTopology(IOdictionary&)"
+                )   << "Duplicate patch " << patchNames[nPatches]
+                    << " at line " << patchStream.lineNumber()
+                    << ". Exiting !" << nl
+                    << exit(FatalError);
+            }
+        }
+
+        topologyOK = topologyOK && patchLabelsOK
+        (
+            nPatches,
+            blockPointField_,
+            tmpBlocksPatches[nPatches]
+        );
+
+        nPatches++;
+
+
+        // Split old style cyclics
+
+        if (patchTypes[nPatches-1] == cyclicPolyPatch::typeName)
+        {
+            word halfA = patchNames[nPatches-1] + "_half0";
+            word halfB = patchNames[nPatches-1] + "_half1";
+
+            WarningIn("blockMesh::createTopology(IOdictionary&)")
+                << "Old-style cyclic definition."
+                << " Splitting patch "
+                << patchNames[nPatches-1] << " into two halves "
+                << halfA << " and " << halfB << endl
+                << "    Alternatively use new 'boundary' dictionary syntax."
+                << endl;
+
+            // Add extra patch
+            if (tmpBlocksPatches.size() <= nPatches)
+            {
+                tmpBlocksPatches.setSize(nPatches + 1);
+                patchNames.setSize(nPatches + 1);
+                patchTypes.setSize(nPatches + 1);
+                nbrPatchNames.setSize(nPatches + 1);
+            }
+
+            // Update halfA info
+            patchNames[nPatches-1] = halfA;
+            nbrPatchNames[nPatches-1] = halfB;
+            // Update halfB info
+            patchTypes[nPatches] = patchTypes[nPatches-1];
+            patchNames[nPatches] = halfB;
+            nbrPatchNames[nPatches] = halfA;
+
+            // Split faces
+            if ((tmpBlocksPatches[nPatches-1].size() % 2) != 0)
+            {
+                FatalErrorIn
+                (
+                    "blockMesh::createTopology(IOdictionary&)"
+                )   << "Size of cyclic faces is not a multiple of 2 :"
+                    << tmpBlocksPatches[nPatches-1]
+                    << exit(FatalError);
+            }
+            label sz = tmpBlocksPatches[nPatches-1].size()/2;
+            faceList unsplitFaces(tmpBlocksPatches[nPatches-1], true);
+            tmpBlocksPatches[nPatches-1] = faceList
+            (
+                SubList<face>(unsplitFaces, sz)
+            );
+            tmpBlocksPatches[nPatches] = faceList
+            (
+                SubList<face>(unsplitFaces, sz, sz)
+            );
+
+            nPatches++;
+        }
+
+        patchStream >> lastToken;
+    }
+    patchStream.putBack(lastToken);
+
+    // Read end of blocks
+    patchStream.readEnd("patches");
+
+    return topologyOK;
+}
+
+
+bool Foam::blockMesh::readBoundary
+(
+    const dictionary& meshDescription,
+    faceListList& tmpBlocksPatches,
+    PtrList<dictionary>& patchDicts
+)
+{
+    bool topologyOK = true;
+
+    // Read like boundary file
+    const PtrList<entry> patchesInfo
+    (
+        meshDescription.lookup("boundary")
+    );
+
+    tmpBlocksPatches.setSize(patchesInfo.size());
+    patchDicts.setSize(patchesInfo.size());
+
+    forAll(tmpBlocksPatches, patchI)
+    {
+        const entry& patchInfo = patchesInfo[patchI];
+
+        // Construct dictionary and add name
+        patchDicts.set(patchI, new dictionary(patchInfo.dict()));
+        patchDicts[patchI].set("name", patchInfo.keyword());
+        // Read block faces
+        patchDicts[patchI].lookup("faces") >> tmpBlocksPatches[patchI];
+
+        topologyOK = topologyOK && patchLabelsOK
+        (
+            patchI,
+            blockPointField_,
+            tmpBlocksPatches[patchI]
+        );
+    }
+
+    return topologyOK;
+}
+
+
+void Foam::blockMesh::createCellShapes
+(
+    cellShapeList& tmpBlockCells
+)
+{
+    const blockMesh& blocks = *this;
+
+    tmpBlockCells.setSize(blocks.size());
+    forAll(blocks, blockI)
+    {
+        tmpBlockCells[blockI] = cellShape(blocks[blockI].blockShape());
+
+        if (tmpBlockCells[blockI].mag(blockPointField_) < 0.0)
+        {
+            WarningIn
+            (
+                "blockMesh::createTopology(IOdictionary&)"
+            )   << "negative volume block : " << blockI
+                << ", probably defined inside-out" << endl;
+        }
+    }
+}
 
 
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
-Foam::polyMesh* Foam::blockMesh::createTopology(IOdictionary& dict)
+Foam::polyMesh* Foam::blockMesh::createTopology(IOdictionary& meshDescription)
 {
     bool topologyOK = true;
 
@@ -43,30 +264,30 @@ Foam::polyMesh* Foam::blockMesh::createTopology(IOdictionary& dict)
     // get names/types for the unassigned patch faces
     // this is a bit heavy handed (and ugly), but there is currently
     // no easy way to rename polyMesh patches subsequently
-    if (const dictionary* dictPtr = dict.subDictPtr("defaultPatch"))
+    if (const dictionary* dictPtr = meshDescription.subDictPtr("defaultPatch"))
     {
         dictPtr->readIfPresent("name", defaultPatchName);
         dictPtr->readIfPresent("type", defaultPatchType);
     }
 
     // optional 'convertToMeters' or 'scale'  scaling factor
-    if (!dict.readIfPresent("convertToMeters", scaleFactor_))
+    if (!meshDescription.readIfPresent("convertToMeters", scaleFactor_))
     {
-        dict.readIfPresent("scale", scaleFactor_);
+        meshDescription.readIfPresent("scale", scaleFactor_);
     }
 
 
     //
     // get the non-linear edges in mesh
     //
-    if (dict.found("edges"))
+    if (meshDescription.found("edges"))
     {
         if (verboseOutput)
         {
             Info<< "Creating curved edges" << endl;
         }
 
-        ITstream& is(dict.lookup("edges"));
+        ITstream& is(meshDescription.lookup("edges"));
 
         // read number of edges in mesh
         label nEdges = 0;
@@ -134,7 +355,7 @@ Foam::polyMesh* Foam::blockMesh::createTopology(IOdictionary& dict)
     }
 
     {
-        ITstream& is(dict.lookup("blocks"));
+        ITstream& is(meshDescription.lookup("blocks"));
 
         // read number of blocks in mesh
         label nBlocks = 0;
@@ -201,6 +422,8 @@ Foam::polyMesh* Foam::blockMesh::createTopology(IOdictionary& dict)
     }
 
 
+    polyMesh* blockMeshPtr = NULL;
+
     //
     // Create the patches
     //
@@ -209,160 +432,140 @@ Foam::polyMesh* Foam::blockMesh::createTopology(IOdictionary& dict)
         Info<< "Creating topology patches" << endl;
     }
 
-    faceListList tmpBlocksPatches;
-    wordList patchNames;
-    wordList patchTypes;
-
+    if (meshDescription.found("patches"))
     {
-        ITstream& is(dict.lookup("patches"));
+        Info<< nl << "Reading patches section" << endl;
 
-        // read number of patches in mesh
-        label nPatches = 0;
-
-        token firstToken(is);
-
-        if (firstToken.isLabel())
-        {
-            nPatches = firstToken.labelToken();
+        faceListList tmpBlocksPatches;
+        wordList patchNames;
+        wordList patchTypes;
+        wordList nbrPatchNames;
 
-            tmpBlocksPatches.setSize(nPatches);
-            patchNames.setSize(nPatches);
-            patchTypes.setSize(nPatches);
-        }
-        else
+        topologyOK = topologyOK && readPatches
+        (
+            meshDescription,
+            tmpBlocksPatches,
+            patchNames,
+            patchTypes,
+            nbrPatchNames
+        );
+
+        if (!topologyOK)
         {
-            is.putBack(firstToken);
+            FatalErrorIn("blockMesh::createTopology(IOdictionary&)")
+                << "Cannot create mesh due to errors in topology, exiting !"
+                << nl << exit(FatalError);
         }
 
-        // Read beginning of blocks
-        is.readBegin("patches");
+        Info<< nl << "Creating block mesh topology" << endl;
 
-        nPatches = 0;
+        cellShapeList tmpBlockCells(blocks.size());
+        createCellShapes(tmpBlockCells);
 
-        token lastToken(is);
-        while
+
+        Info<< nl << "Reading physicalType from existing boundary file" << endl;
+
+        wordList patchPhysicalTypes(tmpBlocksPatches.size());
+
+        preservePatchTypes
         (
-            !(
-                 lastToken.isPunctuation()
-              && lastToken.pToken() == token::END_LIST
-             )
-        )
+            meshDescription.time(),
+            meshDescription.time().constant(),
+            polyMesh::meshSubDir,
+            patchNames,
+            patchTypes,
+            defaultPatchName,
+            defaultPatchType,
+            patchPhysicalTypes
+        );
+
+
+        // Convert into dictionary
+        PtrList<dictionary> patchDicts(patchNames.size());
+        forAll(patchDicts, patchI)
         {
-            if (tmpBlocksPatches.size() <= nPatches)
+            patchDicts.set(patchI, new dictionary());
+            patchDicts[patchI].set("name", patchNames[patchI]);
+            patchDicts[patchI].set("type", patchTypes[patchI]);
+            if (nbrPatchNames[patchI] != word::null)
             {
-                tmpBlocksPatches.setSize(nPatches + 1);
-                patchNames.setSize(nPatches + 1);
-                patchTypes.setSize(nPatches + 1);
+                patchDicts[patchI].set("neighbourPatch", nbrPatchNames[patchI]);
             }
-
-            is.putBack(lastToken);
-
-            is
-                >> patchTypes[nPatches]
-                >> patchNames[nPatches]
-                >> tmpBlocksPatches[nPatches];
-
-
-            // Catch multiple patches asap.
-            for (label i = 0; i < nPatches; i++)
+            if (patchPhysicalTypes[patchI] != word::null)
             {
-                if (patchNames[nPatches] == patchNames[i])
-                {
-                    FatalErrorIn
-                    (
-                        "blockMesh::createTopology(IOdictionary&)"
-                    )   << "Duplicate patch " << patchNames[nPatches]
-                        << " at line " << is.lineNumber()
-                        << ". Exiting !" << nl
-                        << exit(FatalError);
-                }
+                patchDicts[patchI].set
+                (
+                    "physicalType",
+                    patchPhysicalTypes[patchI]
+                );
             }
-
-            topologyOK = topologyOK && patchLabelsOK
-            (
-                nPatches,
-                blockPointField_,
-                tmpBlocksPatches[nPatches]
-            );
-
-            nPatches++;
-
-            is >> lastToken;
         }
-        is.putBack(lastToken);
-
-        // Read end of blocks
-        is.readEnd("patches");
-    }
 
 
-    if (!topologyOK)
-    {
-        FatalErrorIn("blockMesh::createTopology(IOdictionary&)")
-            << "Cannot create mesh due to errors in topology, exiting !" << nl
-            << exit(FatalError);
+        blockMeshPtr = new polyMesh
+        (
+            IOobject
+            (
+                "blockMesh",
+                meshDescription.time().constant(),
+                meshDescription.time(),
+                IOobject::NO_READ,
+                IOobject::NO_WRITE,
+                false
+            ),
+            xferCopy(blockPointField_),   // copy these points, do NOT move
+            tmpBlockCells,
+            tmpBlocksPatches,
+            patchDicts,
+            defaultPatchName,
+            defaultPatchType
+        );
     }
-
-
-    //
-    // Create the topology
-    //
-    if (verboseOutput)
+    else if (meshDescription.found("boundary"))
     {
-        Info<< "Creating topology mesh" << endl;
-    }
+        faceListList tmpBlocksPatches;
+        PtrList<dictionary> patchDicts;
 
-    cellShapeList tmpBlockShapes(blocks.size());
-    forAll(blocks, blockI)
-    {
-        tmpBlockShapes[blockI] = cellShape(blocks[blockI].blockShape());
+        topologyOK = topologyOK && readBoundary
+        (
+            meshDescription,
+            tmpBlocksPatches,
+            patchDicts
+        );
 
-        if (tmpBlockShapes[blockI].mag(blockPointField_) < 0.0)
+        if (!topologyOK)
         {
-            WarningIn
-            (
-                "blockMesh::createTopology(IOdictionary&)"
-            )   << "negative volume block : " << blockI
-                << ", probably defined inside-out" << endl;
+            FatalErrorIn("blockMesh::createTopology(IOdictionary&)")
+                << "Cannot create mesh due to errors in topology, exiting !"
+                << nl << exit(FatalError);
         }
-    }
 
-    wordList patchPhysicalTypes(tmpBlocksPatches.size());
 
-    preservePatchTypes
-    (
-        dict.time(),
-        dict.time().constant(),
-        polyMesh::meshSubDir,
-        patchNames,
-        patchTypes,
-        defaultPatchName,
-        defaultPatchType,
-        patchPhysicalTypes
-    );
+        Info<< nl << "Creating block mesh topology" << endl;
 
+        cellShapeList tmpBlockCells(blocks.size());
+        createCellShapes(tmpBlockCells);
 
-    // construct the topology as its own mesh
-    polyMesh* blockMeshPtr = new polyMesh
-    (
-        IOobject
+
+        blockMeshPtr = new polyMesh
         (
-            "blockMesh",
-            dict.time().constant(),
-            dict.time(),
-            IOobject::NO_READ,
-            IOobject::NO_WRITE,
-            false
-        ),
-        xferCopy(blockPointField_),   // copy these points, do NOT move
-        tmpBlockShapes,
-        tmpBlocksPatches,
-        patchNames,
-        patchTypes,
-        defaultPatchName,
-        defaultPatchType,
-        patchPhysicalTypes
-    );
+            IOobject
+            (
+                "blockMesh",
+                meshDescription.time().constant(),
+                meshDescription.time(),
+                IOobject::NO_READ,
+                IOobject::NO_WRITE,
+                false
+            ),
+            xferCopy(blockPointField_),   // copy these points, do NOT move
+            tmpBlockCells,
+            tmpBlocksPatches,
+            patchDicts,
+            defaultPatchName,
+            defaultPatchType
+        );
+    }
 
     checkBlockMesh(*blockMeshPtr);
 
diff --git a/src/meshTools/PointEdgeWave/PointEdgeWave.C b/src/meshTools/PointEdgeWave/PointEdgeWave.C
index d88b5699f45df9fe8aee1fb547ed94036c73995d..7d42f0c75e65e500dac79e2d84fdca112a5390ba 100644
--- a/src/meshTools/PointEdgeWave/PointEdgeWave.C
+++ b/src/meshTools/PointEdgeWave/PointEdgeWave.C
@@ -56,49 +56,6 @@ void Foam::PointEdgeWave<Type>::offset(const label val, labelList& elems)
 // - list of halfA points (in cyclic patch points)
 // - list of halfB points (can overlap with A!)
 // - for every patchPoint its corresponding point
-template <class Type>
-void Foam::PointEdgeWave<Type>::calcCyclicAddressing()
-{
-    label cycHalf = 0;
-
-    forAll(mesh_.boundaryMesh(), patchI)
-    {
-        const polyPatch& patch = mesh_.boundaryMesh()[patchI];
-
-        if (isA<cyclicPolyPatch>(patch))
-        {
-            label halfSize = patch.size()/2;
-
-            SubList<face> halfAFaces
-            (
-                mesh_.faces(),
-                halfSize,
-                patch.start()
-            );
-
-            cycHalves_.set
-            (
-                cycHalf++,
-                new primitivePatch(halfAFaces, mesh_.points())
-            );
-
-            SubList<face> halfBFaces
-            (
-                mesh_.faces(),
-                halfSize,
-                patch.start() + halfSize
-            );
-
-            cycHalves_.set
-            (
-                cycHalf++,
-                new primitivePatch(halfBFaces, mesh_.points())
-            );
-        }
-    }
-}
-
-
 // Handle leaving domain. Implementation referred to Type
 template <class Type>
 void Foam::PointEdgeWave<Type>::leaveDomain
@@ -575,96 +532,57 @@ void Foam::PointEdgeWave<Type>::handleCyclicPatches()
     // 1. Send all point info on cyclic patches. Send as
     // face label + offset in face.
 
-    label cycHalf = 0;
-
     forAll(mesh_.boundaryMesh(), patchI)
     {
         const polyPatch& patch = mesh_.boundaryMesh()[patchI];
 
         if (isA<cyclicPolyPatch>(patch))
         {
-            const primitivePatch& halfA = cycHalves_[cycHalf++];
-            const primitivePatch& halfB = cycHalves_[cycHalf++];
-
-            // HalfA : get all changed points in relative addressing
-
-            DynamicList<Type> halfAInfo(halfA.nPoints());
-            DynamicList<label> halfAPoints(halfA.nPoints());
-            DynamicList<label> halfAOwner(halfA.nPoints());
-            DynamicList<label> halfAIndex(halfA.nPoints());
-
-            getChangedPatchPoints
-            (
-                halfA,
-                halfAInfo,
-                halfAPoints,
-                halfAOwner,
-                halfAIndex
-            );
+            const cyclicPolyPatch& cycPatch =
+                refCast<const cyclicPolyPatch>(patch);
 
-            // HalfB : get all changed points in relative addressing
+            const cyclicPolyPatch& nbrPatch = cycPatch.neighbPatch();
 
-            DynamicList<Type> halfBInfo(halfB.nPoints());
-            DynamicList<label> halfBPoints(halfB.nPoints());
-            DynamicList<label> halfBOwner(halfB.nPoints());
-            DynamicList<label> halfBIndex(halfB.nPoints());
+            DynamicList<Type> nbrInfo(nbrPatch.nPoints());
+            DynamicList<label> nbrPoints(nbrPatch.nPoints());
+            DynamicList<label> nbrOwner(nbrPatch.nPoints());
+            DynamicList<label> nbrIndex(nbrPatch.nPoints());
 
             getChangedPatchPoints
             (
-                halfB,
-                halfBInfo,
-                halfBPoints,
-                halfBOwner,
-                halfBIndex
+                nbrPatch,
+                nbrInfo,
+                nbrPoints,
+                nbrOwner,
+                nbrIndex
             );
 
-
-            // HalfA : adapt for leaving domain
-            leaveDomain(patch, halfA, halfAPoints, halfAInfo);
-
-            // HalfB : adapt for leaving domain
-            leaveDomain(patch, halfB, halfBPoints, halfBInfo);
-
+            // nbr : adapt for leaving domain
+            leaveDomain(nbrPatch, nbrPatch, nbrPoints, nbrInfo);
 
             // Apply rotation for non-parallel planes
-            const cyclicPolyPatch& cycPatch =
-                refCast<const cyclicPolyPatch>(patch);
 
             if (!cycPatch.parallel())
             {
                 // received data from half1
-                transform(cycPatch.forwardT(), halfAInfo);
-
-                // received data from half2
-                transform(cycPatch.reverseT(), halfBInfo);
+                transform(cycPatch.forwardT(), nbrInfo);
             }
 
             if (debug)
             {
                 Pout<< "Cyclic patch " << patchI << ' ' << patch.name()
-                    << "  Changed on first half : " << halfAInfo.size()
-                    << "  Changed on second half : " << halfBInfo.size()
+                    << "  Changed : " << nbrInfo.size()
                     << endl;
             }
 
             // Half1: update with data from halfB
             updateFromPatchInfo
             (
-                patch,
-                halfA,
-                halfBOwner,
-                halfBIndex,
-                halfBInfo
-            );
-
-            // Half2: update with data from halfA
-            updateFromPatchInfo
-            (
-                patch,
-                halfB,
-                halfAOwner,
-                halfAIndex,
-                halfAInfo
+                cycPatch,
+                cycPatch,
+                nbrOwner,
+                nbrIndex,
+                nbrInfo
             );
 
             if (debug)
@@ -703,7 +621,6 @@ Foam::PointEdgeWave<Type>::PointEdgeWave
     changedEdges_(mesh_.nEdges()),
     nChangedEdges_(0),
     nCyclicPatches_(countPatchType<cyclicPolyPatch>()),
-    cycHalves_(2*nCyclicPatches_),
     nEvals_(0),
     nUnvisitedPoints_(mesh_.nPoints()),
     nUnvisitedEdges_(mesh_.nEdges())
@@ -736,13 +653,6 @@ Foam::PointEdgeWave<Type>::PointEdgeWave
     }
 
 
-    // Calculate cyclic halves addressing.
-    if (nCyclicPatches_ > 0)
-    {
-        calcCyclicAddressing();
-    }
-
-
     // Set from initial changed points data
     setPointInfo(changedPoints, changedPointsInfo);
 
diff --git a/src/meshTools/PointEdgeWave/PointEdgeWave.H b/src/meshTools/PointEdgeWave/PointEdgeWave.H
index a40edb3b83cd7b8dc068ee121c59f3919c4ae2e5..2164ae1da13a94bb673c3de3e9c2377a14f34945 100644
--- a/src/meshTools/PointEdgeWave/PointEdgeWave.H
+++ b/src/meshTools/PointEdgeWave/PointEdgeWave.H
@@ -230,9 +230,6 @@ class PointEdgeWave
             //- Merge data from across processor boundaries
             void handleProcPatches();
 
-            //- Calculate cyclic halves addressing.
-            void calcCyclicAddressing();
-
             //- Merge data from across cyclic boundaries
             void handleCyclicPatches();
 
diff --git a/src/meshTools/regionSplit/regionSplit.C b/src/meshTools/regionSplit/regionSplit.C
index ae5edb82ad970b140f73c566003fdde5a11cbe00..d1645ae9ae773d37f096722eccc421d2ade58f57 100644
--- a/src/meshTools/regionSplit/regionSplit.C
+++ b/src/meshTools/regionSplit/regionSplit.C
@@ -209,16 +209,22 @@ void Foam::regionSplit::fillSeedMask
         {
             const polyPatch& pp = patches[patchI];
 
-            if (isA<cyclicPolyPatch>(pp))
+            if
+            (
+                isA<cyclicPolyPatch>(pp)
+             && refCast<const cyclicPolyPatch>(pp).owner()
+            )
             {
-                label faceI = pp.start();
+                // Transfer from neighbourPatch to here or vice versa.
+
+                const cyclicPolyPatch& cycPatch =
+                    refCast<const cyclicPolyPatch>(pp);
 
-                label halfSz = pp.size()/2;
+                label faceI = cycPatch.start();
 
-                for (label i = 0; i < halfSz; i++)
+                forAll(cycPatch, i)
                 {
-                    label otherFaceI = refCast<const cyclicPolyPatch>(pp)
-                        .transformGlobalFace(faceI);
+                    label otherFaceI = cycPatch.transformGlobalFace(faceI);
 
                     transferCoupledFaceRegion
                     (
@@ -268,7 +274,7 @@ Foam::label Foam::regionSplit::calcRegionSplit
         {
             // Check that blockedFace is synced.
             boolList syncBlockedFace(blockedFace);
-            syncTools::swapFaceList(mesh_, syncBlockedFace, false);
+            syncTools::swapFaceList(mesh_, syncBlockedFace);
 
             forAll(syncBlockedFace, faceI)
             {
diff --git a/src/meshTools/sets/cellSources/regionToCell/regionToCell.C b/src/meshTools/sets/cellSources/regionToCell/regionToCell.C
index d9be5d55cfd31218359d9632ee74fb18fb82dc1d..56ee4e493b4774a39d823b9810dee96292ddd0ec 100644
--- a/src/meshTools/sets/cellSources/regionToCell/regionToCell.C
+++ b/src/meshTools/sets/cellSources/regionToCell/regionToCell.C
@@ -97,7 +97,7 @@ void Foam::regionToCell::combine(topoSet& set, const bool add) const
         {
              neiSet[faceI-nInt] = inSubset[mesh_.faceOwner()[faceI]];
         }
-        syncTools::swapBoundaryFaceList(mesh_, neiSet, false);
+        syncTools::swapBoundaryFaceList(mesh_, neiSet);
 
         // Find faces inbetween subSet and non-subset.
         for (label faceI = 0; faceI < nInt; faceI++)
diff --git a/src/meshTools/sets/faceSources/cellToFace/cellToFace.C b/src/meshTools/sets/faceSources/cellToFace/cellToFace.C
index 431fad348ce007bc895624c1478e033faaad654a..9a0fcc78798e5c11a958ffd206cd0c79d87df646 100644
--- a/src/meshTools/sets/faceSources/cellToFace/cellToFace.C
+++ b/src/meshTools/sets/faceSources/cellToFace/cellToFace.C
@@ -127,7 +127,7 @@ void Foam::cellToFace::combine(topoSet& set, const bool add) const
                 }
             }
         }
-        syncTools::swapBoundaryFaceList(mesh_, neiInSet, false);
+        syncTools::swapBoundaryFaceList(mesh_, neiInSet);
 
 
         // Check all boundary faces
diff --git a/src/meshTools/sets/topoSets/cellZoneSet.C b/src/meshTools/sets/topoSets/cellZoneSet.C
index 9c506589b1ceb3794b556547dc5d25be474f8a8e..0a387c669ff885477df44ceeabc6385d3527abab 100644
--- a/src/meshTools/sets/topoSets/cellZoneSet.C
+++ b/src/meshTools/sets/topoSets/cellZoneSet.C
@@ -26,8 +26,6 @@ License
 #include "cellZoneSet.H"
 #include "mapPolyMesh.H"
 #include "polyMesh.H"
-#include "processorPolyPatch.H"
-#include "cyclicPolyPatch.H"
 
 #include "addToRunTimeSelectionTable.H"
 
diff --git a/src/meshTools/sets/topoSets/faceSet.C b/src/meshTools/sets/topoSets/faceSet.C
index 1dea0b0e9b02c0c5e35cd19f70ec4825dfee40bb..0569591704b9c4242a5fe794fc8bdddf746695d2 100644
--- a/src/meshTools/sets/topoSets/faceSet.C
+++ b/src/meshTools/sets/topoSets/faceSet.C
@@ -26,8 +26,7 @@ License
 #include "faceSet.H"
 #include "mapPolyMesh.H"
 #include "polyMesh.H"
-#include "processorPolyPatch.H"
-#include "cyclicPolyPatch.H"
+#include "syncTools.H"
 
 #include "addToRunTimeSelectionTable.H"
 
@@ -113,116 +112,40 @@ faceSet::~faceSet()
 
 void faceSet::sync(const polyMesh& mesh)
 {
-    const polyBoundaryMesh& patches = mesh.boundaryMesh();
+    boolList set(mesh.nFaces(), false);
+
+    forAllConstIter(faceSet, *this, iter)
+    {
+        set[iter.key()] = true;
+    }
+    syncTools::syncFaceList(mesh, set, orEqOp<bool>());
 
     label nAdded = 0;
 
-    if (Pstream::parRun())
+    forAll(set, faceI)
     {
-        // Send faces in set that are on a processorPatch. Send as patch face
-        // indices.
-        forAll(patches, patchI)
+        if (set[faceI])
         {
-            const polyPatch& pp = patches[patchI];
-
-            if (isA<processorPolyPatch>(pp))
+            if (insert(faceI))
             {
-                const processorPolyPatch& procPatch =
-                    refCast<const processorPolyPatch>(pp);
-
-                // Convert faceSet locally to labelList.
-                DynamicList<label> setFaces(pp.size());
-
-                forAll(pp, i)
-                {
-                    if (found(pp.start() + i))
-                    {
-                        setFaces.append(i);
-                    }
-                }
-                setFaces.shrink();
-
-                OPstream toNeighbour
-                (
-                    Pstream::blocking,
-                    procPatch.neighbProcNo()
-                );
-
-                toNeighbour << setFaces;
+                nAdded++;
             }
         }
-
-        // Receive
-        forAll(patches, patchI)
+        else if (found(faceI))
         {
-            const polyPatch& pp = patches[patchI];
-
-            if (isA<processorPolyPatch>(pp))
-            {
-                const processorPolyPatch& procPatch =
-                    refCast<const processorPolyPatch>(pp);
-
-                IPstream fromNeighbour
-                (
-                    Pstream::blocking,
-                    procPatch.neighbProcNo()
-                );
-
-                labelList setFaces(fromNeighbour);
-
-                forAll(setFaces, i)
-                {
-                    if (insert(pp.start() + setFaces[i]))
-                    {
-                        nAdded++;
-                    }
-                }
-            }
+            FatalErrorIn("faceSet::sync(const polyMesh&)")
+                << "Problem : syncing removed faces from set."
+                << abort(FatalError);
         }
     }
 
-    // Couple cyclic patches
-    forAll(patches, patchI)
+    reduce(nAdded, sumOp<label>());
+    if (nAdded > 0)
     {
-        const polyPatch& pp = patches[patchI];
-
-        if (isA<cyclicPolyPatch>(pp))
-        {
-            const cyclicPolyPatch& cycPatch =
-                refCast<const cyclicPolyPatch>(pp);
-
-            forAll(cycPatch, i)
-            {
-                label thisFaceI = cycPatch.start() + i;
-                label otherFaceI = cycPatch.transformGlobalFace(thisFaceI);
-
-                if (found(thisFaceI))
-                {
-                    if (insert(otherFaceI))
-                    {
-                        nAdded++;
-                    }
-                }
-                else if (found(otherFaceI))
-                {
-                    if (insert(thisFaceI))
-                    {
-                        nAdded++;
-                    }
-                }
-            }
-        }
+        Info<< "Added an additional " << nAdded
+            << " faces on coupled patches. "
+            << "(processorPolyPatch, cyclicPolyPatch)" << endl;
     }
-
-
-    reduce(nAdded, sumOp<label>());
-
-    //if (nAdded > 0)
-    //{
-    //    Info<< "Added an additional " << nAdded
-    //        << " faces on coupled patches. "
-    //        << "(processorPolyPatch, cyclicPolyPatch)" << endl;
-    //}
 }
 
 
diff --git a/src/meshTools/sets/topoSets/faceZoneSet.C b/src/meshTools/sets/topoSets/faceZoneSet.C
index fdee31918fc0257821b0807df6190f38356a2f51..ed552af24b20315f71b40823734e7b5ec8f7146a 100644
--- a/src/meshTools/sets/topoSets/faceZoneSet.C
+++ b/src/meshTools/sets/topoSets/faceZoneSet.C
@@ -26,8 +26,6 @@ License
 #include "faceZoneSet.H"
 #include "mapPolyMesh.H"
 #include "polyMesh.H"
-#include "processorPolyPatch.H"
-#include "cyclicPolyPatch.H"
 
 #include "addToRunTimeSelectionTable.H"
 
diff --git a/src/meshTools/sets/topoSets/pointSet.C b/src/meshTools/sets/topoSets/pointSet.C
index 4567847d49e317281a5523317590d68be87f192c..53e7c63591595516b5f72be6bcb1751096c9a26b 100644
--- a/src/meshTools/sets/topoSets/pointSet.C
+++ b/src/meshTools/sets/topoSets/pointSet.C
@@ -125,8 +125,7 @@ void pointSet::sync(const polyMesh& mesh)
         mesh,
         contents,
         orEqOp<bool>(),
-        false,          // null value
-        false           // no separation
+        false           // null value
     );
 
     // Convert back to labelHashSet
diff --git a/src/parallel/decompose/decompositionMethods/decompositionMethod/decompositionMethod.C b/src/parallel/decompose/decompositionMethods/decompositionMethod/decompositionMethod.C
index 2e240d6ea302c05f68c398bdaaa199662c4bff7e..4e026f9e487a7b46fc034f959fe8129ea22921ca 100644
--- a/src/parallel/decompose/decompositionMethods/decompositionMethod/decompositionMethod.C
+++ b/src/parallel/decompose/decompositionMethods/decompositionMethod/decompositionMethod.C
@@ -287,16 +287,25 @@ void Foam::decompositionMethod::calcCSR
 
     forAll(pbm, patchI)
     {
-        if (isA<cyclicPolyPatch>(pbm[patchI]))
+        if
+        (
+            isA<cyclicPolyPatch>(pbm[patchI])
+         && refCast<const cyclicPolyPatch>(pbm[patchI]).owner()
+        )
         {
-            const unallocLabelList& faceCells = pbm[patchI].faceCells();
+            const cyclicPolyPatch& cycPatch = refCast<const cyclicPolyPatch>
+            (
+                pbm[patchI]
+            );
 
-            label sizeby2 = faceCells.size()/2;
+            const unallocLabelList& faceCells = cycPatch.faceCells();
+            const unallocLabelList& nbrCells =
+                cycPatch.neighbPatch().faceCells();
 
-            for (label faceI=0; faceI<sizeby2; faceI++)
+            forAll(faceCells, facei)
             {
-                label own = faceCells[faceI];
-                label nei = faceCells[faceI + sizeby2];
+                label own = faceCells[facei];
+                label nei = nbrCells[facei];
 
                 if (cellPair.insert(edge(own, nei)))
                 {
@@ -348,16 +357,25 @@ void Foam::decompositionMethod::calcCSR
     cellPair.clear();
     forAll(pbm, patchI)
     {
-        if (isA<cyclicPolyPatch>(pbm[patchI]))
+        if
+        (
+            isA<cyclicPolyPatch>(pbm[patchI])
+         && refCast<const cyclicPolyPatch>(pbm[patchI]).owner()
+        )
         {
-            const unallocLabelList& faceCells = pbm[patchI].faceCells();
+            const cyclicPolyPatch& cycPatch = refCast<const cyclicPolyPatch>
+            (
+                pbm[patchI]
+            );
 
-            label sizeby2 = faceCells.size()/2;
+            const unallocLabelList& faceCells = cycPatch.faceCells();
+            const unallocLabelList& nbrCells =
+                cycPatch.neighbPatch().faceCells();
 
-            for (label faceI=0; faceI<sizeby2; faceI++)
+            forAll(faceCells, facei)
             {
-                label own = faceCells[faceI];
-                label nei = faceCells[faceI + sizeby2];
+                label own = faceCells[facei];
+                label nei = nbrCells[facei];
 
                 if (cellPair.insert(edge(own, nei)))
                 {
@@ -479,7 +497,7 @@ void Foam::decompositionMethod::calcDistributedCSR
     }
 
     // Get the cell on the other side of coupled patches
-    syncTools::swapBoundaryFaceList(mesh, globalNeighbour, false);
+    syncTools::swapBoundaryFaceList(mesh, globalNeighbour);
 
 
     // Count number of faces (internal + coupled)
diff --git a/src/postProcessing/functionObjects/field/fieldValues/faceSource/faceSource.C b/src/postProcessing/functionObjects/field/fieldValues/faceSource/faceSource.C
index 517e5803b74c637eba7d25f895346ead24c46b98..bc0639b28bbae66b0877a38871dc598de9e5d31e 100644
--- a/src/postProcessing/functionObjects/field/fieldValues/faceSource/faceSource.C
+++ b/src/postProcessing/functionObjects/field/fieldValues/faceSource/faceSource.C
@@ -27,7 +27,7 @@ License
 #include "fvMesh.H"
 #include "cyclicPolyPatch.H"
 #include "emptyPolyPatch.H"
-#include "processorPolyPatch.H"
+#include "coupledPolyPatch.H"
 #include "surfaceFields.H"
 #include "volFields.H"
 
@@ -96,9 +96,9 @@ void Foam::fieldValues::faceSource::setFaceZoneFaces()
         {
             facePatchId = mesh().boundaryMesh().whichPatch(faceI);
             const polyPatch& pp = mesh().boundaryMesh()[facePatchId];
-            if (isA<processorPolyPatch>(pp))
+            if (isA<coupledPolyPatch>(pp))
             {
-                if (refCast<const processorPolyPatch>(pp).owner())
+                if (refCast<const coupledPolyPatch>(pp).owner())
                 {
                     faceId = pp.whichFace(faceI);
                 }
@@ -107,18 +107,6 @@ void Foam::fieldValues::faceSource::setFaceZoneFaces()
                     faceId = -1;
                 }
             }
-            else if (isA<cyclicPolyPatch>(pp))
-            {
-                label patchFaceI = faceI - pp.start();
-                if (patchFaceI < pp.size()/2)
-                {
-                    faceId = patchFaceI;
-                }
-                else
-                {
-                    faceId = -1;
-                }
-            }
             else if (!isA<emptyPolyPatch>(pp))
             {
                 faceId = faceI - pp.start();
diff --git a/src/sampling/sampledSurface/isoSurface/isoSurface.C b/src/sampling/sampledSurface/isoSurface/isoSurface.C
index 405065906fa2a066f8901b715139dc6dea90a738..82a8c80185af319dd30cf72dd9cd7e4b84727104 100644
--- a/src/sampling/sampledSurface/isoSurface/isoSurface.C
+++ b/src/sampling/sampledSurface/isoSurface/isoSurface.C
@@ -26,7 +26,6 @@ License
 #include "isoSurface.H"
 #include "fvMesh.H"
 #include "mergePoints.H"
-#include "syncTools.H"
 #include "addToRunTimeSelectionTable.H"
 #include "slicedVolFields.H"
 #include "volFields.H"
@@ -56,10 +55,10 @@ bool Foam::isoSurface::noTransform(const tensor& tt) const
 }
 
 
+// Calculates per face whether couple is collocated.
 bool Foam::isoSurface::collocatedPatch(const polyPatch& pp)
 {
     const coupledPolyPatch& cpp = refCast<const coupledPolyPatch>(pp);
-
     return cpp.parallel() && !cpp.separated();
 }
 
@@ -73,78 +72,29 @@ Foam::PackedBoolList Foam::isoSurface::collocatedFaces
     // Initialise to false
     PackedBoolList collocated(pp.size());
 
-    const vectorField& separation = pp.separation();
-    const tensorField& forwardT = pp.forwardT();
-
-    if (forwardT.size() == 0)
+    if (isA<processorPolyPatch>(pp) && collocatedPatch(pp))
     {
-        // Parallel.
-        if (separation.size() == 0)
-        {
-            collocated = 1u;
-        }
-        else if (separation.size() == 1)
-        {
-            // Fully separate. Do not synchronise.
-        }
-        else
+        forAll(pp, i)
         {
-            // Per face separation.
-            forAll(pp, faceI)
-            {
-                if (mag(separation[faceI]) < mergeDistance_)
-                {
-                    collocated[faceI] = 1u;
-                }
-            }
+            collocated[i] = 1u;
         }
     }
-    else if (forwardT.size() == 1)
-    {
-        // Fully transformed.
-    }
-    else
+    else if (isA<cyclicPolyPatch>(pp) && collocatedPatch(pp))
     {
-        // Per face transformation.
-        forAll(pp, faceI)
+        forAll(pp, i)
         {
-            if (noTransform(forwardT[faceI]))
-            {
-                collocated[faceI] = 1u;
-            }
+            collocated[i] = 1u;
         }
     }
-    return collocated;
-}
-
-
-// Insert the data for local point patchPointI into patch local values
-// and/or into the shared values field.
-void Foam::isoSurface::insertPointData
-(
-    const processorPolyPatch& pp,
-    const Map<label>& meshToShared,
-    const pointField& pointValues,
-    const label patchPointI,
-    pointField& patchValues,
-    pointField& sharedValues
-) const
-{
-    label meshPointI = pp.meshPoints()[patchPointI];
-
-    // Store in local field
-    label nbrPointI = pp.neighbPoints()[patchPointI];
-    if (nbrPointI >= 0 && nbrPointI < patchValues.size())
-    {
-        minEqOp<point>()(patchValues[nbrPointI], pointValues[meshPointI]);
-    }
-
-    // Store in shared field
-    Map<label>::const_iterator iter = meshToShared.find(meshPointI);
-    if (iter != meshToShared.end())
+    else
     {
-        minEqOp<point>()(sharedValues[iter()], pointValues[meshPointI]);
+        FatalErrorIn
+        (
+            "isoSurface::collocatedFaces(const coupledPolyPatch&) const"
+        )   << "Unhandled coupledPolyPatch type " << pp.type()
+            << abort(FatalError);
     }
+    return collocated;
 }
 
 
@@ -157,20 +107,6 @@ void Foam::isoSurface::syncUnseparatedPoints
     // Until syncPointList handles separated coupled patches with multiple
     // transforms do our own synchronisation of non-separated patches only
     const polyBoundaryMesh& patches = mesh_.boundaryMesh();
-    const globalMeshData& pd = mesh_.globalData();
-    const labelList& sharedPtAddr = pd.sharedPointAddr();
-    const labelList& sharedPtLabels = pd.sharedPointLabels();
-
-    // Create map from meshPoint to globalShared index.
-    Map<label> meshToShared(2*sharedPtLabels.size());
-    forAll(sharedPtLabels, i)
-    {
-        meshToShared.insert(sharedPtLabels[i], sharedPtAddr[i]);
-    }
-
-    // Values on shared points.
-    pointField sharedInfo(pd.nGlobalPoints(), nullValue);
-
 
     if (Pstream::parRun())
     {
@@ -181,37 +117,21 @@ void Foam::isoSurface::syncUnseparatedPoints
             (
                 isA<processorPolyPatch>(patches[patchI])
              && patches[patchI].nPoints() > 0
+             && collocatedPatch(patches[patchI])
             )
             {
                 const processorPolyPatch& pp =
                     refCast<const processorPolyPatch>(patches[patchI]);
-                const labelList& meshPts = pp.meshPoints();
 
-                pointField patchInfo(meshPts.size(), nullValue);
+                const labelList& meshPts = pp.meshPoints();
+                const labelList& nbrPts = pp.neighbPoints();
 
-                PackedBoolList isCollocated(collocatedFaces(pp));
+                pointField patchInfo(meshPts.size());
 
-                forAll(isCollocated, faceI)
+                forAll(nbrPts, pointI)
                 {
-                    if (isCollocated[faceI])
-                    {
-                        const face& f = pp.localFaces()[faceI];
-
-                        forAll(f, fp)
-                        {
-                            label pointI = f[fp];
-
-                            insertPointData
-                            (
-                                pp,
-                                meshToShared,
-                                pointValues,
-                                pointI,
-                                patchInfo,
-                                sharedInfo
-                            );
-                        }
-                    }
+                    label nbrPointI = nbrPts[pointI];
+                    patchInfo[nbrPointI] = pointValues[meshPts[pointI]];
                 }
 
                 OPstream toNbr(Pstream::blocking, pp.neighbProcNo());
@@ -227,6 +147,7 @@ void Foam::isoSurface::syncUnseparatedPoints
             (
                 isA<processorPolyPatch>(patches[patchI])
              && patches[patchI].nPoints() > 0
+             && collocatedPatch(patches[patchI])
             )
             {
                 const processorPolyPatch& pp =
@@ -240,9 +161,6 @@ void Foam::isoSurface::syncUnseparatedPoints
                     fromNbr >> nbrPatchInfo;
                 }
 
-                // Null any value which is not on neighbouring processor
-                nbrPatchInfo.setSize(pp.nPoints(), nullValue);
-
                 const labelList& meshPts = pp.meshPoints();
 
                 forAll(meshPts, pointI)
@@ -258,22 +176,72 @@ void Foam::isoSurface::syncUnseparatedPoints
         }
     }
 
+    // Do the cyclics.
+    forAll(patches, patchI)
+    {
+        if (isA<cyclicPolyPatch>(patches[patchI]))
+        {
+            const cyclicPolyPatch& cycPatch =
+                refCast<const cyclicPolyPatch>(patches[patchI]);
+
+            if (cycPatch.owner() && collocatedPatch(cycPatch))
+            {
+                // Owner does all.
 
-    // Don't do cyclics for now. Are almost always separated anyway.
+                const edgeList& coupledPoints = cycPatch.coupledPoints();
+                const labelList& meshPts = cycPatch.meshPoints();
+                const cyclicPolyPatch& nbrPatch = cycPatch.neighbPatch();
+                const labelList& nbrMeshPoints = nbrPatch.meshPoints();
 
+                pointField half0Values(coupledPoints.size());
+                pointField half1Values(coupledPoints.size());
 
-    // Shared points
+                forAll(coupledPoints, i)
+                {
+                    const edge& e = coupledPoints[i];
+                    half0Values[i] = pointValues[meshPts[e[0]]];
+                    half1Values[i] = pointValues[nbrMeshPoints[e[1]]];
+                }
 
-    // Combine on master.
-    Pstream::listCombineGather(sharedInfo, minEqOp<point>());
-    Pstream::listCombineScatter(sharedInfo);
+                forAll(coupledPoints, i)
+                {
+                    const edge& e = coupledPoints[i];
+                    label p0 = meshPts[e[0]];
+                    label p1 = nbrMeshPoints[e[1]];
 
-    // Now we will all have the same information. Merge it back with
-    // my local information. (Note assignment and not combine operator)
-    forAll(sharedPtLabels, i)
+                    minEqOp<point>()(pointValues[p0], half1Values[i]);
+                    minEqOp<point>()(pointValues[p1], half0Values[i]);
+                }
+            }
+        }
+    }
+
+    // Synchronize multiple shared points.
+    const globalMeshData& pd = mesh_.globalData();
+
+    if (pd.nGlobalPoints() > 0)
     {
-        label meshPointI = sharedPtLabels[i];
-        pointValues[meshPointI] = sharedInfo[sharedPtAddr[i]];
+        // Values on shared points.
+        pointField sharedPts(pd.nGlobalPoints(), nullValue);
+
+        forAll(pd.sharedPointLabels(), i)
+        {
+            label meshPointI = pd.sharedPointLabels()[i];
+            // Fill my entries in the shared points
+            sharedPts[pd.sharedPointAddr()[i]] = pointValues[meshPointI];
+        }
+
+        // Combine on master.
+        Pstream::listCombineGather(sharedPts, minEqOp<point>());
+        Pstream::listCombineScatter(sharedPts);
+
+        // Now we will all have the same information. Merge it back with
+        // my local information.
+        forAll(pd.sharedPointLabels(), i)
+        {
+            label meshPointI = pd.sharedPointLabels()[i];
+            pointValues[meshPointI] = sharedPts[pd.sharedPointAddr()[i]];
+        }
     }
 }
 
@@ -1801,7 +1769,7 @@ Foam::isoSurface::isoSurface
         const polyPatch& pp = patches[patchI];
 
         // Adapt separated coupled (proc and cyclic) patches
-        if (isA<coupledPolyPatch>(pp) && !collocatedPatch(pp))
+        if (isA<coupledPolyPatch>(pp))
         {
             fvPatchVectorField& pfld = const_cast<fvPatchVectorField&>
             (
@@ -1918,26 +1886,23 @@ Foam::isoSurface::isoSurface
 
             if (patches[patchI].coupled())
             {
-                if (!collocatedPatch(patches[patchI]))
-                {
-                    const coupledPolyPatch& cpp =
-                        refCast<const coupledPolyPatch>
-                        (
-                            patches[patchI]
-                        );
+                const coupledPolyPatch& cpp =
+                    refCast<const coupledPolyPatch>
+                    (
+                        patches[patchI]
+                    );
 
-                    PackedBoolList isCollocated(collocatedFaces(cpp));
+                PackedBoolList isCollocated(collocatedFaces(cpp));
 
-                    forAll(isCollocated, i)
+                forAll(isCollocated, i)
+                {
+                    if (!isCollocated[i])
                     {
-                        if (!isCollocated[i])
-                        {
-                            const face& f = mesh_.faces()[cpp.start()+i];
+                        const face& f = mesh_.faces()[cpp.start()+i];
 
-                            forAll(f, fp)
-                            {
-                                isBoundaryPoint.set(f[fp], 1);
-                            }
+                        forAll(f, fp)
+                        {
+                            isBoundaryPoint.set(f[fp], 1);
                         }
                     }
                 }
diff --git a/src/sampling/sampledSurface/isoSurface/isoSurface.H b/src/sampling/sampledSurface/isoSurface/isoSurface.H
index c4762bd97a23d1d571f500d6ad4cef06ccce3ff3..85cdc148b00c5048c362503293a2f2710b7b6425 100644
--- a/src/sampling/sampledSurface/isoSurface/isoSurface.H
+++ b/src/sampling/sampledSurface/isoSurface/isoSurface.H
@@ -149,19 +149,6 @@ class isoSurface
             //- Per face whether is collocated
             PackedBoolList collocatedFaces(const coupledPolyPatch&) const;
 
-            //- Take value at local point patchPointI and assign it to its
-            //  correct place in patchValues (for transferral) and sharedValues
-            //  (for reduction)
-            void insertPointData
-            (
-                const processorPolyPatch& pp,
-                const Map<label>& meshToShared,
-                const pointField& pointValues,
-                const label patchPointI,
-                pointField& patchValues,
-                pointField& sharedValues
-            ) const;
-
             //- Synchonise points on all non-separated coupled patches
             void syncUnseparatedPoints
             (
diff --git a/src/sampling/sampledSurface/isoSurface/isoSurfaceCell.C b/src/sampling/sampledSurface/isoSurface/isoSurfaceCell.C
index 822c668f8fed0ff6ea9099b971568334ec051fa7..72837ffd699256886fa17a1716e0188b64d2cb3e 100644
--- a/src/sampling/sampledSurface/isoSurface/isoSurfaceCell.C
+++ b/src/sampling/sampledSurface/isoSurface/isoSurfaceCell.C
@@ -755,13 +755,12 @@ void Foam::isoSurfaceCell::calcSnappedPoint
         }
     }
 
-    syncTools::syncPointList
+    syncTools::syncPointPositions
     (
         mesh_,
         collapsedPoint,
         minEqOp<point>(),
-        point::max,
-        true                // are coordinates so separate
+        point::max
     );
 
     snappedPoint.setSize(mesh_.nPoints());
diff --git a/src/sampling/sampledSurface/isoSurface/isoSurfaceTemplates.C b/src/sampling/sampledSurface/isoSurface/isoSurfaceTemplates.C
index 4ad827a1f32cf9afa124f70aa2462fa2b9b7a09b..72467ed2398c99d06ab248efd1c78656ced3515e 100644
--- a/src/sampling/sampledSurface/isoSurface/isoSurfaceTemplates.C
+++ b/src/sampling/sampledSurface/isoSurface/isoSurfaceTemplates.C
@@ -116,7 +116,7 @@ Foam::isoSurface::adaptPatchFields
         {
             // Already has interpolate as value
         }
-        else if (isA<processorPolyPatch>(pp) && !collocatedPatch(pp))
+        else if (isA<processorPolyPatch>(pp))
         {
             fvPatchField<Type>& pfld = const_cast<fvPatchField<Type>&>
             (
@@ -568,8 +568,8 @@ void Foam::isoSurface::generateTriPoints
             }
         }
     }
-    syncTools::swapBoundaryFaceList(mesh_, neiSnapped, false);
-    syncTools::swapBoundaryFaceList(mesh_, neiSnappedPoint, false);
+    syncTools::swapBoundaryFaceList(mesh_, neiSnapped);
+    syncTools::swapBoundaryFaceList(mesh_, neiSnappedPoint);
 
 
 
diff --git a/tutorials/DNS/dnsFoam/boxTurb16/0.org/U b/tutorials/DNS/dnsFoam/boxTurb16/0.org/U
index 77cc396c203778a173d6d308fd4298735f4b9909..9b2701a3ae515953c50901eb7e6c878fc2d1dbe2 100644
--- a/tutorials/DNS/dnsFoam/boxTurb16/0.org/U
+++ b/tutorials/DNS/dnsFoam/boxTurb16/0.org/U
@@ -1,8 +1,8 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  1.6                                   |
-|   \\  /    A nd           | Web:      http://www.OpenFOAM.org               |
+|  \\    /   O peration     | Version:  splitCyclic                           |
+|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
 FoamFile
@@ -10,28 +10,42 @@ FoamFile
     version     2.0;
     format      ascii;
     class       volVectorField;
+    location    "1";
     object      U;
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-dimensions      [0 1 -1 0 0 0 0];
+dimensions      [ 0 1 -1 0 0 0 0 ];
 
-internalField   uniform (0 0 0);
+internalField   uniform ( 0 0 0 );
 
 boundaryField
 {
-    patch0
+    patch0_half0
     {
         type            cyclic;
     }
-    patch1
+    patch1_half0
     {
         type            cyclic;
     }
-    patch2
+    patch2_half0
+    {
+        type            cyclic;
+    }
+    patch2_half1
+    {
+        type            cyclic;
+    }
+    patch1_half1
+    {
+        type            cyclic;
+    }
+    patch0_half1
     {
         type            cyclic;
     }
 }
 
+
 // ************************************************************************* //
diff --git a/tutorials/DNS/dnsFoam/boxTurb16/0.org/enstrophy b/tutorials/DNS/dnsFoam/boxTurb16/0.org/enstrophy
index 4f1197074dec8e2dcadeef982090db7e2e79213b..254013e6c9f63ad74a4d1e7595ee11d4fc6b6f8e 100644
--- a/tutorials/DNS/dnsFoam/boxTurb16/0.org/enstrophy
+++ b/tutorials/DNS/dnsFoam/boxTurb16/0.org/enstrophy
@@ -1,8 +1,8 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  1.6                                   |
-|   \\  /    A nd           | Web:      http://www.OpenFOAM.org               |
+|  \\    /   O peration     | Version:  splitCyclic                           |
+|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
 FoamFile
@@ -10,31 +10,48 @@ FoamFile
     version     2.0;
     format      ascii;
     class       volScalarField;
+    location    "1";
     object      enstrophy;
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-dimensions      [0 0 -2 0 0 0 0];
+dimensions      [ 0 0 -2 0 0 0 0 ];
 
 internalField   uniform 0;
 
 boundaryField
 {
-    patch0
+    patch0_half0
     {
         type            cyclic;
         value           uniform 0;
     }
-    patch1
+    patch1_half0
     {
         type            cyclic;
         value           uniform 0;
     }
-    patch2
+    patch2_half0
+    {
+        type            cyclic;
+        value           uniform 0;
+    }
+    patch2_half1
+    {
+        type            cyclic;
+        value           uniform 0;
+    }
+    patch1_half1
+    {
+        type            cyclic;
+        value           uniform 0;
+    }
+    patch0_half1
     {
         type            cyclic;
         value           uniform 0;
     }
 }
 
+
 // ************************************************************************* //
diff --git a/tutorials/DNS/dnsFoam/boxTurb16/0.org/p b/tutorials/DNS/dnsFoam/boxTurb16/0.org/p
index 0874357a9b126d03c9c4d599414bb41779729e77..0738f6a86781b8089f5a029ad3195c72c2ca319a 100644
--- a/tutorials/DNS/dnsFoam/boxTurb16/0.org/p
+++ b/tutorials/DNS/dnsFoam/boxTurb16/0.org/p
@@ -1,8 +1,8 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  1.6                                   |
-|   \\  /    A nd           | Web:      http://www.OpenFOAM.org               |
+|  \\    /   O peration     | Version:  splitCyclic                           |
+|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
 FoamFile
@@ -10,30 +10,42 @@ FoamFile
     version     2.0;
     format      ascii;
     class       volScalarField;
+    location    "1";
     object      p;
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-dimensions      [0 2 -2 0 0 0 0];
+dimensions      [ 0 2 -2 0 0 0 0 ];
 
 internalField   uniform 0;
 
 boundaryField
 {
-    patch0          
+    patch0_half0
     {
         type            cyclic;
     }
-
-    patch1          
+    patch1_half0
     {
         type            cyclic;
     }
-
-    patch2          
+    patch2_half0
+    {
+        type            cyclic;
+    }
+    patch2_half1
+    {
+        type            cyclic;
+    }
+    patch1_half1
+    {
+        type            cyclic;
+    }
+    patch0_half1
     {
         type            cyclic;
     }
 }
 
+
 // ************************************************************************* //
diff --git a/tutorials/DNS/dnsFoam/boxTurb16/0/U b/tutorials/DNS/dnsFoam/boxTurb16/0/U
index 77cc396c203778a173d6d308fd4298735f4b9909..9b2701a3ae515953c50901eb7e6c878fc2d1dbe2 100644
--- a/tutorials/DNS/dnsFoam/boxTurb16/0/U
+++ b/tutorials/DNS/dnsFoam/boxTurb16/0/U
@@ -1,8 +1,8 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  1.6                                   |
-|   \\  /    A nd           | Web:      http://www.OpenFOAM.org               |
+|  \\    /   O peration     | Version:  splitCyclic                           |
+|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
 FoamFile
@@ -10,28 +10,42 @@ FoamFile
     version     2.0;
     format      ascii;
     class       volVectorField;
+    location    "1";
     object      U;
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-dimensions      [0 1 -1 0 0 0 0];
+dimensions      [ 0 1 -1 0 0 0 0 ];
 
-internalField   uniform (0 0 0);
+internalField   uniform ( 0 0 0 );
 
 boundaryField
 {
-    patch0
+    patch0_half0
     {
         type            cyclic;
     }
-    patch1
+    patch1_half0
     {
         type            cyclic;
     }
-    patch2
+    patch2_half0
+    {
+        type            cyclic;
+    }
+    patch2_half1
+    {
+        type            cyclic;
+    }
+    patch1_half1
+    {
+        type            cyclic;
+    }
+    patch0_half1
     {
         type            cyclic;
     }
 }
 
+
 // ************************************************************************* //
diff --git a/tutorials/DNS/dnsFoam/boxTurb16/0/enstrophy b/tutorials/DNS/dnsFoam/boxTurb16/0/enstrophy
index 4f1197074dec8e2dcadeef982090db7e2e79213b..254013e6c9f63ad74a4d1e7595ee11d4fc6b6f8e 100644
--- a/tutorials/DNS/dnsFoam/boxTurb16/0/enstrophy
+++ b/tutorials/DNS/dnsFoam/boxTurb16/0/enstrophy
@@ -1,8 +1,8 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  1.6                                   |
-|   \\  /    A nd           | Web:      http://www.OpenFOAM.org               |
+|  \\    /   O peration     | Version:  splitCyclic                           |
+|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
 FoamFile
@@ -10,31 +10,48 @@ FoamFile
     version     2.0;
     format      ascii;
     class       volScalarField;
+    location    "1";
     object      enstrophy;
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-dimensions      [0 0 -2 0 0 0 0];
+dimensions      [ 0 0 -2 0 0 0 0 ];
 
 internalField   uniform 0;
 
 boundaryField
 {
-    patch0
+    patch0_half0
     {
         type            cyclic;
         value           uniform 0;
     }
-    patch1
+    patch1_half0
     {
         type            cyclic;
         value           uniform 0;
     }
-    patch2
+    patch2_half0
+    {
+        type            cyclic;
+        value           uniform 0;
+    }
+    patch2_half1
+    {
+        type            cyclic;
+        value           uniform 0;
+    }
+    patch1_half1
+    {
+        type            cyclic;
+        value           uniform 0;
+    }
+    patch0_half1
     {
         type            cyclic;
         value           uniform 0;
     }
 }
 
+
 // ************************************************************************* //
diff --git a/tutorials/DNS/dnsFoam/boxTurb16/0/p b/tutorials/DNS/dnsFoam/boxTurb16/0/p
index 0874357a9b126d03c9c4d599414bb41779729e77..0738f6a86781b8089f5a029ad3195c72c2ca319a 100644
--- a/tutorials/DNS/dnsFoam/boxTurb16/0/p
+++ b/tutorials/DNS/dnsFoam/boxTurb16/0/p
@@ -1,8 +1,8 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  1.6                                   |
-|   \\  /    A nd           | Web:      http://www.OpenFOAM.org               |
+|  \\    /   O peration     | Version:  splitCyclic                           |
+|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
 FoamFile
@@ -10,30 +10,42 @@ FoamFile
     version     2.0;
     format      ascii;
     class       volScalarField;
+    location    "1";
     object      p;
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-dimensions      [0 2 -2 0 0 0 0];
+dimensions      [ 0 2 -2 0 0 0 0 ];
 
 internalField   uniform 0;
 
 boundaryField
 {
-    patch0          
+    patch0_half0
     {
         type            cyclic;
     }
-
-    patch1          
+    patch1_half0
     {
         type            cyclic;
     }
-
-    patch2          
+    patch2_half0
+    {
+        type            cyclic;
+    }
+    patch2_half1
+    {
+        type            cyclic;
+    }
+    patch1_half1
+    {
+        type            cyclic;
+    }
+    patch0_half1
     {
         type            cyclic;
     }
 }
 
+
 // ************************************************************************* //
diff --git a/tutorials/DNS/dnsFoam/boxTurb16/constant/polyMesh/boundary b/tutorials/DNS/dnsFoam/boxTurb16/constant/polyMesh/boundary
index bbae8091918170ac889ea09258b8ee430c65b892..1999f682b1cef32176181b155c87805e3809153f 100644
--- a/tutorials/DNS/dnsFoam/boxTurb16/constant/polyMesh/boundary
+++ b/tutorials/DNS/dnsFoam/boxTurb16/constant/polyMesh/boundary
@@ -1,7 +1,7 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  1.6                                   |
+|  \\    /   O peration     | Version:  splitCyclic                           |
 |   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
@@ -15,28 +15,49 @@ FoamFile
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-3
+6
 (
-    patch0
+    patch0_half0
     {
         type            cyclic;
-        nFaces          512;
+        nFaces          256;
         startFace       11520;
-        featureCos      0.9;
+        neighbourPatch  patch0_half1;
     }
-    patch1
+    patch0_half1
     {
         type            cyclic;
-        nFaces          512;
+        nFaces          256;
+        startFace       11776;
+        neighbourPatch  patch0_half0;
+    }
+    patch1_half0
+    {
+        type            cyclic;
+        nFaces          256;
         startFace       12032;
-        featureCos      0.9;
+        neighbourPatch  patch1_half1;
     }
-    patch2
+    patch1_half1
     {
         type            cyclic;
-        nFaces          512;
+        nFaces          256;
+        startFace       12288;
+        neighbourPatch  patch1_half0;
+    }
+    patch2_half0
+    {
+        type            cyclic;
+        nFaces          256;
         startFace       12544;
-        featureCos      0.9;
+        neighbourPatch  patch2_half1;
+    }
+    patch2_half1
+    {
+        type            cyclic;
+        nFaces          256;
+        startFace       12800;
+        neighbourPatch  patch2_half0;
     }
 )
 
diff --git a/tutorials/channelOodles/channel395/constant/polyMesh/blockMeshDict b/tutorials/channelOodles/channel395/constant/polyMesh/blockMeshDict
new file mode 100644
index 0000000000000000000000000000000000000000..2adabb4f217630938807a89e65ff8bf132a508d3
--- /dev/null
+++ b/tutorials/channelOodles/channel395/constant/polyMesh/blockMeshDict
@@ -0,0 +1,177 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  1.5                                   |
+|   \\  /    A nd           | Web:      http://www.OpenFOAM.org               |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       dictionary;
+    object      blockMeshDict;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+convertToMeters 1;
+
+vertices        
+(
+    (0 0 0)
+    (4 0 0)
+    (0 1 0)
+    (4 1 0)
+    (0 2 0)
+    (4 2 0)
+    (0 0 2)
+    (4 0 2)
+    (0 1 2)
+    (4 1 2)
+    (0 2 2)
+    (4 2 2)
+);
+
+blocks          
+(
+    hex (0 1 3 2 6 7 9 8) (40 25 30) simpleGrading (1 10.7028 1)
+    hex (2 3 5 4 8 9 11 10) (40 25 30) simpleGrading (1 0.0984 1)
+);
+
+edges           
+(
+);
+
+//patches         
+//(
+//    wall bottomWall 
+//    (
+//        (0 1 7 6)
+//    )
+//    wall topWall 
+//    (
+//        (4 10 11 5)
+//    )
+//    cyclic sides1 
+//    (
+//        (0 2 3 1)
+//        (6 7 9 8)
+//    )
+//    cyclic sides2 
+//    (
+//        (2 4 5 3)
+//        (8 9 11 10)
+//    )
+//    cyclic inout1 
+//    (
+//        (1 3 9 7)
+//        (0 6 8 2)
+//    )
+//    cyclic inout2 
+//    (
+//        (3 5 11 9)
+//        (2 8 10 4)
+//    )
+//);
+
+boundary         
+(
+    bottomWall
+    {
+        type wall;
+        faces
+        (
+            (0 1 7 6)
+        );
+    }
+    topWall 
+    {
+        type wall;
+        faces
+        (
+            (4 10 11 5)
+        );
+    }
+
+    sides1_half0
+    {
+        type cyclic;
+        neighbourPatch sides1_half1;
+        faces
+        (
+            (0 2 3 1)
+        );
+    }
+    sides1_half1
+    {
+        type cyclic;
+        neighbourPatch sides1_half0;
+        faces
+        (
+            (6 7 9 8)
+        );
+    }
+
+    sides2_half0
+    {
+        type cyclic;
+        neighbourPatch sides2_half1;
+        faces
+        (
+            (2 4 5 3)
+        );
+    }
+    sides2_half1
+    {
+        type cyclic;
+        neighbourPatch sides2_half0;
+        faces
+        (
+            (8 9 11 10)
+        );
+    }
+
+    inout1_half0
+    {
+        type cyclic;
+        neighbourPatch inout1_half1;
+        faces
+        (
+            (1 3 9 7)
+        );
+    }
+    inout1_half1
+    {
+        type cyclic;
+        neighbourPatch inout1_half0;
+        faces
+        (
+            (0 6 8 2)
+        );
+    }
+
+    inout2_half0
+    {
+        type cyclic;
+        neighbourPatch inout2_half1;
+        faces
+        (
+            (3 5 11 9)
+        );
+    }
+    inout2_half1
+    {
+        type cyclic;
+        neighbourPatch inout2_half0;
+        faces
+        (
+            (2 8 10 4)
+        );
+    }
+);
+
+mergePatchPairs
+(
+);
+
+// ************************************************************************* //
diff --git a/tutorials/combustion/XiFoam/les/pitzDaily3D/0/Su b/tutorials/combustion/XiFoam/les/pitzDaily3D/0/Su
index c04ce1d7e0326823040d81056bc2a2f7120e9b73..d3cc26e7d8edcece3ed0f559929d3a42b65dd790 100644
--- a/tutorials/combustion/XiFoam/les/pitzDaily3D/0/Su
+++ b/tutorials/combustion/XiFoam/les/pitzDaily3D/0/Su
@@ -1,8 +1,8 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  1.6                                   |
-|   \\  /    A nd           | Web:      http://www.OpenFOAM.org               |
+|  \\    /   O peration     | Version:  splitCyclic                           |
+|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
 FoamFile
@@ -10,11 +10,12 @@ FoamFile
     version     2.0;
     format      ascii;
     class       volScalarField;
+    location    "0";
     object      Su;
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-dimensions      [0 1 -1 0 0 0 0];
+dimensions      [ 0 1 -1 0 0 0 0 ];
 
 internalField   uniform 0.135;
 
@@ -25,28 +26,29 @@ boundaryField
         type            fixedValue;
         value           uniform 0.135;
     }
-
     outlet
     {
         type            inletOutlet;
         inletValue      uniform 0.135;
         value           uniform 0.135;
     }
-
     upperWall
     {
         type            zeroGradient;
     }
-
     lowerWall
     {
         type            zeroGradient;
     }
-
-    frontAndBack
+    frontAndBack_half0
+    {
+        type            cyclic;
+    }
+    frontAndBack_half1
     {
         type            cyclic;
     }
 }
 
+
 // ************************************************************************* //
diff --git a/tutorials/combustion/XiFoam/les/pitzDaily3D/0/T b/tutorials/combustion/XiFoam/les/pitzDaily3D/0/T
index bb7a3a2d796665b96fe89f1056b8f2016d1e095b..f8c2f8ec0c30c2a93e9ee7e325f4bb1a6a34fc50 100644
--- a/tutorials/combustion/XiFoam/les/pitzDaily3D/0/T
+++ b/tutorials/combustion/XiFoam/les/pitzDaily3D/0/T
@@ -1,8 +1,8 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  1.6                                   |
-|   \\  /    A nd           | Web:      http://www.OpenFOAM.org               |
+|  \\    /   O peration     | Version:  splitCyclic                           |
+|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
 FoamFile
@@ -10,11 +10,12 @@ FoamFile
     version     2.0;
     format      ascii;
     class       volScalarField;
+    location    "0";
     object      T;
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-dimensions      [0 0 0 1 0 0 0];
+dimensions      [ 0 0 0 1 0 0 0 ];
 
 internalField   uniform 293;
 
@@ -25,30 +26,31 @@ boundaryField
         type            fixedValue;
         value           uniform 293;
     }
-
     outlet
     {
         type            inletOutlet;
         inletValue      uniform 293;
         value           uniform 293;
     }
-
     upperWall
     {
         type            fixedValue;
         value           uniform 293;
     }
-
     lowerWall
     {
         type            fixedValue;
         value           uniform 570;
     }
-
-    frontAndBack
+    frontAndBack_half0
+    {
+        type            cyclic;
+    }
+    frontAndBack_half1
     {
         type            cyclic;
     }
 }
 
+
 // ************************************************************************* //
diff --git a/tutorials/combustion/XiFoam/les/pitzDaily3D/0/Tu b/tutorials/combustion/XiFoam/les/pitzDaily3D/0/Tu
index 82ea630126305b297be627093e1625a22ae1d66f..c0fa420d2b62b98d05296879a8b5e8289480a86a 100644
--- a/tutorials/combustion/XiFoam/les/pitzDaily3D/0/Tu
+++ b/tutorials/combustion/XiFoam/les/pitzDaily3D/0/Tu
@@ -1,8 +1,8 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  1.6                                   |
-|   \\  /    A nd           | Web:      http://www.OpenFOAM.org               |
+|  \\    /   O peration     | Version:  splitCyclic                           |
+|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
 FoamFile
@@ -10,11 +10,12 @@ FoamFile
     version     2.0;
     format      ascii;
     class       volScalarField;
+    location    "0";
     object      Tu;
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-dimensions      [0 0 0 1 0 0 0];
+dimensions      [ 0 0 0 1 0 0 0 ];
 
 internalField   uniform 293;
 
@@ -25,30 +26,31 @@ boundaryField
         type            fixedValue;
         value           uniform 293;
     }
-
     outlet
     {
         type            inletOutlet;
         inletValue      uniform 293;
         value           uniform 293;
     }
-
     upperWall
     {
         type            fixedValue;
         value           uniform 293;
     }
-
     lowerWall
     {
         type            fixedValue;
         value           uniform 570;
     }
-
-    frontAndBack
+    frontAndBack_half0
+    {
+        type            cyclic;
+    }
+    frontAndBack_half1
     {
         type            cyclic;
     }
 }
 
+
 // ************************************************************************* //
diff --git a/tutorials/combustion/XiFoam/les/pitzDaily3D/0/U b/tutorials/combustion/XiFoam/les/pitzDaily3D/0/U
index c3f3a97c29db153e27df11f91f56bf35f95c1c91..6067884afc1f8ba65ad62799fad8ba288dc8503b 100644
--- a/tutorials/combustion/XiFoam/les/pitzDaily3D/0/U
+++ b/tutorials/combustion/XiFoam/les/pitzDaily3D/0/U
@@ -1,8 +1,8 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  1.6                                   |
-|   \\  /    A nd           | Web:      http://www.OpenFOAM.org               |
+|  \\    /   O peration     | Version:  splitCyclic                           |
+|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
 FoamFile
@@ -10,47 +10,49 @@ FoamFile
     version     2.0;
     format      ascii;
     class       volVectorField;
+    location    "0";
     object      U;
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-dimensions      [0 1 -1 0 0 0 0];
+dimensions      [ 0 1 -1 0 0 0 0 ];
 
-internalField   uniform (0 0 0);
+internalField   uniform ( 0 0 0 );
 
 boundaryField
 {
     inlet
     {
         type            turbulentInlet;
-        referenceField  uniform (13.3 0 0);
-        fluctuationScale (0.04 0.02 0.02);
-        alpha            0.1;
+        referenceField  uniform ( 13.3 0 0 );
+        fluctuationScale ( 0.04 0.02 0.02 );
+        alpha           0.1;
     }
-
     outlet
     {
         type            inletOutlet;
-        inletValue      uniform (0 0 0);
-        value           uniform (0 0 0);
+        inletValue      uniform ( 0 0 0 );
+        value           uniform ( 0 0 0 );
     }
-
     upperWall
     {
         type            fixedValue;
-        value           uniform (0 0 0);
+        value           uniform ( 0 0 0 );
     }
-
     lowerWall
     {
         type            fixedValue;
-        value           uniform (0 0 0);
+        value           uniform ( 0 0 0 );
     }
-
-    frontAndBack
+    frontAndBack_half0
+    {
+        type            cyclic;
+    }
+    frontAndBack_half1
     {
         type            cyclic;
     }
 }
 
+
 // ************************************************************************* //
diff --git a/tutorials/combustion/XiFoam/les/pitzDaily3D/0/Xi b/tutorials/combustion/XiFoam/les/pitzDaily3D/0/Xi
index 6ddd7b27fb13c1a4345b4368e1c9d9d546b56621..eb94d243a8299f1a42311c97ef06561d3bc3b3e8 100644
--- a/tutorials/combustion/XiFoam/les/pitzDaily3D/0/Xi
+++ b/tutorials/combustion/XiFoam/les/pitzDaily3D/0/Xi
@@ -1,8 +1,8 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  1.6                                   |
-|   \\  /    A nd           | Web:      http://www.OpenFOAM.org               |
+|  \\    /   O peration     | Version:  splitCyclic                           |
+|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
 FoamFile
@@ -10,11 +10,12 @@ FoamFile
     version     2.0;
     format      ascii;
     class       volScalarField;
+    location    "0";
     object      Xi;
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-dimensions      [0 0 0 0 0 0 0];
+dimensions      [ 0 0 0 0 0 0 0 ];
 
 internalField   uniform 1;
 
@@ -25,28 +26,29 @@ boundaryField
         type            fixedValue;
         value           uniform 1;
     }
-
     outlet
     {
         type            inletOutlet;
         inletValue      uniform 1;
         value           uniform 1;
     }
-
     upperWall
     {
         type            zeroGradient;
     }
-
     lowerWall
     {
         type            zeroGradient;
     }
-
-    frontAndBack
+    frontAndBack_half0
+    {
+        type            cyclic;
+    }
+    frontAndBack_half1
     {
         type            cyclic;
     }
 }
 
+
 // ************************************************************************* //
diff --git a/tutorials/combustion/XiFoam/les/pitzDaily3D/0/alphaSgs b/tutorials/combustion/XiFoam/les/pitzDaily3D/0/alphaSgs
index b536298afbde6d3d058e1e71a21879386d1a9e50..3b3abcca8bf70d6ba77f8774cfa16af41350dee9 100644
--- a/tutorials/combustion/XiFoam/les/pitzDaily3D/0/alphaSgs
+++ b/tutorials/combustion/XiFoam/les/pitzDaily3D/0/alphaSgs
@@ -1,8 +1,8 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  1.6                                   |
-|   \\  /    A nd           | Web:      http://www.OpenFOAM.org               |
+|  \\    /   O peration     | Version:  splitCyclic                           |
+|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
 FoamFile
@@ -10,11 +10,12 @@ FoamFile
     version     2.0;
     format      ascii;
     class       volScalarField;
+    location    "0";
     object      alphaSgs;
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-dimensions      [1 -1 -1 0 0 0 0];
+dimensions      [ 1 -1 -1 0 0 0 0 ];
 
 internalField   uniform 0;
 
@@ -24,28 +25,29 @@ boundaryField
     {
         type            zeroGradient;
     }
-
     outlet
     {
         type            zeroGradient;
     }
-
     upperWall
     {
         type            alphaSgsJayatillekeWallFunction;
         value           uniform 0;
     }
-
     lowerWall
     {
         type            alphaSgsJayatillekeWallFunction;
         value           uniform 0;
     }
-
-    frontAndBack
+    frontAndBack_half0
+    {
+        type            cyclic;
+    }
+    frontAndBack_half1
     {
         type            cyclic;
     }
 }
 
+
 // ************************************************************************* //
diff --git a/tutorials/combustion/XiFoam/les/pitzDaily3D/0/b b/tutorials/combustion/XiFoam/les/pitzDaily3D/0/b
index 593c5cbfb1fd73b144dcd445c5d5d720125774d5..072346a532ce026b329c6d84788bee5d55bb5b17 100644
--- a/tutorials/combustion/XiFoam/les/pitzDaily3D/0/b
+++ b/tutorials/combustion/XiFoam/les/pitzDaily3D/0/b
@@ -1,8 +1,8 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  1.6                                   |
-|   \\  /    A nd           | Web:      http://www.OpenFOAM.org               |
+|  \\    /   O peration     | Version:  splitCyclic                           |
+|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
 FoamFile
@@ -10,11 +10,12 @@ FoamFile
     version     2.0;
     format      ascii;
     class       volScalarField;
+    location    "0";
     object      b;
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-dimensions      [0 0 0 0 0 0 0];
+dimensions      [ 0 0 0 0 0 0 0 ];
 
 internalField   uniform 1;
 
@@ -25,28 +26,29 @@ boundaryField
         type            fixedValue;
         value           uniform 1;
     }
-
     outlet
     {
         type            inletOutlet;
         inletValue      uniform 1;
         value           uniform 1;
     }
-
     upperWall
     {
         type            zeroGradient;
     }
-
     lowerWall
     {
         type            zeroGradient;
     }
-
-    frontAndBack
+    frontAndBack_half0
+    {
+        type            cyclic;
+    }
+    frontAndBack_half1
     {
         type            cyclic;
     }
 }
 
+
 // ************************************************************************* //
diff --git a/tutorials/combustion/XiFoam/les/pitzDaily3D/0/k b/tutorials/combustion/XiFoam/les/pitzDaily3D/0/k
index 4732ee3c328f65acf3a8675df9092cbf635719c1..862110ed4c789c6277106727b0bf7de2ba4a24d0 100644
--- a/tutorials/combustion/XiFoam/les/pitzDaily3D/0/k
+++ b/tutorials/combustion/XiFoam/les/pitzDaily3D/0/k
@@ -1,8 +1,8 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  1.6                                   |
-|   \\  /    A nd           | Web:      http://www.OpenFOAM.org               |
+|  \\    /   O peration     | Version:  splitCyclic                           |
+|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
 FoamFile
@@ -10,11 +10,12 @@ FoamFile
     version     2.0;
     format      ascii;
     class       volScalarField;
+    location    "0";
     object      k;
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-dimensions      [0 2 -2 0 0 0 0];
+dimensions      [ 0 2 -2 0 0 0 0 ];
 
 internalField   uniform 2e-05;
 
@@ -25,30 +26,31 @@ boundaryField
         type            fixedValue;
         value           uniform 2e-05;
     }
-
     outlet
     {
         type            inletOutlet;
         inletValue      uniform 2e-05;
         value           uniform 2e-05;
     }
-
     upperWall
     {
         type            zeroGradient;
         value           uniform 2e-05;
     }
-
     lowerWall
     {
         type            zeroGradient;
         value           uniform 2e-05;
     }
-
-    frontAndBack
+    frontAndBack_half0
+    {
+        type            cyclic;
+    }
+    frontAndBack_half1
     {
         type            cyclic;
     }
 }
 
+
 // ************************************************************************* //
diff --git a/tutorials/combustion/XiFoam/les/pitzDaily3D/0/muSgs b/tutorials/combustion/XiFoam/les/pitzDaily3D/0/muSgs
index 7a45526d54a995080e2de0fe56b082a297abb641..3894d39183dbecfca54f3e40c7de54595996ab03 100644
--- a/tutorials/combustion/XiFoam/les/pitzDaily3D/0/muSgs
+++ b/tutorials/combustion/XiFoam/les/pitzDaily3D/0/muSgs
@@ -1,8 +1,8 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  1.6                                   |
-|   \\  /    A nd           | Web:      http://www.OpenFOAM.org               |
+|  \\    /   O peration     | Version:  splitCyclic                           |
+|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
 FoamFile
@@ -10,11 +10,12 @@ FoamFile
     version     2.0;
     format      ascii;
     class       volScalarField;
+    location    "0";
     object      muSgs;
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-dimensions      [1 -1 -1 0 0 0 0];
+dimensions      [ 1 -1 -1 0 0 0 0 ];
 
 internalField   uniform 0;
 
@@ -24,28 +25,29 @@ boundaryField
     {
         type            zeroGradient;
     }
-
     outlet
     {
         type            zeroGradient;
     }
-
     upperWall
     {
         type            muSgsUSpaldingWallFunction;
         value           uniform 0;
     }
-
     lowerWall
     {
         type            muSgsUSpaldingWallFunction;
         value           uniform 0;
     }
-
-    frontAndBack
+    frontAndBack_half0
+    {
+        type            cyclic;
+    }
+    frontAndBack_half1
     {
         type            cyclic;
     }
 }
 
+
 // ************************************************************************* //
diff --git a/tutorials/combustion/XiFoam/les/pitzDaily3D/0/p b/tutorials/combustion/XiFoam/les/pitzDaily3D/0/p
index 375a81d78366c21f38824702ae59a1b5129a1265..bfd7be5db2f7b4d190e99ed451e14ca016b3374d 100644
--- a/tutorials/combustion/XiFoam/les/pitzDaily3D/0/p
+++ b/tutorials/combustion/XiFoam/les/pitzDaily3D/0/p
@@ -1,8 +1,8 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  1.6                                   |
-|   \\  /    A nd           | Web:      http://www.OpenFOAM.org               |
+|  \\    /   O peration     | Version:  splitCyclic                           |
+|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
 FoamFile
@@ -10,13 +10,14 @@ FoamFile
     version     2.0;
     format      ascii;
     class       volScalarField;
+    location    "0";
     object      p;
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-dimensions      [1 -1 -2 0 0 0 0];
+dimensions      [ 1 -1 -2 0 0 0 0 ];
 
-internalField   uniform 1e5;
+internalField   uniform 100000;
 
 boundaryField
 {
@@ -24,7 +25,6 @@ boundaryField
     {
         type            zeroGradient;
     }
-
     outlet
     {
         type            waveTransmissive;
@@ -33,25 +33,27 @@ boundaryField
         rho             rho;
         psi             psi;
         gamma           1.3;
-        fieldInf        1e5;
+        fieldInf        100000;
         lInf            0.3;
-        value           uniform 1e5;
+        value           uniform 100000;
     }
-
     upperWall
     {
         type            zeroGradient;
     }
-
     lowerWall
     {
         type            zeroGradient;
     }
-
-    frontAndBack
+    frontAndBack_half0
+    {
+        type            cyclic;
+    }
+    frontAndBack_half1
     {
         type            cyclic;
     }
 }
 
+
 // ************************************************************************* //
diff --git a/tutorials/combustion/XiFoam/les/pitzDaily3D/constant/polyMesh/boundary b/tutorials/combustion/XiFoam/les/pitzDaily3D/constant/polyMesh/boundary
index 19a09dd2c70ea42bdd3a67d5f2b730301dfbb213..807a1d700bcacca6e34218714b5a5c6c5d5d12f3 100644
--- a/tutorials/combustion/XiFoam/les/pitzDaily3D/constant/polyMesh/boundary
+++ b/tutorials/combustion/XiFoam/les/pitzDaily3D/constant/polyMesh/boundary
@@ -1,7 +1,7 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  dev                                   |
+|  \\    /   O peration     | Version:  splitCyclic                           |
 |   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
@@ -15,7 +15,7 @@ FoamFile
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-5
+6
 (
     inlet
     {
@@ -41,12 +41,19 @@ FoamFile
         nFaces          5000;
         startFace       721875;
     }
-    frontAndBack
+    frontAndBack_half0
     {
         type            cyclic;
-        nFaces          24450;
+        nFaces          12225;
         startFace       726875;
-        featureCos      0.9;
+        neighbourPatch  frontAndBack_half1;
+    }
+    frontAndBack_half1
+    {
+        type            cyclic;
+        nFaces          12225;
+        startFace       739100;
+        neighbourPatch  frontAndBack_half0;
     }
 )
 
diff --git a/tutorials/combustion/fireFoam/les/smallPoolFire2D/constant/polyMesh/boundary b/tutorials/combustion/fireFoam/les/smallPoolFire2D/constant/polyMesh/boundary
index ce658ffe2525b139025eff2cb449728439bbadf9..ec0f8f9092dbd828af9f68e4cb0c8cca498788f8 100644
--- a/tutorials/combustion/fireFoam/les/smallPoolFire2D/constant/polyMesh/boundary
+++ b/tutorials/combustion/fireFoam/les/smallPoolFire2D/constant/polyMesh/boundary
@@ -1,7 +1,7 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  dev                                   |
+|  \\    /   O peration     | Version:  splitCyclic                           |
 |   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
@@ -15,37 +15,31 @@ FoamFile
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-5
+4
 (
     base
     {
         type            patch;
-        nFaces          134;
+        nFaces          150;
         startFace       44700;
     }
     outlet
     {
         type            patch;
         nFaces          150;
-        startFace       44834;
+        startFace       44850;
     }
     sides
     {
         type            patch;
         nFaces          300;
-        startFace       44984;
+        startFace       45000;
     }
     frontAndBack
     {
         type            empty;
         nFaces          45000;
-        startFace       45284;
-    }
-    inlet
-    {
-        type            patch;
-        nFaces          16;
-        startFace       90284;
+        startFace       45300;
     }
 )
 
diff --git a/tutorials/icoFoam/cavity/constant/polyMesh/blockMeshDict b/tutorials/icoFoam/cavity/constant/polyMesh/blockMeshDict
new file mode 100644
index 0000000000000000000000000000000000000000..8cd967d0a920980d81bab51aba197dadb0e5e4cc
--- /dev/null
+++ b/tutorials/icoFoam/cavity/constant/polyMesh/blockMeshDict
@@ -0,0 +1,97 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  1.5                                   |
+|   \\  /    A nd           | Web:      http://www.OpenFOAM.org               |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       dictionary;
+    object      blockMeshDict;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+convertToMeters 0.1;
+
+vertices        
+(
+    (0 0 0)
+    (1 0 0)
+    (1 1 0)
+    (0 1 0)
+    (0 0 0.1)
+    (1 0 0.1)
+    (1 1 0.1)
+    (0 1 0.1)
+);
+
+blocks          
+(
+    hex (0 1 2 3 4 5 6 7) (20 20 1) simpleGrading (1 1 1)
+);
+
+edges           
+(
+);
+
+//patches         
+//(
+//    wall movingWall 
+//    (
+//        (3 7 6 2)
+//    )
+//    wall fixedWalls 
+//    (
+//        (0 4 7 3)
+//        (2 6 5 1)
+//        (1 5 4 0)
+//    )
+//    empty frontAndBack 
+//    (
+//        (0 3 2 1)
+//        (4 5 6 7)
+//    )
+//);
+
+boundary         
+(
+    movingWall
+    {
+        type wall;
+        faces
+        (
+            (3 7 6 2)
+        );
+    }
+
+    fixedWalls
+    {
+        type wall;
+        faces
+        (
+            (0 4 7 3)
+            (2 6 5 1)
+            (1 5 4 0)
+        );
+    }
+
+    frontAndBack 
+    {
+        type empty;
+        faces
+        (
+            (0 3 2 1)
+            (4 5 6 7)
+        );
+    }
+);
+
+
+mergePatchPairs 
+(
+);
+
+// ************************************************************************* //
diff --git a/tutorials/incompressible/boundaryFoam/boundaryLaunderSharma/0/R b/tutorials/incompressible/boundaryFoam/boundaryLaunderSharma/0/R
index 2f43ccf83a3cc90817a35c59cb808f9180cc18f6..4c521594c6711856b11639ea6ec40772c60731f1 100644
--- a/tutorials/incompressible/boundaryFoam/boundaryLaunderSharma/0/R
+++ b/tutorials/incompressible/boundaryFoam/boundaryLaunderSharma/0/R
@@ -1,8 +1,8 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  1.6                                   |
-|   \\  /    A nd           | Web:      http://www.OpenFOAM.org               |
+|  \\    /   O peration     | Version:  splitCyclic                           |
+|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
 FoamFile
@@ -10,37 +10,40 @@ FoamFile
     version     2.0;
     format      ascii;
     class       volSymmTensorField;
+    location    "0";
     object      R;
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-dimensions      [0 2 -2 0 0 0 0];
+dimensions      [ 0 2 -2 0 0 0 0 ];
 
-internalField   uniform (0 0 0 0 0 0);
+internalField   uniform ( 0 0 0 0 0 0 );
 
 boundaryField
 {
-    lowerWall       
+    lowerWall
     {
         type            fixedValue;
-        value           uniform (0 0 0 0 0 0);
+        value           uniform ( 0 0 0 0 0 0 );
     }
-
-    upperWall       
+    upperWall
     {
         type            fixedValue;
-        value           uniform (0 0 0 0 0 0);
+        value           uniform ( 0 0 0 0 0 0 );
     }
-
-    frontBack
+    frontBack_half0
     {
         type            cyclic;
     }
-
-    defaultFaces    
+    defaultFaces
     {
         type            empty;
     }
+    frontBack_half1
+    {
+        type            cyclic;
+    }
 }
 
+
 // ************************************************************************* //
diff --git a/tutorials/incompressible/boundaryFoam/boundaryLaunderSharma/0/U b/tutorials/incompressible/boundaryFoam/boundaryLaunderSharma/0/U
index ff0c48d23a52f9a3da31fc00d2a7155835b64cd7..c9e313803e47db09d64aba5279d1322b0be93b3e 100644
--- a/tutorials/incompressible/boundaryFoam/boundaryLaunderSharma/0/U
+++ b/tutorials/incompressible/boundaryFoam/boundaryLaunderSharma/0/U
@@ -1,8 +1,8 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  1.6                                   |
-|   \\  /    A nd           | Web:      http://www.OpenFOAM.org               |
+|  \\    /   O peration     | Version:  splitCyclic                           |
+|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
 FoamFile
@@ -10,37 +10,40 @@ FoamFile
     version     2.0;
     format      ascii;
     class       volVectorField;
+    location    "0";
     object      U;
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-dimensions      [0 1 -1 0 0 0 0];
+dimensions      [ 0 1 -1 0 0 0 0 ];
 
-internalField   uniform (10 0 0);
+internalField   uniform ( 10 0 0 );
 
 boundaryField
 {
-    lowerWall       
+    lowerWall
     {
         type            fixedValue;
-        value           uniform (0 0 0);
+        value           uniform ( 0 0 0 );
     }
-
-    upperWall       
+    upperWall
     {
         type            fixedValue;
-        value           uniform (0 0 0);
+        value           uniform ( 0 0 0 );
     }
-
-    frontBack
+    frontBack_half0
     {
         type            cyclic;
     }
-
-    defaultFaces    
+    defaultFaces
     {
         type            empty;
     }
+    frontBack_half1
+    {
+        type            cyclic;
+    }
 }
 
+
 // ************************************************************************* //
diff --git a/tutorials/incompressible/boundaryFoam/boundaryLaunderSharma/0/epsilon b/tutorials/incompressible/boundaryFoam/boundaryLaunderSharma/0/epsilon
index 185f2774648f114dab1ba3cd1900cc4bff6d772a..52126ce75462a71b644cfec5e8f8ea033d16ac58 100644
--- a/tutorials/incompressible/boundaryFoam/boundaryLaunderSharma/0/epsilon
+++ b/tutorials/incompressible/boundaryFoam/boundaryLaunderSharma/0/epsilon
@@ -1,8 +1,8 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  1.6                                   |
-|   \\  /    A nd           | Web:      http://www.OpenFOAM.org               |
+|  \\    /   O peration     | Version:  splitCyclic                           |
+|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
 FoamFile
@@ -10,37 +10,40 @@ FoamFile
     version     2.0;
     format      ascii;
     class       volScalarField;
+    location    "0";
     object      epsilon;
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-dimensions      [0 2 -3 0 0 0 0];
+dimensions      [ 0 2 -3 0 0 0 0 ];
 
 internalField   uniform 10;
 
 boundaryField
 {
-    lowerWall       
+    lowerWall
     {
         type            fixedValue;
         value           uniform 1e-08;
     }
-
-    upperWall       
+    upperWall
     {
         type            fixedValue;
         value           uniform 1e-08;
     }
-
-    frontBack
+    frontBack_half0
     {
         type            cyclic;
     }
-
-    defaultFaces    
+    defaultFaces
     {
         type            empty;
     }
+    frontBack_half1
+    {
+        type            cyclic;
+    }
 }
 
+
 // ************************************************************************* //
diff --git a/tutorials/incompressible/boundaryFoam/boundaryLaunderSharma/0/k b/tutorials/incompressible/boundaryFoam/boundaryLaunderSharma/0/k
index 31c80698070dc0b8963efe78c474a282ed894110..c0be82cd30a7929e2c1b0e1f5f7878b712aae3b5 100644
--- a/tutorials/incompressible/boundaryFoam/boundaryLaunderSharma/0/k
+++ b/tutorials/incompressible/boundaryFoam/boundaryLaunderSharma/0/k
@@ -1,8 +1,8 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  1.6                                   |
-|   \\  /    A nd           | Web:      http://www.OpenFOAM.org               |
+|  \\    /   O peration     | Version:  splitCyclic                           |
+|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
 FoamFile
@@ -10,37 +10,40 @@ FoamFile
     version     2.0;
     format      ascii;
     class       volScalarField;
+    location    "0";
     object      k;
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-dimensions      [0 2 -2 0 0 0 0];
+dimensions      [ 0 2 -2 0 0 0 0 ];
 
 internalField   uniform 1;
 
 boundaryField
 {
-    lowerWall       
+    lowerWall
     {
         type            fixedValue;
         value           uniform 1e-10;
     }
-
-    upperWall       
+    upperWall
     {
         type            fixedValue;
         value           uniform 1e-10;
     }
-
-    frontBack
+    frontBack_half0
     {
         type            cyclic;
     }
-
-    defaultFaces    
+    defaultFaces
     {
         type            empty;
     }
+    frontBack_half1
+    {
+        type            cyclic;
+    }
 }
 
+
 // ************************************************************************* //
diff --git a/tutorials/incompressible/boundaryFoam/boundaryLaunderSharma/0/nu.xy b/tutorials/incompressible/boundaryFoam/boundaryLaunderSharma/0/nu.xy
index 2494e52d0cdddef5b33903b136e441df5a7b72c4..a2d65783b77e48a63f602310aa21e48df6cd11ca 100644
--- a/tutorials/incompressible/boundaryFoam/boundaryLaunderSharma/0/nu.xy
+++ b/tutorials/incompressible/boundaryFoam/boundaryLaunderSharma/0/nu.xy
@@ -1,80 +1,80 @@
--0.0499719      1e-05
--0.0499122      1e-05
- -0.049845      1e-05
--0.0497694      1e-05
--0.0496843      1e-05
--0.0495885      1e-05
--0.0494808      1e-05
--0.0493595      1e-05
--0.0492231      1e-05
--0.0490695      1e-05
--0.0488967      1e-05
--0.0487022      1e-05
--0.0484834      1e-05
--0.0482371      1e-05
-  -0.04796      1e-05
--0.0476481      1e-05
--0.0472971      1e-05
--0.0469021      1e-05
--0.0464577      1e-05
--0.0459575      1e-05
--0.0453947      1e-05
--0.0447613      1e-05
--0.0440485      1e-05
--0.0432464      1e-05
--0.0423437      1e-05
--0.0413279      1e-05
--0.0401848      1e-05
--0.0388984      1e-05
--0.0374508      1e-05
--0.0358218      1e-05
--0.0339885      1e-05
--0.0319255      1e-05
- -0.029604      1e-05
--0.0269914      1e-05
--0.0240515      1e-05
- -0.020743      1e-05
--0.0170199      1e-05
--0.0128301      1e-05
--0.00811521      1e-05
--0.00280937      1e-05
-0.00280937      1e-05
-0.00811521      1e-05
- 0.0128301      1e-05
- 0.0170199      1e-05
-  0.020743      1e-05
- 0.0240515      1e-05
- 0.0269914      1e-05
-  0.029604      1e-05
- 0.0319255      1e-05
- 0.0339885      1e-05
- 0.0358218      1e-05
- 0.0374508      1e-05
- 0.0388984      1e-05
- 0.0401848      1e-05
- 0.0413279      1e-05
- 0.0423437      1e-05
- 0.0432464      1e-05
- 0.0440485      1e-05
- 0.0447613      1e-05
- 0.0453947      1e-05
- 0.0459575      1e-05
- 0.0464577      1e-05
- 0.0469021      1e-05
- 0.0472971      1e-05
- 0.0476481      1e-05
-   0.04796      1e-05
- 0.0482371      1e-05
- 0.0484834      1e-05
- 0.0487022      1e-05
- 0.0488967      1e-05
- 0.0490695      1e-05
- 0.0492231      1e-05
- 0.0493595      1e-05
- 0.0494808      1e-05
- 0.0495885      1e-05
- 0.0496843      1e-05
- 0.0497694      1e-05
-  0.049845      1e-05
- 0.0499122      1e-05
- 0.0499719      1e-05
+2.80937e-05      1e-05
+8.78022e-05      1e-05
+0.000154994      1e-05
+0.000230608      1e-05
+0.000315699      1e-05
+0.000411455      1e-05
+0.000519212      1e-05
+0.000640475      1e-05
+0.000776937      1e-05
+0.000930502      1e-05
+0.00110331      1e-05
+0.00129779      1e-05
+0.00151663      1e-05
+0.00176291      1e-05
+0.00204005      1e-05
+0.00235193      1e-05
+ 0.0027029      1e-05
+0.00309785      1e-05
+0.00354231      1e-05
+0.00404248      1e-05
+0.00460533      1e-05
+0.00523873      1e-05
+0.00595151      1e-05
+0.00675364      1e-05
+ 0.0076563      1e-05
+0.00867209      1e-05
+ 0.0098152      1e-05
+ 0.0111016      1e-05
+ 0.0125492      1e-05
+ 0.0141782      1e-05
+ 0.0160115      1e-05
+ 0.0180745      1e-05
+  0.020396      1e-05
+ 0.0230086      1e-05
+ 0.0259485      1e-05
+  0.029257      1e-05
+ 0.0329801      1e-05
+ 0.0371699      1e-05
+ 0.0418848      1e-05
+ 0.0471906      1e-05
+ 0.0528094      1e-05
+ 0.0581152      1e-05
+ 0.0628301      1e-05
+ 0.0670199      1e-05
+  0.070743      1e-05
+ 0.0740515      1e-05
+ 0.0769914      1e-05
+  0.079604      1e-05
+ 0.0819255      1e-05
+ 0.0839885      1e-05
+ 0.0858218      1e-05
+ 0.0874508      1e-05
+ 0.0888984      1e-05
+ 0.0901848      1e-05
+ 0.0913279      1e-05
+ 0.0923437      1e-05
+ 0.0932464      1e-05
+ 0.0940485      1e-05
+ 0.0947613      1e-05
+ 0.0953947      1e-05
+ 0.0959575      1e-05
+ 0.0964577      1e-05
+ 0.0969021      1e-05
+ 0.0972971      1e-05
+ 0.0976481      1e-05
+   0.09796      1e-05
+ 0.0982371      1e-05
+ 0.0984834      1e-05
+ 0.0987022      1e-05
+ 0.0988967      1e-05
+ 0.0990695      1e-05
+ 0.0992231      1e-05
+ 0.0993595      1e-05
+ 0.0994808      1e-05
+ 0.0995885      1e-05
+ 0.0996843      1e-05
+ 0.0997694      1e-05
+  0.099845      1e-05
+ 0.0999122      1e-05
+ 0.0999719      1e-05
diff --git a/tutorials/incompressible/boundaryFoam/boundaryLaunderSharma/0/nuTilda b/tutorials/incompressible/boundaryFoam/boundaryLaunderSharma/0/nuTilda
index 5a3e879d5ff25dc2f58351cf3c5e60e00e44b01b..a9534f20fbf342e18599551d8ebe3cd6839529ef 100644
--- a/tutorials/incompressible/boundaryFoam/boundaryLaunderSharma/0/nuTilda
+++ b/tutorials/incompressible/boundaryFoam/boundaryLaunderSharma/0/nuTilda
@@ -1,8 +1,8 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  1.6                                   |
-|   \\  /    A nd           | Web:      http://www.OpenFOAM.org               |
+|  \\    /   O peration     | Version:  splitCyclic                           |
+|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
 FoamFile
@@ -10,37 +10,40 @@ FoamFile
     version     2.0;
     format      ascii;
     class       volScalarField;
+    location    "0";
     object      nuTilda;
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-dimensions      [0 2 -1 0 0 0 0];
+dimensions      [ 0 2 -1 0 0 0 0 ];
 
 internalField   uniform 0;
 
 boundaryField
 {
-    lowerWall       
+    lowerWall
     {
         type            fixedValue;
         value           uniform 0;
     }
-
-    upperWall       
+    upperWall
     {
         type            fixedValue;
         value           uniform 0;
     }
-
-    frontBack
+    frontBack_half0
     {
         type            cyclic;
     }
-
-    defaultFaces    
+    defaultFaces
     {
         type            empty;
     }
+    frontBack_half1
+    {
+        type            cyclic;
+    }
 }
 
+
 // ************************************************************************* //
diff --git a/tutorials/incompressible/boundaryFoam/boundaryLaunderSharma/constant/polyMesh/boundary b/tutorials/incompressible/boundaryFoam/boundaryLaunderSharma/constant/polyMesh/boundary
index 9948385f121d383a0404a9b74c6f47b8f4d4d20f..0c4f64d3e0c3c3f0e927b0265f9bda2334208ef3 100644
--- a/tutorials/incompressible/boundaryFoam/boundaryLaunderSharma/constant/polyMesh/boundary
+++ b/tutorials/incompressible/boundaryFoam/boundaryLaunderSharma/constant/polyMesh/boundary
@@ -1,7 +1,7 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  1.6                                   |
+|  \\    /   O peration     | Version:  splitCyclic                           |
 |   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
@@ -15,7 +15,7 @@ FoamFile
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-4
+5
 (
     lowerWall
     {
@@ -29,12 +29,19 @@ FoamFile
         nFaces          1;
         startFace       80;
     }
-    frontBack
+    frontBack_half0
     {
         type            cyclic;
-        nFaces          160;
+        nFaces          80;
         startFace       81;
-        featureCos      0.9;
+        neighbourPatch  frontBack_half1;
+    }
+    frontBack_half1
+    {
+        type            cyclic;
+        nFaces          80;
+        startFace       161;
+        neighbourPatch  frontBack_half0;
     }
     defaultFaces
     {
diff --git a/tutorials/incompressible/boundaryFoam/boundaryWallFunctions/0/R b/tutorials/incompressible/boundaryFoam/boundaryWallFunctions/0/R
index 54eeab58dd43aa5476f458a9eb2bcd885eb41c3c..1c5c522387400f39c6533b8ac235ee6e9c51649d 100644
--- a/tutorials/incompressible/boundaryFoam/boundaryWallFunctions/0/R
+++ b/tutorials/incompressible/boundaryFoam/boundaryWallFunctions/0/R
@@ -1,8 +1,8 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  1.6                                   |
-|   \\  /    A nd           | Web:      http://www.OpenFOAM.org               |
+|  \\    /   O peration     | Version:  splitCyclic                           |
+|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
 FoamFile
@@ -10,35 +10,38 @@ FoamFile
     version     2.0;
     format      ascii;
     class       volSymmTensorField;
+    location    "0";
     object      R;
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-dimensions      [0 2 -2 0 0 0 0];
+dimensions      [ 0 2 -2 0 0 0 0 ];
 
-internalField   uniform (0 0 0 0 0 0);
+internalField   uniform ( 0 0 0 0 0 0 );
 
 boundaryField
 {
-    lowerWall       
+    lowerWall
     {
         type            zeroGradient;
     }
-
-    upperWall       
+    upperWall
     {
         type            zeroGradient;
     }
-
-    frontBack
+    frontBack_half0
     {
         type            cyclic;
     }
-
-    defaultFaces    
+    defaultFaces
     {
         type            empty;
     }
+    frontBack_half1
+    {
+        type            cyclic;
+    }
 }
 
+
 // ************************************************************************* //
diff --git a/tutorials/incompressible/boundaryFoam/boundaryWallFunctions/0/U b/tutorials/incompressible/boundaryFoam/boundaryWallFunctions/0/U
index 00140fa5044938c14acd7e07f1330f6dda4435e4..cc15bf6bfee1281e568002f55bc2e3bb1cf05d7d 100644
--- a/tutorials/incompressible/boundaryFoam/boundaryWallFunctions/0/U
+++ b/tutorials/incompressible/boundaryFoam/boundaryWallFunctions/0/U
@@ -1,8 +1,8 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  1.6                                   |
-|   \\  /    A nd           | Web:      http://www.OpenFOAM.org               |
+|  \\    /   O peration     | Version:  splitCyclic                           |
+|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
 FoamFile
@@ -10,37 +10,40 @@ FoamFile
     version     2.0;
     format      ascii;
     class       volVectorField;
+    location    "0";
     object      U;
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-dimensions      [0 1 -1 0 0 0 0];
+dimensions      [ 0 1 -1 0 0 0 0 ];
 
-internalField   uniform (0 0 0);
+internalField   uniform ( 0 0 0 );
 
 boundaryField
 {
-    lowerWall       
+    lowerWall
     {
         type            fixedValue;
-        value           uniform (0 0 0);
+        value           uniform ( 0 0 0 );
     }
-
-    upperWall       
+    upperWall
     {
         type            fixedValue;
-        value           uniform (0 0 0);
+        value           uniform ( 0 0 0 );
     }
-
-    frontBack
+    frontBack_half0
     {
         type            cyclic;
     }
-
-    defaultFaces    
+    defaultFaces
     {
         type            empty;
     }
+    frontBack_half1
+    {
+        type            cyclic;
+    }
 }
 
+
 // ************************************************************************* //
diff --git a/tutorials/incompressible/boundaryFoam/boundaryWallFunctions/0/epsilon b/tutorials/incompressible/boundaryFoam/boundaryWallFunctions/0/epsilon
index 5b6d7f698f76f16741b27760ecdc6c1cd79234ca..37c5fc7837b9c59f828f5eb54c99d9aff2f8bf13 100644
--- a/tutorials/incompressible/boundaryFoam/boundaryWallFunctions/0/epsilon
+++ b/tutorials/incompressible/boundaryFoam/boundaryWallFunctions/0/epsilon
@@ -1,7 +1,7 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  1.6                                   |
+|  \\    /   O peration     | Version:  splitCyclic                           |
 |   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
@@ -15,7 +15,7 @@ FoamFile
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-dimensions      [0 2 -3 0 0 0 0];
+dimensions      [ 0 2 -3 0 0 0 0 ];
 
 internalField   uniform 1e-08;
 
@@ -31,15 +31,18 @@ boundaryField
         type            epsilonWallFunction;
         value           uniform 1e-08;
     }
-    frontBack
+    frontBack_half0
     {
         type            cyclic;
-        value           uniform 1e-08;
     }
     defaultFaces
     {
         type            empty;
     }
+    frontBack_half1
+    {
+        type            cyclic;
+    }
 }
 
 
diff --git a/tutorials/incompressible/boundaryFoam/boundaryWallFunctions/0/k b/tutorials/incompressible/boundaryFoam/boundaryWallFunctions/0/k
index a51a9a2e6d3d10c59b608977d419120be19e4e14..ac3233b3d312f36bb49f6105942b002506014558 100644
--- a/tutorials/incompressible/boundaryFoam/boundaryWallFunctions/0/k
+++ b/tutorials/incompressible/boundaryFoam/boundaryWallFunctions/0/k
@@ -1,7 +1,7 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  1.6                                   |
+|  \\    /   O peration     | Version:  splitCyclic                           |
 |   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
@@ -15,7 +15,7 @@ FoamFile
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-dimensions      [0 2 -2 0 0 0 0];
+dimensions      [ 0 2 -2 0 0 0 0 ];
 
 internalField   uniform 1e-10;
 
@@ -31,179 +31,18 @@ boundaryField
         type            kqRWallFunction;
         value           uniform 1e-10;
     }
-    frontBack
+    frontBack_half0
     {
         type            cyclic;
-        value           nonuniform List<scalar> 
-160
-(
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-1e-10
-)
-;
     }
     defaultFaces
     {
         type            empty;
     }
+    frontBack_half1
+    {
+        type            cyclic;
+    }
 }
 
 
diff --git a/tutorials/incompressible/boundaryFoam/boundaryWallFunctions/0/nu.xy b/tutorials/incompressible/boundaryFoam/boundaryWallFunctions/0/nu.xy
index 9417b47353e7aeafc786a158ca814ce6a523854e..008ac1a40ff22cf531b1da423e0f16e7bf3e88c6 100644
--- a/tutorials/incompressible/boundaryFoam/boundaryWallFunctions/0/nu.xy
+++ b/tutorials/incompressible/boundaryFoam/boundaryWallFunctions/0/nu.xy
@@ -1,43 +1,3 @@
- -0.049375      1e-05
- -0.048125      1e-05
- -0.046875      1e-05
- -0.045625      1e-05
- -0.044375      1e-05
- -0.043125      1e-05
- -0.041875      1e-05
- -0.040625      1e-05
- -0.039375      1e-05
- -0.038125      1e-05
- -0.036875      1e-05
- -0.035625      1e-05
- -0.034375      1e-05
- -0.033125      1e-05
- -0.031875      1e-05
- -0.030625      1e-05
- -0.029375      1e-05
- -0.028125      1e-05
- -0.026875      1e-05
- -0.025625      1e-05
- -0.024375      1e-05
- -0.023125      1e-05
- -0.021875      1e-05
- -0.020625      1e-05
- -0.019375      1e-05
- -0.018125      1e-05
- -0.016875      1e-05
- -0.015625      1e-05
- -0.014375      1e-05
- -0.013125      1e-05
- -0.011875      1e-05
- -0.010625      1e-05
- -0.009375      1e-05
- -0.008125      1e-05
- -0.006875      1e-05
- -0.005625      1e-05
- -0.004375      1e-05
- -0.003125      1e-05
- -0.001875      1e-05
- -0.000625      1e-05
   0.000625      1e-05
   0.001875      1e-05
   0.003125      1e-05
@@ -78,3 +38,43 @@
   0.046875      1e-05
   0.048125      1e-05
   0.049375      1e-05
+  0.050625      1e-05
+  0.051875      1e-05
+  0.053125      1e-05
+  0.054375      1e-05
+  0.055625      1e-05
+  0.056875      1e-05
+  0.058125      1e-05
+  0.059375      1e-05
+  0.060625      1e-05
+  0.061875      1e-05
+  0.063125      1e-05
+  0.064375      1e-05
+  0.065625      1e-05
+  0.066875      1e-05
+  0.068125      1e-05
+  0.069375      1e-05
+  0.070625      1e-05
+  0.071875      1e-05
+  0.073125      1e-05
+  0.074375      1e-05
+  0.075625      1e-05
+  0.076875      1e-05
+  0.078125      1e-05
+  0.079375      1e-05
+  0.080625      1e-05
+  0.081875      1e-05
+  0.083125      1e-05
+  0.084375      1e-05
+  0.085625      1e-05
+  0.086875      1e-05
+  0.088125      1e-05
+  0.089375      1e-05
+  0.090625      1e-05
+  0.091875      1e-05
+  0.093125      1e-05
+  0.094375      1e-05
+  0.095625      1e-05
+  0.096875      1e-05
+  0.098125      1e-05
+  0.099375      1e-05
diff --git a/tutorials/incompressible/boundaryFoam/boundaryWallFunctions/0/nuTilda b/tutorials/incompressible/boundaryFoam/boundaryWallFunctions/0/nuTilda
index 38a021b100eaa1fe09bf2364e8d69e25135e27cd..1a0a5c1a46e2c9b6a7698fbd797268bf04e0629b 100644
--- a/tutorials/incompressible/boundaryFoam/boundaryWallFunctions/0/nuTilda
+++ b/tutorials/incompressible/boundaryFoam/boundaryWallFunctions/0/nuTilda
@@ -1,8 +1,8 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  1.6                                   |
-|   \\  /    A nd           | Web:      http://www.OpenFOAM.org               |
+|  \\    /   O peration     | Version:  splitCyclic                           |
+|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
 FoamFile
@@ -10,35 +10,38 @@ FoamFile
     version     2.0;
     format      ascii;
     class       volScalarField;
+    location    "0";
     object      nuTilda;
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-dimensions      [0 2 -1 0 0 0 0];
+dimensions      [ 0 2 -1 0 0 0 0 ];
 
 internalField   uniform 0;
 
 boundaryField
 {
-    lowerWall       
+    lowerWall
     {
         type            zeroGradient;
     }
-
-    upperWall       
+    upperWall
     {
         type            zeroGradient;
     }
-
-    frontBack
+    frontBack_half0
     {
         type            cyclic;
     }
-
-    defaultFaces    
+    defaultFaces
     {
         type            empty;
     }
+    frontBack_half1
+    {
+        type            cyclic;
+    }
 }
 
+
 // ************************************************************************* //
diff --git a/tutorials/incompressible/boundaryFoam/boundaryWallFunctions/0/nut b/tutorials/incompressible/boundaryFoam/boundaryWallFunctions/0/nut
index 5bcd4c4a1db7b020221531c616c9e56b26d8c2c4..986830e430429ea325ac281391ff2aa165a5356c 100644
--- a/tutorials/incompressible/boundaryFoam/boundaryWallFunctions/0/nut
+++ b/tutorials/incompressible/boundaryFoam/boundaryWallFunctions/0/nut
@@ -1,7 +1,7 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  1.6                                   |
+|  \\    /   O peration     | Version:  splitCyclic                           |
 |   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
@@ -15,7 +15,7 @@ FoamFile
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-dimensions      [0 2 -1 0 0 0 0];
+dimensions      [ 0 2 -1 0 0 0 0 ];
 
 internalField   uniform 0;
 
@@ -31,15 +31,18 @@ boundaryField
         type            nutkWallFunction;
         value           uniform 0;
     }
-    frontBack
+    frontBack_half0
     {
         type            cyclic;
-        value           uniform 0;
     }
     defaultFaces
     {
         type            empty;
     }
+    frontBack_half1
+    {
+        type            cyclic;
+    }
 }
 
 
diff --git a/tutorials/incompressible/boundaryFoam/boundaryWallFunctions/constant/polyMesh/boundary b/tutorials/incompressible/boundaryFoam/boundaryWallFunctions/constant/polyMesh/boundary
index 9948385f121d383a0404a9b74c6f47b8f4d4d20f..0c4f64d3e0c3c3f0e927b0265f9bda2334208ef3 100644
--- a/tutorials/incompressible/boundaryFoam/boundaryWallFunctions/constant/polyMesh/boundary
+++ b/tutorials/incompressible/boundaryFoam/boundaryWallFunctions/constant/polyMesh/boundary
@@ -1,7 +1,7 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  1.6                                   |
+|  \\    /   O peration     | Version:  splitCyclic                           |
 |   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
@@ -15,7 +15,7 @@ FoamFile
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-4
+5
 (
     lowerWall
     {
@@ -29,12 +29,19 @@ FoamFile
         nFaces          1;
         startFace       80;
     }
-    frontBack
+    frontBack_half0
     {
         type            cyclic;
-        nFaces          160;
+        nFaces          80;
         startFace       81;
-        featureCos      0.9;
+        neighbourPatch  frontBack_half1;
+    }
+    frontBack_half1
+    {
+        type            cyclic;
+        nFaces          80;
+        startFace       161;
+        neighbourPatch  frontBack_half0;
     }
     defaultFaces
     {
diff --git a/tutorials/incompressible/boundaryFoam/boundaryWallFunctionsProfile/0/U b/tutorials/incompressible/boundaryFoam/boundaryWallFunctionsProfile/0/U
index b75d124cdc759d9c09bbf2566179138bc45c0415..24fd818213520a39aabfb177004d11ae6cadb8b4 100644
--- a/tutorials/incompressible/boundaryFoam/boundaryWallFunctionsProfile/0/U
+++ b/tutorials/incompressible/boundaryFoam/boundaryWallFunctionsProfile/0/U
@@ -1,8 +1,8 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  1.6                                   |
-|   \\  /    A nd           | Web:      http://www.OpenFOAM.org               |
+|  \\    /   O peration     | Version:  splitCyclic                           |
+|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
 FoamFile
@@ -10,37 +10,40 @@ FoamFile
     version     2.0;
     format      ascii;
     class       volVectorField;
+    location    "0";
     object      U;
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-dimensions      [0 1 -1 0 0 0 0];
+dimensions      [ 0 1 -1 0 0 0 0 ];
 
-internalField   uniform (1 0 0);
+internalField   uniform ( 1 0 0 );
 
 boundaryField
 {
-    lowerWall       
+    lowerWall
     {
         type            fixedValue;
-        value           uniform (0 0 0);
+        value           uniform ( 0 0 0 );
     }
-
-    upperWall       
+    upperWall
     {
         type            fixedValue;
-        value           uniform (0 0 0);
+        value           uniform ( 0 0 0 );
     }
-
-    frontBack
+    frontBack_half0
     {
         type            cyclic;
     }
-
-    defaultFaces    
+    defaultFaces
     {
         type            empty;
     }
+    frontBack_half1
+    {
+        type            cyclic;
+    }
 }
 
+
 // ************************************************************************* //
diff --git a/tutorials/incompressible/boundaryFoam/boundaryWallFunctionsProfile/0/epsilon b/tutorials/incompressible/boundaryFoam/boundaryWallFunctionsProfile/0/epsilon
index 5b6d7f698f76f16741b27760ecdc6c1cd79234ca..37c5fc7837b9c59f828f5eb54c99d9aff2f8bf13 100644
--- a/tutorials/incompressible/boundaryFoam/boundaryWallFunctionsProfile/0/epsilon
+++ b/tutorials/incompressible/boundaryFoam/boundaryWallFunctionsProfile/0/epsilon
@@ -1,7 +1,7 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  1.6                                   |
+|  \\    /   O peration     | Version:  splitCyclic                           |
 |   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
@@ -15,7 +15,7 @@ FoamFile
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-dimensions      [0 2 -3 0 0 0 0];
+dimensions      [ 0 2 -3 0 0 0 0 ];
 
 internalField   uniform 1e-08;
 
@@ -31,15 +31,18 @@ boundaryField
         type            epsilonWallFunction;
         value           uniform 1e-08;
     }
-    frontBack
+    frontBack_half0
     {
         type            cyclic;
-        value           uniform 1e-08;
     }
     defaultFaces
     {
         type            empty;
     }
+    frontBack_half1
+    {
+        type            cyclic;
+    }
 }
 
 
diff --git a/tutorials/incompressible/boundaryFoam/boundaryWallFunctionsProfile/0/k b/tutorials/incompressible/boundaryFoam/boundaryWallFunctionsProfile/0/k
index d278c05cef04184fc247738de09b461bfc25b452..be252cdb7863c231b6ef2c904095ce9e09fb1202 100644
--- a/tutorials/incompressible/boundaryFoam/boundaryWallFunctionsProfile/0/k
+++ b/tutorials/incompressible/boundaryFoam/boundaryWallFunctionsProfile/0/k
@@ -1,7 +1,7 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  1.6                                   |
+|  \\    /   O peration     | Version:  splitCyclic                           |
 |   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
@@ -15,9 +15,9 @@ FoamFile
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-dimensions      [0 2 -2 0 0 0 0];
+dimensions      [ 0 2 -2 0 0 0 0 ];
 
-internalField   uniform 0.000000001;
+internalField   uniform 1e-09;
 
 boundaryField
 {
@@ -31,15 +31,18 @@ boundaryField
         type            kqRWallFunction;
         internalField   uniform 0.1;
     }
-    frontBack
+    frontBack_half0
     {
         type            cyclic;
-        internalField   uniform 0.1;
     }
     defaultFaces
     {
         type            empty;
     }
+    frontBack_half1
+    {
+        type            cyclic;
+    }
 }
 
 
diff --git a/tutorials/incompressible/boundaryFoam/boundaryWallFunctionsProfile/0/nuTilda b/tutorials/incompressible/boundaryFoam/boundaryWallFunctionsProfile/0/nuTilda
index 38a021b100eaa1fe09bf2364e8d69e25135e27cd..1a0a5c1a46e2c9b6a7698fbd797268bf04e0629b 100644
--- a/tutorials/incompressible/boundaryFoam/boundaryWallFunctionsProfile/0/nuTilda
+++ b/tutorials/incompressible/boundaryFoam/boundaryWallFunctionsProfile/0/nuTilda
@@ -1,8 +1,8 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  1.6                                   |
-|   \\  /    A nd           | Web:      http://www.OpenFOAM.org               |
+|  \\    /   O peration     | Version:  splitCyclic                           |
+|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
 FoamFile
@@ -10,35 +10,38 @@ FoamFile
     version     2.0;
     format      ascii;
     class       volScalarField;
+    location    "0";
     object      nuTilda;
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-dimensions      [0 2 -1 0 0 0 0];
+dimensions      [ 0 2 -1 0 0 0 0 ];
 
 internalField   uniform 0;
 
 boundaryField
 {
-    lowerWall       
+    lowerWall
     {
         type            zeroGradient;
     }
-
-    upperWall       
+    upperWall
     {
         type            zeroGradient;
     }
-
-    frontBack
+    frontBack_half0
     {
         type            cyclic;
     }
-
-    defaultFaces    
+    defaultFaces
     {
         type            empty;
     }
+    frontBack_half1
+    {
+        type            cyclic;
+    }
 }
 
+
 // ************************************************************************* //
diff --git a/tutorials/incompressible/boundaryFoam/boundaryWallFunctionsProfile/0/nut b/tutorials/incompressible/boundaryFoam/boundaryWallFunctionsProfile/0/nut
index 5bcd4c4a1db7b020221531c616c9e56b26d8c2c4..986830e430429ea325ac281391ff2aa165a5356c 100644
--- a/tutorials/incompressible/boundaryFoam/boundaryWallFunctionsProfile/0/nut
+++ b/tutorials/incompressible/boundaryFoam/boundaryWallFunctionsProfile/0/nut
@@ -1,7 +1,7 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  1.6                                   |
+|  \\    /   O peration     | Version:  splitCyclic                           |
 |   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
@@ -15,7 +15,7 @@ FoamFile
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-dimensions      [0 2 -1 0 0 0 0];
+dimensions      [ 0 2 -1 0 0 0 0 ];
 
 internalField   uniform 0;
 
@@ -31,15 +31,18 @@ boundaryField
         type            nutkWallFunction;
         value           uniform 0;
     }
-    frontBack
+    frontBack_half0
     {
         type            cyclic;
-        value           uniform 0;
     }
     defaultFaces
     {
         type            empty;
     }
+    frontBack_half1
+    {
+        type            cyclic;
+    }
 }
 
 
diff --git a/tutorials/incompressible/boundaryFoam/boundaryWallFunctionsProfile/0/nut.k b/tutorials/incompressible/boundaryFoam/boundaryWallFunctionsProfile/0/nut.k
index 5bcd4c4a1db7b020221531c616c9e56b26d8c2c4..63deabe6d36826d6268b69bee97e43613b40d00d 100644
--- a/tutorials/incompressible/boundaryFoam/boundaryWallFunctionsProfile/0/nut.k
+++ b/tutorials/incompressible/boundaryFoam/boundaryWallFunctionsProfile/0/nut.k
@@ -1,7 +1,7 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  1.6                                   |
+|  \\    /   O peration     | Version:  splitCyclic                           |
 |   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
@@ -11,11 +11,11 @@ FoamFile
     format      ascii;
     class       volScalarField;
     location    "0";
-    object      nut;
+    object      nut.k;
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-dimensions      [0 2 -1 0 0 0 0];
+dimensions      [ 0 2 -1 0 0 0 0 ];
 
 internalField   uniform 0;
 
@@ -31,15 +31,18 @@ boundaryField
         type            nutkWallFunction;
         value           uniform 0;
     }
-    frontBack
+    frontBack_half0
     {
         type            cyclic;
-        value           uniform 0;
     }
     defaultFaces
     {
         type            empty;
     }
+    frontBack_half1
+    {
+        type            cyclic;
+    }
 }
 
 
diff --git a/tutorials/incompressible/boundaryFoam/boundaryWallFunctionsProfile/0/nut.spalding b/tutorials/incompressible/boundaryFoam/boundaryWallFunctionsProfile/0/nut.spalding
index 21cc8ebc19cf9a1a6f660d7f94746585bdae05d2..174b075808e8aaf0761401dd55df13a58e7a3166 100644
--- a/tutorials/incompressible/boundaryFoam/boundaryWallFunctionsProfile/0/nut.spalding
+++ b/tutorials/incompressible/boundaryFoam/boundaryWallFunctionsProfile/0/nut.spalding
@@ -1,7 +1,7 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  1.6                                   |
+|  \\    /   O peration     | Version:  splitCyclic                           |
 |   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
@@ -11,11 +11,11 @@ FoamFile
     format      ascii;
     class       volScalarField;
     location    "0";
-    object      nut;
+    object      nut.spalding;
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-dimensions      [0 2 -1 0 0 0 0];
+dimensions      [ 0 2 -1 0 0 0 0 ];
 
 internalField   uniform 0;
 
@@ -31,15 +31,18 @@ boundaryField
         type            nutUSpaldingWallFunction;
         value           uniform 0;
     }
-    frontBack
+    frontBack_half0
     {
         type            cyclic;
-        value           uniform 0;
     }
     defaultFaces
     {
         type            empty;
     }
+    frontBack_half1
+    {
+        type            cyclic;
+    }
 }
 
 
diff --git a/tutorials/incompressible/boundaryFoam/boundaryWallFunctionsProfile/0/omega b/tutorials/incompressible/boundaryFoam/boundaryWallFunctionsProfile/0/omega
index 75b8cd335bae6a37a31959c89d59b51b83034cfe..948c7e240928bd919bc67c8b98041dd68658ce47 100644
--- a/tutorials/incompressible/boundaryFoam/boundaryWallFunctionsProfile/0/omega
+++ b/tutorials/incompressible/boundaryFoam/boundaryWallFunctionsProfile/0/omega
@@ -1,7 +1,7 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  1.6                                   |
+|  \\    /   O peration     | Version:  splitCyclic                           |
 |   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
@@ -15,7 +15,7 @@ FoamFile
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-dimensions      [0 0 -1 0 0 0 0];
+dimensions      [ 0 0 -1 0 0 0 0 ];
 
 internalField   uniform 1111.11;
 
@@ -31,15 +31,18 @@ boundaryField
         type            omegaWallFunction;
         value           uniform 1111.11;
     }
-    frontBack
+    frontBack_half0
     {
         type            cyclic;
-        value           uniform 1111.11;
     }
     defaultFaces
     {
         type            empty;
     }
+    frontBack_half1
+    {
+        type            cyclic;
+    }
 }
 
 
diff --git a/tutorials/incompressible/boundaryFoam/boundaryWallFunctionsProfile/constant/polyMesh/boundary b/tutorials/incompressible/boundaryFoam/boundaryWallFunctionsProfile/constant/polyMesh/boundary
index 34af32827c52f64f9c0f99296856c5d408b17d70..0c4f64d3e0c3c3f0e927b0265f9bda2334208ef3 100644
--- a/tutorials/incompressible/boundaryFoam/boundaryWallFunctionsProfile/constant/polyMesh/boundary
+++ b/tutorials/incompressible/boundaryFoam/boundaryWallFunctionsProfile/constant/polyMesh/boundary
@@ -1,7 +1,7 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  dev                                   |
+|  \\    /   O peration     | Version:  splitCyclic                           |
 |   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
@@ -15,7 +15,7 @@ FoamFile
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-4
+5
 (
     lowerWall
     {
@@ -29,12 +29,19 @@ FoamFile
         nFaces          1;
         startFace       80;
     }
-    frontBack
+    frontBack_half0
     {
         type            cyclic;
-        nFaces          160;
+        nFaces          80;
         startFace       81;
-        featureCos      0.9;
+        neighbourPatch  frontBack_half1;
+    }
+    frontBack_half1
+    {
+        type            cyclic;
+        nFaces          80;
+        startFace       161;
+        neighbourPatch  frontBack_half0;
     }
     defaultFaces
     {
diff --git a/tutorials/incompressible/channelFoam/channel395/0.org/B b/tutorials/incompressible/channelFoam/channel395/0.org/B
index 5d176ac6f6d34f21e43318c68e1825fe8df8e5ed..afb27554914d6201e4d48f2f5cc4e46765f42311 100644
--- a/tutorials/incompressible/channelFoam/channel395/0.org/B
+++ b/tutorials/incompressible/channelFoam/channel395/0.org/B
@@ -1,8 +1,8 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  1.6                                   |
-|   \\  /    A nd           | Web:      http://www.OpenFOAM.org               |
+|  \\    /   O peration     | Version:  splitCyclic                           |
+|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
 FoamFile
@@ -10,45 +10,58 @@ FoamFile
     version     2.0;
     format      ascii;
     class       volTensorField;
+    location    "1";
     object      B;
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-dimensions      [0 2 -2 0 0 0 0];
+dimensions      [ 0 2 -2 0 0 0 0 ];
 
-internalField   uniform (0 0 0 0 0 0 0 0 0);
+internalField   uniform ( 0 0 0 0 0 0 0 0 0 );
 
 boundaryField
 {
-    bottomWall      
+    bottomWall
     {
         type            zeroGradient;
     }
-
-    topWall         
+    topWall
     {
         type            zeroGradient;
     }
-
-    sides1          
+    sides1_half0
     {
         type            cyclic;
     }
-
-    sides2          
+    sides2_half0
     {
         type            cyclic;
     }
-
-    inout1          
+    inout1_half0
     {
         type            cyclic;
     }
-
-    inout2          
+    inout2_half0
+    {
+        type            cyclic;
+    }
+    sides2_half1
+    {
+        type            cyclic;
+    }
+    sides1_half1
+    {
+        type            cyclic;
+    }
+    inout1_half1
+    {
+        type            cyclic;
+    }
+    inout2_half1
     {
         type            cyclic;
     }
 }
 
+
 // ************************************************************************* //
diff --git a/tutorials/incompressible/channelFoam/channel395/0.org/U b/tutorials/incompressible/channelFoam/channel395/0.org/U
index c58accba92203922fb0976260c0a753c8b42d750..77aea5e8f061ddf491b308af126d7ad31e05cec3 100644
--- a/tutorials/incompressible/channelFoam/channel395/0.org/U
+++ b/tutorials/incompressible/channelFoam/channel395/0.org/U
@@ -1,8 +1,8 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  1.6                                   |
-|   \\  /    A nd           | Web:      http://www.OpenFOAM.org               |
+|  \\    /   O peration     | Version:  splitCyclic                           |
+|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
 FoamFile
@@ -10,47 +10,60 @@ FoamFile
     version     2.0;
     format      ascii;
     class       volVectorField;
+    location    "1";
     object      U;
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-dimensions      [0 1 -1 0 0 0 0];
+dimensions      [ 0 1 -1 0 0 0 0 ];
 
-internalField   uniform (0.1335 0 0);
+internalField   uniform ( 0.1335 0 0 );
 
 boundaryField
 {
-    bottomWall      
+    bottomWall
     {
         type            fixedValue;
-        value           uniform (0 0 0);
+        value           uniform ( 0 0 0 );
     }
-
-    topWall         
+    topWall
     {
         type            fixedValue;
-        value           uniform (0 0 0);
+        value           uniform ( 0 0 0 );
     }
-
-    sides1          
+    sides1_half0
     {
         type            cyclic;
     }
-
-    sides2          
+    sides2_half0
     {
         type            cyclic;
     }
-
-    inout1          
+    inout1_half0
     {
         type            cyclic;
     }
-
-    inout2          
+    inout2_half0
+    {
+        type            cyclic;
+    }
+    sides2_half1
+    {
+        type            cyclic;
+    }
+    sides1_half1
+    {
+        type            cyclic;
+    }
+    inout1_half1
+    {
+        type            cyclic;
+    }
+    inout2_half1
     {
         type            cyclic;
     }
 }
 
+
 // ************************************************************************* //
diff --git a/tutorials/incompressible/channelFoam/channel395/0.org/k b/tutorials/incompressible/channelFoam/channel395/0.org/k
index 8fc33b69f1e4c000ecdf7a3c5fd3520b0ad2c5a7..c2e41f797b29a0f4aaecfeb4e9b9adf0db13bc29 100644
--- a/tutorials/incompressible/channelFoam/channel395/0.org/k
+++ b/tutorials/incompressible/channelFoam/channel395/0.org/k
@@ -1,8 +1,8 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  1.6                                   |
-|   \\  /    A nd           | Web:      http://www.OpenFOAM.org               |
+|  \\    /   O peration     | Version:  splitCyclic                           |
+|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
 FoamFile
@@ -10,47 +10,60 @@ FoamFile
     version     2.0;
     format      ascii;
     class       volScalarField;
+    location    "1";
     object      k;
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-dimensions      [0 2 -2 0 0 0 0];
+dimensions      [ 0 2 -2 0 0 0 0 ];
 
 internalField   uniform 0;
 
 boundaryField
 {
-    bottomWall      
+    bottomWall
     {
         type            fixedValue;
         value           uniform 0;
     }
-
-    topWall         
+    topWall
     {
         type            fixedValue;
         value           uniform 0;
     }
-
-    sides1          
+    sides1_half0
     {
         type            cyclic;
     }
-
-    sides2          
+    sides2_half0
     {
         type            cyclic;
     }
-
-    inout1          
+    inout1_half0
     {
         type            cyclic;
     }
-
-    inout2          
+    inout2_half0
+    {
+        type            cyclic;
+    }
+    sides2_half1
+    {
+        type            cyclic;
+    }
+    sides1_half1
+    {
+        type            cyclic;
+    }
+    inout1_half1
+    {
+        type            cyclic;
+    }
+    inout2_half1
     {
         type            cyclic;
     }
 }
 
+
 // ************************************************************************* //
diff --git a/tutorials/incompressible/channelFoam/channel395/0.org/nuSgs b/tutorials/incompressible/channelFoam/channel395/0.org/nuSgs
index 0ee721ac1aed324cf03ff644a7700fadbbf091a3..0779277fe261e66618f54f61410bce9eaa42564d 100644
--- a/tutorials/incompressible/channelFoam/channel395/0.org/nuSgs
+++ b/tutorials/incompressible/channelFoam/channel395/0.org/nuSgs
@@ -1,8 +1,8 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  1.6                                   |
-|   \\  /    A nd           | Web:      http://www.OpenFOAM.org               |
+|  \\    /   O peration     | Version:  splitCyclic                           |
+|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
 FoamFile
@@ -10,45 +10,58 @@ FoamFile
     version     2.0;
     format      ascii;
     class       volScalarField;
+    location    "1";
     object      nuSgs;
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-dimensions      [0 2 -1 0 0 0 0];
+dimensions      [ 0 2 -1 0 0 0 0 ];
 
 internalField   uniform 0;
 
 boundaryField
 {
-    bottomWall      
+    bottomWall
     {
         type            zeroGradient;
     }
-
-    topWall         
+    topWall
     {
         type            zeroGradient;
     }
-
-    sides1          
+    sides1_half0
     {
         type            cyclic;
     }
-
-    sides2          
+    sides2_half0
     {
         type            cyclic;
     }
-
-    inout1          
+    inout1_half0
     {
         type            cyclic;
     }
-
-    inout2          
+    inout2_half0
+    {
+        type            cyclic;
+    }
+    sides2_half1
+    {
+        type            cyclic;
+    }
+    sides1_half1
+    {
+        type            cyclic;
+    }
+    inout1_half1
+    {
+        type            cyclic;
+    }
+    inout2_half1
     {
         type            cyclic;
     }
 }
 
+
 // ************************************************************************* //
diff --git a/tutorials/incompressible/channelFoam/channel395/0.org/nuTilda b/tutorials/incompressible/channelFoam/channel395/0.org/nuTilda
index a6d88adfbbaefb7d061c35378eb9f0f11413966c..af18403bb51ddce2dc18a68d0f5c1bad8fca4687 100644
--- a/tutorials/incompressible/channelFoam/channel395/0.org/nuTilda
+++ b/tutorials/incompressible/channelFoam/channel395/0.org/nuTilda
@@ -1,8 +1,8 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  1.6                                   |
-|   \\  /    A nd           | Web:      http://www.OpenFOAM.org               |
+|  \\    /   O peration     | Version:  splitCyclic                           |
+|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
 FoamFile
@@ -10,47 +10,60 @@ FoamFile
     version     2.0;
     format      ascii;
     class       volScalarField;
+    location    "1";
     object      nuTilda;
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-dimensions      [0 2 -1 0 0 0 0];
+dimensions      [ 0 2 -1 0 0 0 0 ];
 
 internalField   uniform 0;
 
 boundaryField
 {
-    bottomWall      
+    bottomWall
     {
         type            fixedValue;
         value           uniform 0;
     }
-
-    topWall         
+    topWall
     {
         type            fixedValue;
         value           uniform 0;
     }
-
-    sides1          
+    sides1_half0
     {
         type            cyclic;
     }
-
-    sides2          
+    sides2_half0
     {
         type            cyclic;
     }
-
-    inout1          
+    inout1_half0
     {
         type            cyclic;
     }
-
-    inout2          
+    inout2_half0
+    {
+        type            cyclic;
+    }
+    sides2_half1
+    {
+        type            cyclic;
+    }
+    sides1_half1
+    {
+        type            cyclic;
+    }
+    inout1_half1
+    {
+        type            cyclic;
+    }
+    inout2_half1
     {
         type            cyclic;
     }
 }
 
+
 // ************************************************************************* //
diff --git a/tutorials/incompressible/channelFoam/channel395/0.org/p b/tutorials/incompressible/channelFoam/channel395/0.org/p
index 3dcd0ff8818f1965e6db1bbb1d0593cc4130dfda..4c9f41f7f4218718bf315459596c7355cfb27ac4 100644
--- a/tutorials/incompressible/channelFoam/channel395/0.org/p
+++ b/tutorials/incompressible/channelFoam/channel395/0.org/p
@@ -1,8 +1,8 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  1.6                                   |
-|   \\  /    A nd           | Web:      http://www.OpenFOAM.org               |
+|  \\    /   O peration     | Version:  splitCyclic                           |
+|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
 FoamFile
@@ -10,45 +10,58 @@ FoamFile
     version     2.0;
     format      ascii;
     class       volScalarField;
+    location    "1";
     object      p;
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-dimensions      [0 2 -2 0 0 0 0];
+dimensions      [ 0 2 -2 0 0 0 0 ];
 
 internalField   uniform 0;
 
 boundaryField
 {
-    bottomWall      
+    bottomWall
     {
         type            zeroGradient;
     }
-
-    topWall         
+    topWall
     {
         type            zeroGradient;
     }
-
-    sides1          
+    sides1_half0
     {
         type            cyclic;
     }
-
-    sides2          
+    sides2_half0
     {
         type            cyclic;
     }
-
-    inout1          
+    inout1_half0
     {
         type            cyclic;
     }
-
-    inout2          
+    inout2_half0
+    {
+        type            cyclic;
+    }
+    sides2_half1
+    {
+        type            cyclic;
+    }
+    sides1_half1
+    {
+        type            cyclic;
+    }
+    inout1_half1
+    {
+        type            cyclic;
+    }
+    inout2_half1
     {
         type            cyclic;
     }
 }
 
+
 // ************************************************************************* //
diff --git a/tutorials/incompressible/channelFoam/channel395/0/B.gz b/tutorials/incompressible/channelFoam/channel395/0/B.gz
index 8f0c76a0d0fd9df8f698f0fd0339ff616d3f91a5..20acb0941ebd031c8a7d6e1e7179f18df228b86b 100644
Binary files a/tutorials/incompressible/channelFoam/channel395/0/B.gz and b/tutorials/incompressible/channelFoam/channel395/0/B.gz differ
diff --git a/tutorials/incompressible/channelFoam/channel395/0/U.gz b/tutorials/incompressible/channelFoam/channel395/0/U.gz
index 8d760d6bf3b665930b73373fb25d238798439920..2a35b7da6c60a3adfd2dde3b6af9553ab4ee34e9 100644
Binary files a/tutorials/incompressible/channelFoam/channel395/0/U.gz and b/tutorials/incompressible/channelFoam/channel395/0/U.gz differ
diff --git a/tutorials/incompressible/channelFoam/channel395/0/k.gz b/tutorials/incompressible/channelFoam/channel395/0/k.gz
index 8764beb118e16f4fd336ab3824ebcef0786bd26c..dc3f5d446e05afeb9d8873f7d910f61747819a69 100644
Binary files a/tutorials/incompressible/channelFoam/channel395/0/k.gz and b/tutorials/incompressible/channelFoam/channel395/0/k.gz differ
diff --git a/tutorials/incompressible/channelFoam/channel395/0/nuSgs.gz b/tutorials/incompressible/channelFoam/channel395/0/nuSgs.gz
index b35b5e290b8dd0cea21c207f4a60dfbd2cbb4808..7c05e74de9f71cf1d5853ab5496bae46aa9d785d 100644
Binary files a/tutorials/incompressible/channelFoam/channel395/0/nuSgs.gz and b/tutorials/incompressible/channelFoam/channel395/0/nuSgs.gz differ
diff --git a/tutorials/incompressible/channelFoam/channel395/0/nuTilda.gz b/tutorials/incompressible/channelFoam/channel395/0/nuTilda.gz
index fce239f5205458acc00a6d3b6d0a930d0c282e7d..397113a510c2d3fc5adf7a6c6ef89ce9f69e7faf 100644
Binary files a/tutorials/incompressible/channelFoam/channel395/0/nuTilda.gz and b/tutorials/incompressible/channelFoam/channel395/0/nuTilda.gz differ
diff --git a/tutorials/incompressible/channelFoam/channel395/0/p.gz b/tutorials/incompressible/channelFoam/channel395/0/p.gz
index e370a3649721eba302b5283a7509f9e6bce2e273..c34acaeab415a66406e392f6e55460a3f367e2f3 100644
Binary files a/tutorials/incompressible/channelFoam/channel395/0/p.gz and b/tutorials/incompressible/channelFoam/channel395/0/p.gz differ
diff --git a/tutorials/incompressible/channelFoam/channel395/constant/polyMesh/blockMeshDict b/tutorials/incompressible/channelFoam/channel395/constant/polyMesh/blockMeshDict
index 9eec7155e5d714d5e919656510296602f0430b1f..57e0203eca9f9125040252d07abf0b20257ce6d1 100644
--- a/tutorials/incompressible/channelFoam/channel395/constant/polyMesh/blockMeshDict
+++ b/tutorials/incompressible/channelFoam/channel395/constant/polyMesh/blockMeshDict
@@ -42,36 +42,70 @@ edges
 (
 );
 
-patches         
+boundary         
 (
-    wall bottomWall 
-    (
-        (0 1 7 6)
-    )
-    wall topWall 
-    (
-        (4 10 11 5)
-    )
-    cyclic sides1 
-    (
-        (0 2 3 1)
-        (6 7 9 8)
-    )
-    cyclic sides2 
-    (
-        (2 4 5 3)
-        (8 9 11 10)
-    )
-    cyclic inout1 
-    (
-        (1 3 9 7)
-        (0 6 8 2)
-    )
-    cyclic inout2 
-    (
-        (3 5 11 9)
-        (2 8 10 4)
-    )
+    bottomWall
+    {
+        type            wall;
+        faces           ((0 1 7 6));
+    }
+    topWall
+    {
+        type            wall;
+        faces           ((4 10 11 5));
+    }
+
+    sides1_half0
+    {
+        type            cyclic;
+        neighbourPatch  sides1_half1;
+        faces           ((0 2 3 1));
+    }
+    sides1_half1
+    {
+        type            cyclic;
+        neighbourPatch  sides1_half0;
+        faces           ((6 7 9 8));
+    }
+
+    sides2_half0
+    {
+        type            cyclic;
+        neighbourPatch  sides2_half1;
+        faces           ((2 4 5 3));
+    }
+    sides2_half1
+    {
+        type            cyclic;
+        neighbourPatch  sides2_half0;
+        faces           ((8 9 11 10));
+    }
+
+    inout1_half0
+    {
+        type            cyclic;
+        neighbourPatch  inout1_half1;
+        faces           ((1 3 9 7));
+    }
+    inout1_half1
+    {
+        type            cyclic;
+        neighbourPatch  inout1_half0;
+        faces           ((0 6 8 2));
+    }
+
+    inout2_half0
+    {
+        type            cyclic;
+        neighbourPatch  inout2_half1;
+        faces           ((3 5 11 9));
+    }
+    inout2_half1
+    {
+        type            cyclic;
+        neighbourPatch  inout2_half0;
+        faces           ((2 8 10 4));
+    }
 );
 
 mergePatchPairs
diff --git a/tutorials/incompressible/channelFoam/channel395/constant/polyMesh/boundary b/tutorials/incompressible/channelFoam/channel395/constant/polyMesh/boundary
deleted file mode 100644
index 99406517bfb287df344dc1e5bc6c5e0274b6d564..0000000000000000000000000000000000000000
--- a/tutorials/incompressible/channelFoam/channel395/constant/polyMesh/boundary
+++ /dev/null
@@ -1,62 +0,0 @@
-/*--------------------------------*- C++ -*----------------------------------*\
-| =========                 |                                                 |
-| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  1.6                                   |
-|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
-|    \\/     M anipulation  |                                                 |
-\*---------------------------------------------------------------------------*/
-FoamFile
-{
-    version     2.0;
-    format      ascii;
-    class       polyBoundaryMesh;
-    location    "constant/polyMesh";
-    object      boundary;
-}
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-6
-(
-    bottomWall
-    {
-        type            wall;
-        nFaces          1200;
-        startFace       175300;
-    }
-    topWall
-    {
-        type            wall;
-        nFaces          1200;
-        startFace       176500;
-    }
-    sides1
-    {
-        type            cyclic;
-        nFaces          2000;
-        startFace       177700;
-        featureCos      0.9;
-    }
-    sides2
-    {
-        type            cyclic;
-        nFaces          2000;
-        startFace       179700;
-        featureCos      0.9;
-    }
-    inout1
-    {
-        type            cyclic;
-        nFaces          1500;
-        startFace       181700;
-        featureCos      0.9;
-    }
-    inout2
-    {
-        type            cyclic;
-        nFaces          1500;
-        startFace       183200;
-        featureCos      0.9;
-    }
-)
-
-// ************************************************************************* //
diff --git a/tutorials/incompressible/icoFoam/cavity/constant/polyMesh/blockMeshDict b/tutorials/incompressible/icoFoam/cavity/constant/polyMesh/blockMeshDict
index f59fe5c528da7372e7fba0dc6b4a20c2f8b5ab4e..eda42b9602456c3983b45958ab0f047bfa3d4cd2 100644
--- a/tutorials/incompressible/icoFoam/cavity/constant/polyMesh/blockMeshDict
+++ b/tutorials/incompressible/icoFoam/cavity/constant/polyMesh/blockMeshDict
@@ -37,23 +37,36 @@ edges
 (
 );
 
-patches         
+boundary
 (
-    wall movingWall 
-    (
-        (3 7 6 2)
-    )
-    wall fixedWalls 
-    (
-        (0 4 7 3)
-        (2 6 5 1)
-        (1 5 4 0)
-    )
-    empty frontAndBack 
-    (
-        (0 3 2 1)
-        (4 5 6 7)
-    )
+
+    movingWall 
+    {
+        type wall;
+        faces
+        (
+            (3 7 6 2)
+        );
+    }
+    fixedWalls 
+    {
+        type wall;
+        faces
+        (
+            (0 4 7 3)
+            (2 6 5 1)
+            (1 5 4 0)
+        );
+    }
+    frontAndBack 
+    {
+        type empty;
+        faces
+        (
+            (0 3 2 1)
+            (4 5 6 7)
+        );
+    }
 );
 
 mergePatchPairs 
diff --git a/tutorials/incompressible/icoFoam/cavity/constant/polyMesh/boundary b/tutorials/incompressible/icoFoam/cavity/constant/polyMesh/boundary
index 8947c6cace9751ecd3b53633e53e7eb55ad10789..7cd893d8ae53136aac19df8242dd3406cb080b69 100644
--- a/tutorials/incompressible/icoFoam/cavity/constant/polyMesh/boundary
+++ b/tutorials/incompressible/icoFoam/cavity/constant/polyMesh/boundary
@@ -1,7 +1,7 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  1.6                                   |
+|  \\    /   O peration     | Version:  splitCyclic                           |
 |   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
diff --git a/tutorials/incompressible/pimpleFoam/t-junction-with-fan/0/U b/tutorials/incompressible/pimpleFoam/t-junction-with-fan/0/U
index 8b3863aff9ee75866d55618473a8c18a4366f645..749fb95b703acfd431ea31472304ee3f933afffb 100644
--- a/tutorials/incompressible/pimpleFoam/t-junction-with-fan/0/U
+++ b/tutorials/incompressible/pimpleFoam/t-junction-with-fan/0/U
@@ -1,8 +1,8 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  1.6                                   |
-|   \\  /    A nd           | Web:      http://www.OpenFOAM.org               |
+|  \\    /   O peration     | Version:  splitCyclic                           |
+|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
 FoamFile
@@ -10,50 +10,53 @@ FoamFile
     version     2.0;
     format      ascii;
     class       volVectorField;
+    location    "0";
     object      U;
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-dimensions      [0 1 -1 0 0 0 0];
+dimensions      [ 0 1 -1 0 0 0 0 ];
 
-internalField   uniform (0 0 0);
+internalField   uniform ( 0 0 0 );
 
 boundaryField
 {
     inlet
     {
         type            pressureInletOutletVelocity;
-        value           uniform (0 0 0);
+        value           uniform ( 0 0 0 );
     }
-
     outlet1
     {
         type            inletOutlet;
-        inletValue      uniform (0 0 0);
-        value           uniform (0 0 0);
+        inletValue      uniform ( 0 0 0 );
+        value           uniform ( 0 0 0 );
     }
-
     outlet2
     {
         type            inletOutlet;
-        inletValue      uniform (0 0 0);
-        value           uniform (0 0 0);
+        inletValue      uniform ( 0 0 0 );
+        value           uniform ( 0 0 0 );
     }
     baffles
     {
         type            fixedValue;
         value           uniform ( 0 0 0 );
     }
-    fan
+    fan_half0
     {
         type            cyclic;
-        value           uniform ( 0 0 0 );
     }
     defaultFaces
     {
         type            fixedValue;
-        value           uniform (0 0 0);
+        value           uniform ( 0 0 0 );
+    }
+    fan_half1
+    {
+        type            cyclic;
     }
 }
 
+
 // ************************************************************************* //
diff --git a/tutorials/incompressible/pimpleFoam/t-junction-with-fan/0/epsilon b/tutorials/incompressible/pimpleFoam/t-junction-with-fan/0/epsilon
index 35ddfed6617fe6722388c66a195947607a3568bb..638085d526370c6c29513cd658c098767804bb33 100644
--- a/tutorials/incompressible/pimpleFoam/t-junction-with-fan/0/epsilon
+++ b/tutorials/incompressible/pimpleFoam/t-junction-with-fan/0/epsilon
@@ -1,7 +1,7 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  1.6                                   |
+|  \\    /   O peration     | Version:  splitCyclic                           |
 |   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
@@ -24,7 +24,7 @@ boundaryField
     inlet
     {
         type            turbulentMixingLengthDissipationRateInlet;
-        mixingLength    0.01;       // 1cm - half channel height
+        mixingLength    0.01;
         value           uniform 1;
     }
     outlet1
@@ -33,7 +33,6 @@ boundaryField
         inletValue      uniform 1;
         value           uniform 1;
     }
-
     outlet2
     {
         type            inletOutlet;
@@ -45,16 +44,19 @@ boundaryField
         type            epsilonWallFunction;
         value           uniform 1;
     }
-    fan
+    fan_half0
     {
         type            cyclic;
-        value           uniform 1;
     }
     defaultFaces
     {
         type            epsilonWallFunction;
         value           uniform 1;
     }
+    fan_half1
+    {
+        type            cyclic;
+    }
 }
 
 
diff --git a/tutorials/incompressible/pimpleFoam/t-junction-with-fan/0/k b/tutorials/incompressible/pimpleFoam/t-junction-with-fan/0/k
index e87a5855d2cf51fe91b10aaf4de295e5377ad5c0..b0af77f38269d6d743296723db12d31f3ac79a2a 100644
--- a/tutorials/incompressible/pimpleFoam/t-junction-with-fan/0/k
+++ b/tutorials/incompressible/pimpleFoam/t-junction-with-fan/0/k
@@ -1,7 +1,7 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  1.6                                   |
+|  \\    /   O peration     | Version:  splitCyclic                           |
 |   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
@@ -24,7 +24,7 @@ boundaryField
     inlet
     {
         type            turbulentIntensityKineticEnergyInlet;
-        intensity       0.05;       // 5% turbulent intensity
+        intensity       0.05;
         value           uniform 1;
     }
     outlet1
@@ -33,7 +33,6 @@ boundaryField
         inletValue      uniform 1;
         value           uniform 1;
     }
-
     outlet2
     {
         type            inletOutlet;
@@ -45,17 +44,19 @@ boundaryField
         type            kqRWallFunction;
         value           uniform 1;
     }
-    fan
+    fan_half0
     {
         type            cyclic;
-        value           uniform 1;
     }
-
     defaultFaces
     {
         type            kqRWallFunction;
         value           uniform 1;
     }
+    fan_half1
+    {
+        type            cyclic;
+    }
 }
 
 
diff --git a/tutorials/incompressible/pimpleFoam/t-junction-with-fan/0/nuTilda b/tutorials/incompressible/pimpleFoam/t-junction-with-fan/0/nuTilda
index ff51eab08cf73307d699f0f4d70261a9094c11ce..14f47a7b67a3392dcbe1fe757e2c57fe0d95d8cf 100644
--- a/tutorials/incompressible/pimpleFoam/t-junction-with-fan/0/nuTilda
+++ b/tutorials/incompressible/pimpleFoam/t-junction-with-fan/0/nuTilda
@@ -1,8 +1,8 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  1.6                                   |
-|   \\  /    A nd           | Web:      http://www.OpenFOAM.org               |
+|  \\    /   O peration     | Version:  splitCyclic                           |
+|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
 FoamFile
@@ -10,11 +10,12 @@ FoamFile
     version     2.0;
     format      ascii;
     class       volScalarField;
+    location    "0";
     object      nuTilda;
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-dimensions      [0 2 -1 0 0 0 0];
+dimensions      [ 0 2 -1 0 0 0 0 ];
 
 internalField   uniform 0;
 
@@ -24,12 +25,10 @@ boundaryField
     {
         type            zeroGradient;
     }
-
     outlet1
     {
         type            zeroGradient;
     }
-
     outlet2
     {
         type            zeroGradient;
@@ -38,15 +37,19 @@ boundaryField
     {
         type            zeroGradient;
     }
-    fan
+    fan_half0
     {
         type            cyclic;
-        value           uniform 0;
     }
     defaultFaces
     {
         type            zeroGradient;
     }
+    fan_half1
+    {
+        type            cyclic;
+    }
 }
 
+
 // ************************************************************************* //
diff --git a/tutorials/incompressible/pimpleFoam/t-junction-with-fan/0/nut b/tutorials/incompressible/pimpleFoam/t-junction-with-fan/0/nut
index 570f1f90ac5188e944d686866217964790e2118d..cd1e41281fe315710771c71eb3e67e421a079bea 100644
--- a/tutorials/incompressible/pimpleFoam/t-junction-with-fan/0/nut
+++ b/tutorials/incompressible/pimpleFoam/t-junction-with-fan/0/nut
@@ -1,7 +1,7 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  1.6                                   |
+|  \\    /   O peration     | Version:  splitCyclic                           |
 |   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
@@ -26,13 +26,11 @@ boundaryField
         type            calculated;
         value           uniform 0;
     }
-
     outlet1
     {
         type            calculated;
         value           uniform 0;
     }
-
     outlet2
     {
         type            calculated;
@@ -43,16 +41,19 @@ boundaryField
         type            nutkWallFunction;
         value           uniform 0;
     }
-    fan
+    fan_half0
     {
         type            cyclic;
-        value           uniform 0;
     }
     defaultFaces
     {
         type            nutkWallFunction;
         value           uniform 0;
     }
+    fan_half1
+    {
+        type            cyclic;
+    }
 }
 
 
diff --git a/tutorials/incompressible/pimpleFoam/t-junction-with-fan/0/p b/tutorials/incompressible/pimpleFoam/t-junction-with-fan/0/p
index d9873e5b7a0f87d7979976f2b630a6cdcf3e26c1..14a655e690ae7667affb9bec45c8d3529c8ffd48 100644
--- a/tutorials/incompressible/pimpleFoam/t-junction-with-fan/0/p
+++ b/tutorials/incompressible/pimpleFoam/t-junction-with-fan/0/p
@@ -1,8 +1,8 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  1.6                                   |
-|   \\  /    A nd           | Web:      http://www.OpenFOAM.org               |
+|  \\    /   O peration     | Version:  splitCyclic                           |
+|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
 FoamFile
@@ -10,11 +10,12 @@ FoamFile
     version     2.0;
     format      ascii;
     class       volScalarField;
+    location    "0";
     object      p;
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-dimensions      [0 2 -2 0 0 0 0];
+dimensions      [ 0 2 -2 0 0 0 0 ];
 
 internalField   uniform 100000;
 
@@ -22,14 +23,10 @@ boundaryField
 {
     inlet
     {
-        //type            totalPressure;
-        //p0              uniform 100040;
-
         type            timeVaryingTotalPressure;
-        p0              100040; // only used for restarts
+        p0              100040;
         outOfBounds     clamp;
         fileName        "$FOAM_CASE/constant/p0vsTime";
-
         U               U;
         phi             phi;
         rho             none;
@@ -37,13 +34,11 @@ boundaryField
         gamma           1;
         value           uniform 100040;
     }
-
     outlet1
     {
         type            fixedValue;
         value           uniform 100010;
     }
-
     outlet2
     {
         type            fixedValue;
@@ -53,17 +48,25 @@ boundaryField
     {
         type            zeroGradient;
     }
-    fan
+    fan_half0
     {
         type            fan;
         patchType       cyclic;
         f               2 ( 50 -0.1 );
-        value           uniform 100000;
+        value           $internalField;
     }
     defaultFaces
     {
         type            zeroGradient;
     }
+    fan_half1
+    {
+        type            fan;
+        patchType       cyclic;
+        f               2 ( 50 -0.1 );
+        value           $internalField;
+    }
 }
 
+
 // ************************************************************************* //
diff --git a/tutorials/incompressible/pimpleFoam/t-junction-with-fan/Allrun b/tutorials/incompressible/pimpleFoam/t-junction-with-fan/Allrun
index 54e4a04eddd818478efed08a70fde5c832f18897..0d96a34fc9adf6cff732d973e403b97d37bc8b8c 100755
--- a/tutorials/incompressible/pimpleFoam/t-junction-with-fan/Allrun
+++ b/tutorials/incompressible/pimpleFoam/t-junction-with-fan/Allrun
@@ -16,12 +16,14 @@ unset FOAM_SETNAN
 
 # Add cyclic baffles for fan
 runApplication setSet -batch selectCyclics.setSet
-runApplication createBaffles cyclicFaces fan -overwrite
+#runApplication createBaffles cyclicFaces '(fan_half0 fan_half1)' -overwrite
+createBaffles cyclicFaces '(fan_half0 fan_half1)' -overwrite > log.createBaffles 2>&1
 
 # Add wall baffles
 rm log.setSet
 runApplication setSet -batch selectBaffles.setSet
 rm log.createBaffles
-runApplication createBaffles baffleFaces baffles -overwrite
+#runApplication createBaffles baffleFaces '(baffles baffles)' -overwrite
+createBaffles baffleFaces '(baffles baffles)' -overwrite > log.createBaffles 2>&1
 
 runApplication $application
diff --git a/tutorials/incompressible/pimpleFoam/t-junction-with-fan/constant/polyMesh/blockMeshDict b/tutorials/incompressible/pimpleFoam/t-junction-with-fan/constant/polyMesh/blockMeshDict
index 5e97f00deb0f66dd3126366c89d2659512dde203..288339e21a740249143ec22e4ec387ca8ba50e3b 100644
--- a/tutorials/incompressible/pimpleFoam/t-junction-with-fan/constant/polyMesh/blockMeshDict
+++ b/tutorials/incompressible/pimpleFoam/t-junction-with-fan/constant/polyMesh/blockMeshDict
@@ -84,32 +84,50 @@ edges
 (
 );
 
-patches         
-(
-    patch inlet
-    (
-        (0 10 13 3)
-    )
-
-    patch outlet1
-    (
-        (6 7 17 16)
-    )
-
-    patch outlet2
-    (
-        (8 18 19 9)
-    )
-
-    wall baffles
-    ()
-
-    cyclic fan
-    ()
-
-    wall defaultFaces
-    ()
-
+boundary
+(         
+    inlet
+    {
+        type patch;
+        faces  ((0 10 13 3));
+    }
+
+    outlet1
+    {
+        type patch;
+        faces ((6 7 17 16));
+    }
+
+    outlet2
+    {
+        type patch;
+        faces ((8 18 19 9));
+    }
+
+    baffles
+    {
+        type wall;
+        faces ();
+    }
+
+    fan_half0
+    {
+        type cyclic;
+        faces ();
+        neighbourPatch fan_half1;
+    }
+    fan_half1
+    {
+        type cyclic;
+        faces ();
+        neighbourPatch fan_half0;
+    }
+
+    defaultFaces
+    {
+        type wall;
+        faces ();
+    }
 );
 
 mergePatchPairs
diff --git a/tutorials/incompressible/pimpleFoam/t-junction-with-fan/constant/polyMesh/boundary b/tutorials/incompressible/pimpleFoam/t-junction-with-fan/constant/polyMesh/boundary
index 24c53efd55cf0afb003ec8b7b92bf27279f40aed..339de8e615a8238283370335059d580909327e4f 100644
--- a/tutorials/incompressible/pimpleFoam/t-junction-with-fan/constant/polyMesh/boundary
+++ b/tutorials/incompressible/pimpleFoam/t-junction-with-fan/constant/polyMesh/boundary
@@ -1,7 +1,7 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  dev                                   |
+|  \\    /   O peration     | Version:  splitCyclic                           |
 |   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
@@ -15,44 +15,51 @@ FoamFile
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-6
+7
 (
     inlet
     {
         type            patch;
         nFaces          25;
-        startFace       10050;
+        startFace       10025;
     }
     outlet1
     {
         type            patch;
         nFaces          25;
-        startFace       10075;
+        startFace       10050;
     }
     outlet2
     {
         type            patch;
         nFaces          25;
-        startFace       10100;
+        startFace       10075;
     }
     baffles
     {
         type            wall;
-        nFaces          0;
-        startFace       10125;
+        nFaces          32;
+        startFace       10100;
+    }
+    fan_half0
+    {
+        type            cyclic;
+        nFaces          9;
+        startFace       10132;
+        neighbourPatch  fan_half1;
     }
-    fan
+    fan_half1
     {
         type            cyclic;
-        nFaces          0;
-        startFace       10125;
-        featureCos      0.9;
+        nFaces          9;
+        startFace       10141;
+        neighbourPatch  fan_half0;
     }
     defaultFaces
     {
         type            wall;
         nFaces          3075;
-        startFace       10125;
+        startFace       10150;
     }
 )
 
diff --git a/tutorials/incompressible/simpleSRFFoam/mixer/0/Urel b/tutorials/incompressible/simpleSRFFoam/mixer/0/Urel
index 5545397bd58e12d60b04ac587250ca1a96934a91..dbf1defeadeffb3576fa714721557e8413e43a66 100644
--- a/tutorials/incompressible/simpleSRFFoam/mixer/0/Urel
+++ b/tutorials/incompressible/simpleSRFFoam/mixer/0/Urel
@@ -1,8 +1,8 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  1.6                                   |
-|   \\  /    A nd           | Web:      http://www.OpenFOAM.org               |
+|  \\    /   O peration     | Version:  splitCyclic                           |
+|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
 FoamFile
@@ -10,47 +10,49 @@ FoamFile
     version     2.0;
     format      ascii;
     class       volVectorField;
+    location    "0";
     object      Urel;
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-dimensions      [0 1 -1 0 0 0 0];
+dimensions      [ 0 1 -1 0 0 0 0 ];
 
-internalField   uniform (0 0 0);
+internalField   uniform ( 0 0 0 );
 
 boundaryField
 {
     inlet
     {
         type            SRFVelocity;
-        inletValue      uniform (0 0 -10);
+        inletValue      uniform ( 0 0 -10 );
         relative        yes;
-        value           uniform (0 0 0);
+        value           uniform ( 0 0 0 );
     }
-
     outlet
     {
         type            zeroGradient;
     }
-
     innerWall
     {
         type            fixedValue;
-        value           uniform (0 0 0);
+        value           uniform ( 0 0 0 );
     }
-
     outerWall
     {
         type            SRFVelocity;
-        inletValue      uniform (0 0 0);
+        inletValue      uniform ( 0 0 0 );
         relative        yes;
-        value           uniform (0 0 0);
+        value           uniform ( 0 0 0 );
     }
-
-    cyclic
+    cyclic_half0
+    {
+        type            cyclic;
+    }
+    cyclic_half1
     {
         type            cyclic;
     }
 }
 
+
 // ************************************************************************* //
diff --git a/tutorials/incompressible/simpleSRFFoam/mixer/0/epsilon b/tutorials/incompressible/simpleSRFFoam/mixer/0/epsilon
index 4499dbcf5af86276989d44aaa059b2e2aa8508cb..c4b875bc8acec3f1257d9bce9f2d3d874daf7065 100644
--- a/tutorials/incompressible/simpleSRFFoam/mixer/0/epsilon
+++ b/tutorials/incompressible/simpleSRFFoam/mixer/0/epsilon
@@ -1,8 +1,8 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  1.6                                   |
-|   \\  /    A nd           | Web:      http://www.OpenFOAM.org               |
+|  \\    /   O peration     | Version:  splitCyclic                           |
+|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
 FoamFile
@@ -10,45 +10,47 @@ FoamFile
     version     2.0;
     format      ascii;
     class       volScalarField;
+    location    "0";
     object      epsilon;
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-dimensions      [0 2 -3 0 0 0 0];
+dimensions      [ 0 2 -3 0 0 0 0 ];
 
 internalField   uniform 14.855;
 
 boundaryField
 {
-    inlet           
+    inlet
     {
         type            fixedValue;
         value           uniform 14.855;
     }
-
-    outlet          
+    outlet
     {
         type            zeroGradient;
     }
-
-    innerWall       
+    innerWall
     {
         type            epsilonWallFunction;
         U               Urel;
         value           uniform 14.855;
     }
-
-    outerWall       
+    outerWall
     {
         type            epsilonWallFunction;
         U               Urel;
         value           uniform 14.855;
     }
-
-    cyclic    
+    cyclic_half0
+    {
+        type            cyclic;
+    }
+    cyclic_half1
     {
         type            cyclic;
     }
 }
 
+
 // ************************************************************************* //
diff --git a/tutorials/incompressible/simpleSRFFoam/mixer/0/k b/tutorials/incompressible/simpleSRFFoam/mixer/0/k
index 229ac266814e6fa7292fb2fd2ef71e6f5dbcdde2..5dff207809651283e148895c67f5b1a30f7e6457 100644
--- a/tutorials/incompressible/simpleSRFFoam/mixer/0/k
+++ b/tutorials/incompressible/simpleSRFFoam/mixer/0/k
@@ -1,7 +1,7 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  1.6                                   |
+|  \\    /   O peration     | Version:  splitCyclic                           |
 |   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
@@ -15,7 +15,7 @@ FoamFile
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-dimensions      [0 2 -2 0 0 0 0];
+dimensions      [ 0 2 -2 0 0 0 0 ];
 
 internalField   uniform 0.375;
 
@@ -40,7 +40,12 @@ boundaryField
         type            kqRWallFunction;
         value           uniform 0.375;
     }
-    cyclic
+    cyclic_half0
+    {
+        type            cyclic;
+        value           uniform 0.375;
+    }
+    cyclic_half1
     {
         type            cyclic;
         value           uniform 0.375;
diff --git a/tutorials/incompressible/simpleSRFFoam/mixer/0/nut b/tutorials/incompressible/simpleSRFFoam/mixer/0/nut
index 82d057a58b12618c365a34e2e0e9f02f916ff0b7..e3c05b94b67269a73838daba667077618ac3aa20 100644
--- a/tutorials/incompressible/simpleSRFFoam/mixer/0/nut
+++ b/tutorials/incompressible/simpleSRFFoam/mixer/0/nut
@@ -1,7 +1,7 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  1.6                                   |
+|  \\    /   O peration     | Version:  splitCyclic                           |
 |   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
@@ -15,7 +15,7 @@ FoamFile
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-dimensions      [0 2 -1 0 0 0 0];
+dimensions      [ 0 2 -1 0 0 0 0 ];
 
 internalField   uniform 0;
 
@@ -43,7 +43,12 @@ boundaryField
         U               Urel;
         value           uniform 0;
     }
-    cyclic
+    cyclic_half0
+    {
+        type            cyclic;
+        value           uniform 0;
+    }
+    cyclic_half1
     {
         type            cyclic;
         value           uniform 0;
diff --git a/tutorials/incompressible/simpleSRFFoam/mixer/0/omega b/tutorials/incompressible/simpleSRFFoam/mixer/0/omega
index b2f952d00c528d1374957df2d88f8e298635adf3..a7915f30b10436e470cddf6a7eee99231e057a3a 100644
--- a/tutorials/incompressible/simpleSRFFoam/mixer/0/omega
+++ b/tutorials/incompressible/simpleSRFFoam/mixer/0/omega
@@ -1,7 +1,7 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  1.6                                   |
+|  \\    /   O peration     | Version:  splitCyclic                           |
 |   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
@@ -15,7 +15,7 @@ FoamFile
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-dimensions      [0 0 -1 0 0 0 0];
+dimensions      [ 0 0 -1 0 0 0 0 ];
 
 internalField   uniform 3.5;
 
@@ -42,7 +42,12 @@ boundaryField
         U               Urel;
         value           uniform 3.5;
     }
-    cyclic
+    cyclic_half0
+    {
+        type            cyclic;
+        value           uniform 3.5;
+    }
+    cyclic_half1
     {
         type            cyclic;
         value           uniform 3.5;
diff --git a/tutorials/incompressible/simpleSRFFoam/mixer/0/p b/tutorials/incompressible/simpleSRFFoam/mixer/0/p
index 4a136a3ccc7d5a41ee83b0784f579dce4b90b9de..dfb6fe99fe26f3e27cc3596fb2763359f3c797ca 100644
--- a/tutorials/incompressible/simpleSRFFoam/mixer/0/p
+++ b/tutorials/incompressible/simpleSRFFoam/mixer/0/p
@@ -1,8 +1,8 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  1.6                                   |
-|   \\  /    A nd           | Web:      http://www.OpenFOAM.org               |
+|  \\    /   O peration     | Version:  splitCyclic                           |
+|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
 FoamFile
@@ -10,11 +10,12 @@ FoamFile
     version     2.0;
     format      ascii;
     class       volScalarField;
+    location    "0";
     object      p;
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-dimensions      [0 2 -2 0 0 0 0];
+dimensions      [ 0 2 -2 0 0 0 0 ];
 
 internalField   uniform 0;
 
@@ -24,27 +25,28 @@ boundaryField
     {
         type            zeroGradient;
     }
-
     outlet
     {
         type            fixedValue;
         value           uniform 0;
     }
-
     innerWall
     {
         type            zeroGradient;
     }
-
     outerWall
     {
         type            zeroGradient;
     }
-
-    cyclic
+    cyclic_half0
+    {
+        type            cyclic;
+    }
+    cyclic_half1
     {
         type            cyclic;
     }
 }
 
+
 // ************************************************************************* //
diff --git a/tutorials/incompressible/simpleSRFFoam/mixer/constant/polyMesh/boundary b/tutorials/incompressible/simpleSRFFoam/mixer/constant/polyMesh/boundary
index 3fff299c5a6ee14dbf30c8b018c753e9de6d2a46..9dd337f2de4b4c560bffa209470ffb53e9a012a2 100644
--- a/tutorials/incompressible/simpleSRFFoam/mixer/constant/polyMesh/boundary
+++ b/tutorials/incompressible/simpleSRFFoam/mixer/constant/polyMesh/boundary
@@ -1,7 +1,7 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  1.6                                   |
+|  \\    /   O peration     | Version:  splitCyclic                           |
 |   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
@@ -15,7 +15,7 @@ FoamFile
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-5
+6
 (
     inlet
     {
@@ -41,12 +41,19 @@ FoamFile
         nFaces          880;
         startFace       100840;
     }
-    cyclic
+    cyclic_half0
     {
         type            cyclic;
-        nFaces          3200;
+        nFaces          1600;
         startFace       101720;
-        featureCos      0.9;
+        neighbourPatch  cyclic_half1;
+    }
+    cyclic_half1
+    {
+        type            cyclic;
+        nFaces          1600;
+        startFace       103320;
+        neighbourPatch  cyclic_half0;
     }
 )
 
diff --git a/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0.org/G b/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0.org/G
index 8fa245026686b323fd69e94e2cbf5cf1cbf49f18..e95384474bf2c2a80d77a346cd1af1a6a05c0d37 100644
--- a/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0.org/G
+++ b/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0.org/G
@@ -1,8 +1,8 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  1.6                                   |
-|   \\  /    A nd           | Web:      http://www.OpenFOAM.org               |
+|  \\    /   O peration     | Version:  splitCyclic                           |
+|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
 FoamFile
@@ -10,12 +10,12 @@ FoamFile
     version     2.0;
     format      ascii;
     class       volScalarField;
-    location    "0";
+    location    "1";
     object      G;
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-dimensions      [1 0 -3 0 0 0 0];
+dimensions      [ 1 0 -3 0 0 0 0 ];
 
 internalField   uniform 0;
 
@@ -27,6 +27,9 @@ boundaryField
         T               T;
         emissivity      1;
         value           uniform 0;
+        refValue        uniform 0;
+        refGradient     uniform 0;
+        valueFraction   uniform 0;
     }
     inlet
     {
@@ -34,25 +37,34 @@ boundaryField
         T               T;
         emissivity      1;
         value           uniform 0;
+        refValue        uniform 0;
+        refGradient     uniform 0;
+        valueFraction   uniform 0;
     }
     outlet
     {
         type            zeroGradient;
     }
-    cycLeft
+    cycLeft_half0
     {
         type            cyclic;
-        value           uniform 0;
     }
-    cycRight
+    cycRight_half0
     {
         type            cyclic;
-        value           uniform 0;
     }
     frontAndBack
     {
         type            empty;
     }
+    cycLeft_half1
+    {
+        type            cyclic;
+    }
+    cycRight_half1
+    {
+        type            cyclic;
+    }
 }
 
 
diff --git a/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0.org/H2O b/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0.org/H2O
index 11ad4763bec0b7394128f3e2ab466bc661c7d5df..b99dfc07c7c2c408559fe691cc9a184fb3841c96 100644
--- a/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0.org/H2O
+++ b/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0.org/H2O
@@ -1,8 +1,8 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  1.6                                   |
-|   \\  /    A nd           | Web:      http://www.OpenFOAM.org               |
+|  \\    /   O peration     | Version:  splitCyclic                           |
+|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
 FoamFile
@@ -10,12 +10,12 @@ FoamFile
     version     2.0;
     format      ascii;
     class       volScalarField;
-    location    "0";
+    location    "1";
     object      H2O;
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-dimensions      [0 0 0 0 0 0 0];
+dimensions      [ 0 0 0 0 0 0 0 ];
 
 internalField   uniform 0;
 
@@ -34,20 +34,26 @@ boundaryField
     {
         type            zeroGradient;
     }
-    cycLeft
+    cycLeft_half0
     {
         type            cyclic;
-        value           uniform 0;
     }
-    cycRight
+    cycRight_half0
     {
         type            cyclic;
-        value           uniform 0;
     }
     frontAndBack
     {
         type            empty;
     }
+    cycLeft_half1
+    {
+        type            cyclic;
+    }
+    cycRight_half1
+    {
+        type            cyclic;
+    }
 }
 
 
diff --git a/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0.org/N2 b/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0.org/N2
index 9335ae313af2b8e4d3dea6522d7a9f8c6d50c8b7..bac9361933be71af80f27c72dc34525f5fd00a6a 100644
--- a/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0.org/N2
+++ b/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0.org/N2
@@ -1,8 +1,8 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  1.6                                   |
-|   \\  /    A nd           | Web:      http://www.OpenFOAM.org               |
+|  \\    /   O peration     | Version:  splitCyclic                           |
+|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
 FoamFile
@@ -10,12 +10,12 @@ FoamFile
     version     2.0;
     format      ascii;
     class       volScalarField;
-    location    "0";
+    location    "1";
     object      N2;
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-dimensions      [0 0 0 0 0 0 0];
+dimensions      [ 0 0 0 0 0 0 0 ];
 
 internalField   uniform 0.79;
 
@@ -34,20 +34,26 @@ boundaryField
     {
         type            zeroGradient;
     }
-    cycLeft
+    cycLeft_half0
     {
         type            cyclic;
-        value           uniform 0.79;
     }
-    cycRight
+    cycRight_half0
     {
         type            cyclic;
-        value           uniform 0.79;
     }
     frontAndBack
     {
         type            empty;
     }
+    cycLeft_half1
+    {
+        type            cyclic;
+    }
+    cycRight_half1
+    {
+        type            cyclic;
+    }
 }
 
 
diff --git a/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0.org/O2 b/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0.org/O2
index 8d4f9c576f9b6e0353c7abbbb00105f49f1837da..7fa3e2e4886fa4d98bc2ab713e5044f1ec50b332 100644
--- a/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0.org/O2
+++ b/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0.org/O2
@@ -1,8 +1,8 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  1.6                                   |
-|   \\  /    A nd           | Web:      http://www.OpenFOAM.org               |
+|  \\    /   O peration     | Version:  splitCyclic                           |
+|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
 FoamFile
@@ -10,12 +10,12 @@ FoamFile
     version     2.0;
     format      ascii;
     class       volScalarField;
-    location    "0";
+    location    "1";
     object      O2;
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-dimensions      [0 0 0 0 0 0 0];
+dimensions      [ 0 0 0 0 0 0 0 ];
 
 internalField   uniform 0.21;
 
@@ -34,20 +34,26 @@ boundaryField
     {
         type            zeroGradient;
     }
-    cycLeft
+    cycLeft_half0
     {
         type            cyclic;
-        value           uniform 0.21;
     }
-    cycRight
+    cycRight_half0
     {
         type            cyclic;
-        value           uniform 0.21;
     }
     frontAndBack
     {
         type            empty;
     }
+    cycLeft_half1
+    {
+        type            cyclic;
+    }
+    cycRight_half1
+    {
+        type            cyclic;
+    }
 }
 
 
diff --git a/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0.org/T b/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0.org/T
index 888a879d4002f6ba79a2066b73dea9fad221ea38..00f9fd04b862fa82cce6bc05a55c3076a4764c83 100644
--- a/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0.org/T
+++ b/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0.org/T
@@ -1,8 +1,8 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  1.6                                   |
-|   \\  /    A nd           | Web:      http://www.OpenFOAM.org               |
+|  \\    /   O peration     | Version:  splitCyclic                           |
+|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
 FoamFile
@@ -10,12 +10,12 @@ FoamFile
     version     2.0;
     format      ascii;
     class       volScalarField;
-    location    "0";
+    location    "1";
     object      T;
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-dimensions      [0 0 0 1 0 0 0];
+dimensions      [ 0 0 0 1 0 0 0 ];
 
 internalField   uniform 350;
 
@@ -35,11 +35,11 @@ boundaryField
     {
         type            zeroGradient;
     }
-    cycLeft
+    cycLeft_half0
     {
         type            cyclic;
     }
-    cycRight
+    cycRight_half0
     {
         type            cyclic;
     }
@@ -47,6 +47,14 @@ boundaryField
     {
         type            empty;
     }
+    cycLeft_half1
+    {
+        type            cyclic;
+    }
+    cycRight_half1
+    {
+        type            cyclic;
+    }
 }
 
 
diff --git a/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0.org/U b/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0.org/U
index a3d2cfe57192898c9f63bda8e47f58da111b9761..a0c6dd9ec1e2da43a15d4ab9af02f108740abb9c 100644
--- a/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0.org/U
+++ b/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0.org/U
@@ -1,8 +1,8 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  1.6                                   |
-|   \\  /    A nd           | Web:      http://www.OpenFOAM.org               |
+|  \\    /   O peration     | Version:  splitCyclic                           |
+|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
 FoamFile
@@ -10,36 +10,36 @@ FoamFile
     version     2.0;
     format      ascii;
     class       volVectorField;
-    location    "0";
+    location    "1";
     object      U;
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-dimensions      [0 1 -1 0 0 0 0];
+dimensions      [ 0 1 -1 0 0 0 0 ];
 
-internalField   uniform (0 0 0);
+internalField   uniform ( 0 0 0 );
 
 boundaryField
 {
     walls
     {
         type            fixedValue;
-        value           uniform (0 0 0);
+        value           uniform ( 0 0 0 );
     }
     inlet
     {
         type            fixedValue;
-        value           uniform (5 0 0);
+        value           uniform ( 5 0 0 );
     }
     outlet
     {
         type            zeroGradient;
     }
-    cycLeft
+    cycLeft_half0
     {
         type            cyclic;
     }
-    cycRight
+    cycRight_half0
     {
         type            cyclic;
     }
@@ -47,6 +47,14 @@ boundaryField
     {
         type            empty;
     }
+    cycLeft_half1
+    {
+        type            cyclic;
+    }
+    cycRight_half1
+    {
+        type            cyclic;
+    }
 }
 
 
diff --git a/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0.org/alphat b/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0.org/alphat
index c87862d4ae4f758cac81ec3587a619730cfee3f1..f7c1245cbf2eb1ca62a32b65c64fce3c871d48ed 100644
--- a/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0.org/alphat
+++ b/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0.org/alphat
@@ -1,7 +1,7 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  1.6                                   |
+|  \\    /   O peration     | Version:  splitCyclic                           |
 |   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
@@ -10,12 +10,12 @@ FoamFile
     version     2.0;
     format      ascii;
     class       volScalarField;
-    location    "0";
+    location    "1";
     object      alphat;
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-dimensions      [1 -1 -1 0 0 0 0];
+dimensions      [ 1 -1 -1 0 0 0 0 ];
 
 internalField   uniform 0;
 
@@ -36,20 +36,26 @@ boundaryField
         type            calculated;
         value           uniform 0;
     }
-    cycLeft
+    cycLeft_half0
     {
         type            cyclic;
-        value           uniform 0;
     }
-    cycRight
+    cycRight_half0
     {
         type            cyclic;
-        value           uniform 0;
     }
     frontAndBack
     {
         type            empty;
     }
+    cycLeft_half1
+    {
+        type            cyclic;
+    }
+    cycRight_half1
+    {
+        type            cyclic;
+    }
 }
 
 
diff --git a/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0.org/epsilon b/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0.org/epsilon
index 9a102e372abd7058195ee79ec6aa756d3dfb1a40..bb80a5e3d1dc6f8b78cf986943c05a7fe4e726db 100644
--- a/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0.org/epsilon
+++ b/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0.org/epsilon
@@ -1,7 +1,7 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  1.6                                   |
+|  \\    /   O peration     | Version:  splitCyclic                           |
 |   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
@@ -10,12 +10,12 @@ FoamFile
     version     2.0;
     format      ascii;
     class       volScalarField;
-    location    "0";
+    location    "1";
     object      epsilon;
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-dimensions      [0 2 -3 0 0 0 0];
+dimensions      [ 0 2 -3 0 0 0 0 ];
 
 internalField   uniform 0.0449;
 
@@ -35,20 +35,26 @@ boundaryField
     {
         type            zeroGradient;
     }
-    cycLeft
+    cycLeft_half0
     {
         type            cyclic;
-        value           uniform 0.0449;
     }
-    cycRight
+    cycRight_half0
     {
         type            cyclic;
-        value           uniform 0.0449;
     }
     frontAndBack
     {
         type            empty;
     }
+    cycLeft_half1
+    {
+        type            cyclic;
+    }
+    cycRight_half1
+    {
+        type            cyclic;
+    }
 }
 
 
diff --git a/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0.org/k b/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0.org/k
index 9bbfb01b910dfff0b912a52398bcd3d603059288..1b91a7d191a823124191de8c0702efaf6ad9b81c 100644
--- a/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0.org/k
+++ b/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0.org/k
@@ -1,7 +1,7 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  1.6                                   |
+|  \\    /   O peration     | Version:  splitCyclic                           |
 |   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
@@ -10,12 +10,12 @@ FoamFile
     version     2.0;
     format      ascii;
     class       volScalarField;
-    location    "0";
+    location    "1";
     object      k;
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-dimensions      [0 2 -2 0 0 0 0];
+dimensions      [ 0 2 -2 0 0 0 0 ];
 
 internalField   uniform 0.0938;
 
@@ -35,20 +35,26 @@ boundaryField
     {
         type            zeroGradient;
     }
-    cycLeft
+    cycLeft_half0
     {
         type            cyclic;
-        value           uniform 0.0938;
     }
-    cycRight
+    cycRight_half0
     {
         type            cyclic;
-        value           uniform 0.0938;
     }
     frontAndBack
     {
         type            empty;
     }
+    cycLeft_half1
+    {
+        type            cyclic;
+    }
+    cycRight_half1
+    {
+        type            cyclic;
+    }
 }
 
 
diff --git a/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0.org/mut b/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0.org/mut
index 9a7573f3f13cdc21e247c8b19a8192f41728c2a3..d3ec136050dbae710ecbe6d44625769f74ea24ad 100644
--- a/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0.org/mut
+++ b/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0.org/mut
@@ -1,7 +1,7 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  1.6                                   |
+|  \\    /   O peration     | Version:  splitCyclic                           |
 |   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
@@ -10,12 +10,12 @@ FoamFile
     version     2.0;
     format      ascii;
     class       volScalarField;
-    location    "0";
+    location    "1";
     object      mut;
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-dimensions      [1 -1 -1 0 0 0 0];
+dimensions      [ 1 -1 -1 0 0 0 0 ];
 
 internalField   uniform 0;
 
@@ -36,20 +36,26 @@ boundaryField
         type            calculated;
         value           uniform 0;
     }
-    cycLeft
+    cycLeft_half0
     {
         type            cyclic;
-        value           uniform 0;
     }
-    cycRight
+    cycRight_half0
     {
         type            cyclic;
-        value           uniform 0;
     }
     frontAndBack
     {
         type            empty;
     }
+    cycLeft_half1
+    {
+        type            cyclic;
+    }
+    cycRight_half1
+    {
+        type            cyclic;
+    }
 }
 
 
diff --git a/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0.org/p b/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0.org/p
index 25b0c984e25542c647babb48ada18ea0463ae4d5..ba5cc3d6069c551a5fe104ef7c3693e0e3c7e38d 100644
--- a/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0.org/p
+++ b/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0.org/p
@@ -1,8 +1,8 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  1.6                                   |
-|   \\  /    A nd           | Web:      http://www.OpenFOAM.org               |
+|  \\    /   O peration     | Version:  splitCyclic                           |
+|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
 FoamFile
@@ -10,12 +10,12 @@ FoamFile
     version     2.0;
     format      ascii;
     class       volScalarField;
-    location    "0";
+    location    "1";
     object      p;
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-dimensions      [1 -1 -2 0 0 0 0];
+dimensions      [ 1 -1 -2 0 0 0 0 ];
 
 internalField   uniform 100000;
 
@@ -34,20 +34,26 @@ boundaryField
         type            fixedValue;
         value           uniform 100000;
     }
-    cycLeft
+    cycLeft_half0
     {
         type            cyclic;
-        value           uniform 100000;
     }
-    cycRight
+    cycRight_half0
     {
         type            cyclic;
-        value           uniform 100000;
     }
     frontAndBack
     {
         type            empty;
     }
+    cycLeft_half1
+    {
+        type            cyclic;
+    }
+    cycRight_half1
+    {
+        type            cyclic;
+    }
 }
 
 
diff --git a/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0/G b/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0/G
index 8fa245026686b323fd69e94e2cbf5cf1cbf49f18..e95384474bf2c2a80d77a346cd1af1a6a05c0d37 100644
--- a/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0/G
+++ b/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0/G
@@ -1,8 +1,8 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  1.6                                   |
-|   \\  /    A nd           | Web:      http://www.OpenFOAM.org               |
+|  \\    /   O peration     | Version:  splitCyclic                           |
+|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
 FoamFile
@@ -10,12 +10,12 @@ FoamFile
     version     2.0;
     format      ascii;
     class       volScalarField;
-    location    "0";
+    location    "1";
     object      G;
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-dimensions      [1 0 -3 0 0 0 0];
+dimensions      [ 1 0 -3 0 0 0 0 ];
 
 internalField   uniform 0;
 
@@ -27,6 +27,9 @@ boundaryField
         T               T;
         emissivity      1;
         value           uniform 0;
+        refValue        uniform 0;
+        refGradient     uniform 0;
+        valueFraction   uniform 0;
     }
     inlet
     {
@@ -34,25 +37,34 @@ boundaryField
         T               T;
         emissivity      1;
         value           uniform 0;
+        refValue        uniform 0;
+        refGradient     uniform 0;
+        valueFraction   uniform 0;
     }
     outlet
     {
         type            zeroGradient;
     }
-    cycLeft
+    cycLeft_half0
     {
         type            cyclic;
-        value           uniform 0;
     }
-    cycRight
+    cycRight_half0
     {
         type            cyclic;
-        value           uniform 0;
     }
     frontAndBack
     {
         type            empty;
     }
+    cycLeft_half1
+    {
+        type            cyclic;
+    }
+    cycRight_half1
+    {
+        type            cyclic;
+    }
 }
 
 
diff --git a/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0/H2O b/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0/H2O
index 11ad4763bec0b7394128f3e2ab466bc661c7d5df..b99dfc07c7c2c408559fe691cc9a184fb3841c96 100644
--- a/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0/H2O
+++ b/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0/H2O
@@ -1,8 +1,8 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  1.6                                   |
-|   \\  /    A nd           | Web:      http://www.OpenFOAM.org               |
+|  \\    /   O peration     | Version:  splitCyclic                           |
+|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
 FoamFile
@@ -10,12 +10,12 @@ FoamFile
     version     2.0;
     format      ascii;
     class       volScalarField;
-    location    "0";
+    location    "1";
     object      H2O;
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-dimensions      [0 0 0 0 0 0 0];
+dimensions      [ 0 0 0 0 0 0 0 ];
 
 internalField   uniform 0;
 
@@ -34,20 +34,26 @@ boundaryField
     {
         type            zeroGradient;
     }
-    cycLeft
+    cycLeft_half0
     {
         type            cyclic;
-        value           uniform 0;
     }
-    cycRight
+    cycRight_half0
     {
         type            cyclic;
-        value           uniform 0;
     }
     frontAndBack
     {
         type            empty;
     }
+    cycLeft_half1
+    {
+        type            cyclic;
+    }
+    cycRight_half1
+    {
+        type            cyclic;
+    }
 }
 
 
diff --git a/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0/N2 b/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0/N2
index 9335ae313af2b8e4d3dea6522d7a9f8c6d50c8b7..bac9361933be71af80f27c72dc34525f5fd00a6a 100644
--- a/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0/N2
+++ b/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0/N2
@@ -1,8 +1,8 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  1.6                                   |
-|   \\  /    A nd           | Web:      http://www.OpenFOAM.org               |
+|  \\    /   O peration     | Version:  splitCyclic                           |
+|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
 FoamFile
@@ -10,12 +10,12 @@ FoamFile
     version     2.0;
     format      ascii;
     class       volScalarField;
-    location    "0";
+    location    "1";
     object      N2;
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-dimensions      [0 0 0 0 0 0 0];
+dimensions      [ 0 0 0 0 0 0 0 ];
 
 internalField   uniform 0.79;
 
@@ -34,20 +34,26 @@ boundaryField
     {
         type            zeroGradient;
     }
-    cycLeft
+    cycLeft_half0
     {
         type            cyclic;
-        value           uniform 0.79;
     }
-    cycRight
+    cycRight_half0
     {
         type            cyclic;
-        value           uniform 0.79;
     }
     frontAndBack
     {
         type            empty;
     }
+    cycLeft_half1
+    {
+        type            cyclic;
+    }
+    cycRight_half1
+    {
+        type            cyclic;
+    }
 }
 
 
diff --git a/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0/O2 b/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0/O2
index 8d4f9c576f9b6e0353c7abbbb00105f49f1837da..7fa3e2e4886fa4d98bc2ab713e5044f1ec50b332 100644
--- a/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0/O2
+++ b/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0/O2
@@ -1,8 +1,8 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  1.6                                   |
-|   \\  /    A nd           | Web:      http://www.OpenFOAM.org               |
+|  \\    /   O peration     | Version:  splitCyclic                           |
+|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
 FoamFile
@@ -10,12 +10,12 @@ FoamFile
     version     2.0;
     format      ascii;
     class       volScalarField;
-    location    "0";
+    location    "1";
     object      O2;
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-dimensions      [0 0 0 0 0 0 0];
+dimensions      [ 0 0 0 0 0 0 0 ];
 
 internalField   uniform 0.21;
 
@@ -34,20 +34,26 @@ boundaryField
     {
         type            zeroGradient;
     }
-    cycLeft
+    cycLeft_half0
     {
         type            cyclic;
-        value           uniform 0.21;
     }
-    cycRight
+    cycRight_half0
     {
         type            cyclic;
-        value           uniform 0.21;
     }
     frontAndBack
     {
         type            empty;
     }
+    cycLeft_half1
+    {
+        type            cyclic;
+    }
+    cycRight_half1
+    {
+        type            cyclic;
+    }
 }
 
 
diff --git a/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0/T b/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0/T
index 888a879d4002f6ba79a2066b73dea9fad221ea38..00f9fd04b862fa82cce6bc05a55c3076a4764c83 100644
--- a/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0/T
+++ b/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0/T
@@ -1,8 +1,8 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  1.6                                   |
-|   \\  /    A nd           | Web:      http://www.OpenFOAM.org               |
+|  \\    /   O peration     | Version:  splitCyclic                           |
+|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
 FoamFile
@@ -10,12 +10,12 @@ FoamFile
     version     2.0;
     format      ascii;
     class       volScalarField;
-    location    "0";
+    location    "1";
     object      T;
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-dimensions      [0 0 0 1 0 0 0];
+dimensions      [ 0 0 0 1 0 0 0 ];
 
 internalField   uniform 350;
 
@@ -35,11 +35,11 @@ boundaryField
     {
         type            zeroGradient;
     }
-    cycLeft
+    cycLeft_half0
     {
         type            cyclic;
     }
-    cycRight
+    cycRight_half0
     {
         type            cyclic;
     }
@@ -47,6 +47,14 @@ boundaryField
     {
         type            empty;
     }
+    cycLeft_half1
+    {
+        type            cyclic;
+    }
+    cycRight_half1
+    {
+        type            cyclic;
+    }
 }
 
 
diff --git a/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0/U b/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0/U
index a3d2cfe57192898c9f63bda8e47f58da111b9761..a0c6dd9ec1e2da43a15d4ab9af02f108740abb9c 100644
--- a/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0/U
+++ b/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0/U
@@ -1,8 +1,8 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  1.6                                   |
-|   \\  /    A nd           | Web:      http://www.OpenFOAM.org               |
+|  \\    /   O peration     | Version:  splitCyclic                           |
+|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
 FoamFile
@@ -10,36 +10,36 @@ FoamFile
     version     2.0;
     format      ascii;
     class       volVectorField;
-    location    "0";
+    location    "1";
     object      U;
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-dimensions      [0 1 -1 0 0 0 0];
+dimensions      [ 0 1 -1 0 0 0 0 ];
 
-internalField   uniform (0 0 0);
+internalField   uniform ( 0 0 0 );
 
 boundaryField
 {
     walls
     {
         type            fixedValue;
-        value           uniform (0 0 0);
+        value           uniform ( 0 0 0 );
     }
     inlet
     {
         type            fixedValue;
-        value           uniform (5 0 0);
+        value           uniform ( 5 0 0 );
     }
     outlet
     {
         type            zeroGradient;
     }
-    cycLeft
+    cycLeft_half0
     {
         type            cyclic;
     }
-    cycRight
+    cycRight_half0
     {
         type            cyclic;
     }
@@ -47,6 +47,14 @@ boundaryField
     {
         type            empty;
     }
+    cycLeft_half1
+    {
+        type            cyclic;
+    }
+    cycRight_half1
+    {
+        type            cyclic;
+    }
 }
 
 
diff --git a/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0/alphat b/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0/alphat
index c87862d4ae4f758cac81ec3587a619730cfee3f1..f7c1245cbf2eb1ca62a32b65c64fce3c871d48ed 100644
--- a/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0/alphat
+++ b/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0/alphat
@@ -1,7 +1,7 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  1.6                                   |
+|  \\    /   O peration     | Version:  splitCyclic                           |
 |   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
@@ -10,12 +10,12 @@ FoamFile
     version     2.0;
     format      ascii;
     class       volScalarField;
-    location    "0";
+    location    "1";
     object      alphat;
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-dimensions      [1 -1 -1 0 0 0 0];
+dimensions      [ 1 -1 -1 0 0 0 0 ];
 
 internalField   uniform 0;
 
@@ -36,20 +36,26 @@ boundaryField
         type            calculated;
         value           uniform 0;
     }
-    cycLeft
+    cycLeft_half0
     {
         type            cyclic;
-        value           uniform 0;
     }
-    cycRight
+    cycRight_half0
     {
         type            cyclic;
-        value           uniform 0;
     }
     frontAndBack
     {
         type            empty;
     }
+    cycLeft_half1
+    {
+        type            cyclic;
+    }
+    cycRight_half1
+    {
+        type            cyclic;
+    }
 }
 
 
diff --git a/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0/epsilon b/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0/epsilon
index 9a102e372abd7058195ee79ec6aa756d3dfb1a40..bb80a5e3d1dc6f8b78cf986943c05a7fe4e726db 100644
--- a/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0/epsilon
+++ b/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0/epsilon
@@ -1,7 +1,7 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  1.6                                   |
+|  \\    /   O peration     | Version:  splitCyclic                           |
 |   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
@@ -10,12 +10,12 @@ FoamFile
     version     2.0;
     format      ascii;
     class       volScalarField;
-    location    "0";
+    location    "1";
     object      epsilon;
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-dimensions      [0 2 -3 0 0 0 0];
+dimensions      [ 0 2 -3 0 0 0 0 ];
 
 internalField   uniform 0.0449;
 
@@ -35,20 +35,26 @@ boundaryField
     {
         type            zeroGradient;
     }
-    cycLeft
+    cycLeft_half0
     {
         type            cyclic;
-        value           uniform 0.0449;
     }
-    cycRight
+    cycRight_half0
     {
         type            cyclic;
-        value           uniform 0.0449;
     }
     frontAndBack
     {
         type            empty;
     }
+    cycLeft_half1
+    {
+        type            cyclic;
+    }
+    cycRight_half1
+    {
+        type            cyclic;
+    }
 }
 
 
diff --git a/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0/k b/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0/k
index 9bbfb01b910dfff0b912a52398bcd3d603059288..1b91a7d191a823124191de8c0702efaf6ad9b81c 100644
--- a/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0/k
+++ b/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0/k
@@ -1,7 +1,7 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  1.6                                   |
+|  \\    /   O peration     | Version:  splitCyclic                           |
 |   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
@@ -10,12 +10,12 @@ FoamFile
     version     2.0;
     format      ascii;
     class       volScalarField;
-    location    "0";
+    location    "1";
     object      k;
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-dimensions      [0 2 -2 0 0 0 0];
+dimensions      [ 0 2 -2 0 0 0 0 ];
 
 internalField   uniform 0.0938;
 
@@ -35,20 +35,26 @@ boundaryField
     {
         type            zeroGradient;
     }
-    cycLeft
+    cycLeft_half0
     {
         type            cyclic;
-        value           uniform 0.0938;
     }
-    cycRight
+    cycRight_half0
     {
         type            cyclic;
-        value           uniform 0.0938;
     }
     frontAndBack
     {
         type            empty;
     }
+    cycLeft_half1
+    {
+        type            cyclic;
+    }
+    cycRight_half1
+    {
+        type            cyclic;
+    }
 }
 
 
diff --git a/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0/mut b/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0/mut
index 9a7573f3f13cdc21e247c8b19a8192f41728c2a3..d3ec136050dbae710ecbe6d44625769f74ea24ad 100644
--- a/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0/mut
+++ b/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0/mut
@@ -1,7 +1,7 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  1.6                                   |
+|  \\    /   O peration     | Version:  splitCyclic                           |
 |   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
@@ -10,12 +10,12 @@ FoamFile
     version     2.0;
     format      ascii;
     class       volScalarField;
-    location    "0";
+    location    "1";
     object      mut;
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-dimensions      [1 -1 -1 0 0 0 0];
+dimensions      [ 1 -1 -1 0 0 0 0 ];
 
 internalField   uniform 0;
 
@@ -36,20 +36,26 @@ boundaryField
         type            calculated;
         value           uniform 0;
     }
-    cycLeft
+    cycLeft_half0
     {
         type            cyclic;
-        value           uniform 0;
     }
-    cycRight
+    cycRight_half0
     {
         type            cyclic;
-        value           uniform 0;
     }
     frontAndBack
     {
         type            empty;
     }
+    cycLeft_half1
+    {
+        type            cyclic;
+    }
+    cycRight_half1
+    {
+        type            cyclic;
+    }
 }
 
 
diff --git a/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0/p b/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0/p
index 25b0c984e25542c647babb48ada18ea0463ae4d5..ba5cc3d6069c551a5fe104ef7c3693e0e3c7e38d 100644
--- a/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0/p
+++ b/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/0/p
@@ -1,8 +1,8 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  1.6                                   |
-|   \\  /    A nd           | Web:      http://www.OpenFOAM.org               |
+|  \\    /   O peration     | Version:  splitCyclic                           |
+|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
 FoamFile
@@ -10,12 +10,12 @@ FoamFile
     version     2.0;
     format      ascii;
     class       volScalarField;
-    location    "0";
+    location    "1";
     object      p;
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-dimensions      [1 -1 -2 0 0 0 0];
+dimensions      [ 1 -1 -2 0 0 0 0 ];
 
 internalField   uniform 100000;
 
@@ -34,20 +34,26 @@ boundaryField
         type            fixedValue;
         value           uniform 100000;
     }
-    cycLeft
+    cycLeft_half0
     {
         type            cyclic;
-        value           uniform 100000;
     }
-    cycRight
+    cycRight_half0
     {
         type            cyclic;
-        value           uniform 100000;
     }
     frontAndBack
     {
         type            empty;
     }
+    cycLeft_half1
+    {
+        type            cyclic;
+    }
+    cycRight_half1
+    {
+        type            cyclic;
+    }
 }
 
 
diff --git a/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/Allrun b/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/Allrun
index b44a7c8e2f7be6290578156d30d38091665d74a7..2fee29a1301c29041a33ec68e71f332ee580b21a 100755
--- a/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/Allrun
+++ b/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/Allrun
@@ -17,10 +17,10 @@ setsToZones -noFlipMap >& log.setsToZones
 
 # create the first cyclic - lhs of porous zone
 unset FOAM_SETNAN
-createBaffles cycLeft cycLeft -overwrite >& log.createBaffles1
+createBaffles cycLeft '(cycLeft_half0 cycLeft_half1)' -overwrite >& log.createBaffles1
 
 # create the second cyclic - rhs of porous zone
-createBaffles cycRight cycRight -overwrite >& log.createBaffles2
+createBaffles cycRight '(cycRight_half0 cycRight_half1)' -overwrite >& log.createBaffles2
 
 runApplication $application
 
diff --git a/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/constant/polyMesh/blockMeshDict b/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/constant/polyMesh/blockMeshDict
index 9470ef2b393925d94815811d525ac30d62c57aa5..a7981f61867354ef29f8ec99f9d572f04cd195ae 100644
--- a/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/constant/polyMesh/blockMeshDict
+++ b/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/constant/polyMesh/blockMeshDict
@@ -62,51 +62,87 @@ edges
 (
 );
 
-patches
+boundary
 (
-    wall walls
-    (
-        ( 0  1 13 12)
-        ( 1  2 14 13)
-        ( 2  3 15 14)
-        ( 3  4 16 15)
-        ( 4  5 17 16)
-        ( 6  7 19 18)
-        ( 7  8 20 19)
-        ( 8  9 21 20)
-        ( 9 10 22 21)
-        (10 11 23 22)
-    )
-
-    patch inlet
-    (
-        (11  0 12 23)
-    )
-
-    patch outlet
-    (
-        ( 5  6 18 17)
-    )
-
-    cyclic cycLeft
-    ()
-
-    cyclic cycRight
-    ()
-
-    empty frontAndBack
-    (
-        ( 0 11 10  1)
-        ( 1 10  9  2)
-        ( 2  9  8  3)
-        ( 3  8  7  4)
-        ( 4  7  6  5)
-        (12 13 22 23)
-        (13 14 21 22)
-        (14 15 20 21)
-        (15 16 19 20)
-        (16 17 18 19)
-    )
+    walls
+    {
+        type wall;
+        faces
+        (
+            ( 0  1 13 12)
+            ( 1  2 14 13)
+            ( 2  3 15 14)
+            ( 3  4 16 15)
+            ( 4  5 17 16)
+            ( 6  7 19 18)
+            ( 7  8 20 19)
+            ( 8  9 21 20)
+            ( 9 10 22 21)
+            (10 11 23 22)
+        );
+    }
+
+    inlet
+    {
+        type patch;
+        faces
+        (
+            (11  0 12 23)
+        );
+    }
+
+    outlet
+    {
+        type patch;
+        faces
+        (
+            ( 5  6 18 17)
+        );
+    }
+
+    cycLeft_half0
+    {
+        type cyclic;
+        faces    ();
+        neighbourPatch cycLeft_half1;
+    }
+    cycLeft_half1
+    {
+        type cyclic;
+        faces    ();
+        neighbourPatch cycLeft_half0;
+    }
+
+    cycRight_half0
+    {
+        type cyclic;
+        faces    ();
+        neighbourPatch cycRight_half1;
+    }
+    cycRight_half1
+    {
+        type cyclic;
+        faces    ();
+        neighbourPatch cycRight_half0;
+    }
+
+    frontAndBack
+    {
+        type empty;
+        faces
+        (
+            ( 0 11 10  1)
+            ( 1 10  9  2)
+            ( 2  9  8  3)
+            ( 3  8  7  4)
+            ( 4  7  6  5)
+            (12 13 22 23)
+            (13 14 21 22)
+            (14 15 20 21)
+            (15 16 19 20)
+            (16 17 18 19)
+        );
+    }
 );
 
 
diff --git a/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/constant/reactingCloud1Properties b/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/constant/reactingCloud1Properties
index 70086f0b264a20fc7ab84aae9e8e2747fe8893c6..e2ebae02d6f4b28854dde91c8c2e43ec6a5e2ed9 100644
--- a/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/constant/reactingCloud1Properties
+++ b/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/constant/reactingCloud1Properties
@@ -136,7 +136,11 @@ LocalInteractionCoeffs
         {
             type    rebound;
         }
-        cycLeft
+        cycLeft_half0
+        {
+            type    rebound;
+        }
+        cycLeft_half1
         {
             type    rebound;
         }
@@ -184,7 +188,8 @@ PatchPostProcessingCoeffs
 
     patches
     (
-        cycLeft
+        cycLeft_half0
+        cycLeft_half1
     );
 }
 
diff --git a/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/system/controlDict b/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/system/controlDict
index b5f8df21a79c6ef466839f7e58e0e376ba27e218..0f3fa40cf92dd05d7fb6cf2633986f4668a6ae27 100644
--- a/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/system/controlDict
+++ b/tutorials/lagrangian/porousExplicitSourceReactingParcelFoam/filter/system/controlDict
@@ -15,6 +15,8 @@ FoamFile
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
+libs            ("libcompressibleTurbulenceModel.so" "libcompressibleRASModels.so" "libradiation.so");
+
 application     porousExplicitSourceReactingParcelFoam;
 
 startFrom       startTime;
diff --git a/unitTestCases/README.txt b/unitTestCases/README.txt
new file mode 100644
index 0000000000000000000000000000000000000000..1f2ce33a509c19453c67b00029ad5b2a04146787
--- /dev/null
+++ b/unitTestCases/README.txt
@@ -0,0 +1,18 @@
+channel395/
+    - splitCyclic version
+    dev/
+    - dev version
+
+singleCyclic
+    - single cyclic z=0 to z=4
+    dev/
+    - dev version
+
+t-junction-with-fan
+    - t-junction tutorial to test baffles and fan-cyclics
+    dev/
+    - dev version
+
+twoCavityCyclicForWallDistance
+    - single cyclic. bottom split into two patches to see how
+    wallDistance transfers through cyclic.
diff --git a/wmake/rules/linux64Gcc/c++Opt b/wmake/rules/linux64Gcc/c++Opt
index 3446f7f58cbeb23e1753e982a9734bbf1a180b43..5e2b738cd9bd0935ff3a504e9c7586c742493d63 100644
--- a/wmake/rules/linux64Gcc/c++Opt
+++ b/wmake/rules/linux64Gcc/c++Opt
@@ -1,4 +1,3 @@
-c++DBUG     =
+#c++DBUG     = -O0 -DFULLDEBUG -g
+c++DBUG     = 
 c++OPT      = -O3
-#c++OPT      = -march=nocona -O3
-# -ftree-vectorize -ftree-vectorizer-verbose=3