diff --git a/applications/solvers/combustion/dieselEngineFoam/createSpray.H b/applications/solvers/combustion/dieselEngineFoam/createSpray.H
index b86b3684c29816f5009edddcf7cc6612e11ebe30..ac473957e5d1e86395509f79c2175c4f8039bc4d 100644
--- a/applications/solvers/combustion/dieselEngineFoam/createSpray.H
+++ b/applications/solvers/combustion/dieselEngineFoam/createSpray.H
@@ -32,7 +32,5 @@ if (dieselSpray.twoD())
     gasMass0 *= 2.0*mathematicalConstant::pi/dieselSpray.angleOfWedge();
 }
 
-reduce(gasMass0, sumOp<scalar>());
-
 gasMass0 -=
     dieselSpray.injectedMass(runTime.value()) - dieselSpray.liquidMass();
diff --git a/applications/solvers/combustion/dieselEngineFoam/spraySummary.H b/applications/solvers/combustion/dieselEngineFoam/spraySummary.H
index 907784b4388791a2c167f149384c1872914a9308..5b251e22902437f4b4bf964ee25c3d9c3169e90e 100644
--- a/applications/solvers/combustion/dieselEngineFoam/spraySummary.H
+++ b/applications/solvers/combustion/dieselEngineFoam/spraySummary.H
@@ -23,8 +23,6 @@
             gasMass *= 2.0*mathematicalConstant::pi/dieselSpray.angleOfWedge();
         }
 
-        reduce(gasMass, sumOp<scalar>());
-
         scalar addedMass = gasMass - gasMass0;
 
         Info<< "Added gas mass................. | " << 1e6*addedMass << " mg"
diff --git a/applications/solvers/heatTransfer/buoyantPisoFoam/Make/options b/applications/solvers/heatTransfer/buoyantPisoFoam/Make/options
index 9ac482d92edf3dcf8e65f39015dbb1ce96a127ca..f26563fc0fbdcff74dec668f5489bf159778d9ab 100644
--- a/applications/solvers/heatTransfer/buoyantPisoFoam/Make/options
+++ b/applications/solvers/heatTransfer/buoyantPisoFoam/Make/options
@@ -1,7 +1,6 @@
 EXE_INC = \
     -I$(LIB_SRC)/thermophysicalModels/basic/lnInclude \
     -I$(LIB_SRC)/turbulenceModels/compressible/turbulenceModel \
-    -I../XiFoam \
     -I$(LIB_SRC)/finiteVolume/lnInclude
 
 EXE_LIBS = \
diff --git a/applications/solvers/heatTransfer/buoyantPisoFoam/buoyantPisoFoam.C b/applications/solvers/heatTransfer/buoyantPisoFoam/buoyantPisoFoam.C
index 18dadabf8baaf398d16e0be06cb69eb726fd7fae..83527f8215130271882402bac0f6d5769ba4f860 100644
--- a/applications/solvers/heatTransfer/buoyantPisoFoam/buoyantPisoFoam.C
+++ b/applications/solvers/heatTransfer/buoyantPisoFoam/buoyantPisoFoam.C
@@ -70,11 +70,12 @@ int main(int argc, char *argv[])
 
         #include "UEqn.H"
 
+        #include "hEqn.H"
+
         // --- PISO loop
 
         for (int corr=0; corr<nCorr; corr++)
         {
-            #include "hEqn.H"
             #include "pEqn.H"
         }
 
diff --git a/applications/solvers/heatTransfer/buoyantPisoFoam/createFields.H b/applications/solvers/heatTransfer/buoyantPisoFoam/createFields.H
index a647f0a3ef2a0831cd06f96ab973c58286a0ba9b..103b3ea3bb531684ed48fc5fe74ac8ec588f4d99 100644
--- a/applications/solvers/heatTransfer/buoyantPisoFoam/createFields.H
+++ b/applications/solvers/heatTransfer/buoyantPisoFoam/createFields.H
@@ -53,12 +53,15 @@
     );
 
     Info<< "Creating field DpDt\n" << endl;
-    volScalarField DpDt =
-        fvc::DDt(surfaceScalarField("phiU", phi/fvc::interpolate(rho)), p);
+    volScalarField DpDt
+    (
+        "DpDt",
+        fvc::DDt(surfaceScalarField("phiU", phi/fvc::interpolate(rho)), p)
+    );
 
     Info<< "Calculating field g.h\n" << endl;
     volScalarField gh("gh", g & mesh.C());
-    surfaceScalarField ghf("gh", g & mesh.Cf());
+    surfaceScalarField ghf("ghf", g & mesh.Cf());
 
     dimensionedScalar pRef("pRef", p.dimensions(), thermo->lookup("pRef"));
 
diff --git a/applications/solvers/heatTransfer/buoyantPisoFoam/pEqn.H b/applications/solvers/heatTransfer/buoyantPisoFoam/pEqn.H
index 91e190b4cdfa4eeab0151de9126ecab5f5173036..53f6688a6a8438f11c91816941e5d78b5bd47c14 100644
--- a/applications/solvers/heatTransfer/buoyantPisoFoam/pEqn.H
+++ b/applications/solvers/heatTransfer/buoyantPisoFoam/pEqn.H
@@ -12,8 +12,8 @@
     (
         fvc::interpolate(rho)
        *(
-           (fvc::interpolate(U) & mesh.Sf())
-         + fvc::ddtPhiCorr(rUA, rho, U, phi)
+            (fvc::interpolate(U) & mesh.Sf())
+          + fvc::ddtPhiCorr(rUA, rho, U, phi)
         )
     );
 
diff --git a/applications/solvers/heatTransfer/buoyantSimpleFoam/createFields.H b/applications/solvers/heatTransfer/buoyantSimpleFoam/createFields.H
index d26da5cb325560d17f59e3f9a1aed4d3f08acdc5..879ee722b98ec4c6ab21ca66518c22fc31a9105c 100644
--- a/applications/solvers/heatTransfer/buoyantSimpleFoam/createFields.H
+++ b/applications/solvers/heatTransfer/buoyantSimpleFoam/createFields.H
@@ -53,7 +53,7 @@
 
     Info<< "Calculating field g.h\n" << endl;
     volScalarField gh("gh", g & mesh.C());
-    surfaceScalarField ghf("gh", g & mesh.Cf());
+    surfaceScalarField ghf("ghf", g & mesh.Cf());
 
     dimensionedScalar pRef("pRef", p.dimensions(), thermo->lookup("pRef"));
 
diff --git a/applications/solvers/heatTransfer/chtMultiRegionFoam/derivedFvPatchFields/solidWallMixedTemperatureCoupled/solidWallMixedTemperatureCoupledFvPatchScalarField.H b/applications/solvers/heatTransfer/chtMultiRegionFoam/derivedFvPatchFields/solidWallMixedTemperatureCoupled/solidWallMixedTemperatureCoupledFvPatchScalarField.H
index 5a78299a7a7967d47417f9f214ec3d8fd77427d9..34c32b1abf4204864d1cc7268ecf3e5874a25d36 100644
--- a/applications/solvers/heatTransfer/chtMultiRegionFoam/derivedFvPatchFields/solidWallMixedTemperatureCoupled/solidWallMixedTemperatureCoupledFvPatchScalarField.H
+++ b/applications/solvers/heatTransfer/chtMultiRegionFoam/derivedFvPatchFields/solidWallMixedTemperatureCoupled/solidWallMixedTemperatureCoupledFvPatchScalarField.H
@@ -103,8 +103,8 @@ public:
             const dictionary&
         );
 
-        //- Construct by mapping given solidWallMixedTemperatureCoupledFvPatchScalarField
-        //  onto a new patch
+        //- Construct by mapping given
+        //  solidWallMixedTemperatureCoupledFvPatchScalarField onto a new patch
         solidWallMixedTemperatureCoupledFvPatchScalarField
         (
             const solidWallMixedTemperatureCoupledFvPatchScalarField&,
diff --git a/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/setRegionFluidFields.H b/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/setRegionFluidFields.H
index bc4590a4286e71d0db721d6f5db9dde70345f810..35a64418a8c6cbd1d488970f1d665420a2f752b6 100644
--- a/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/setRegionFluidFields.H
+++ b/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/setRegionFluidFields.H
@@ -4,7 +4,7 @@
     volScalarField& rho = rhoFluid[i];
     volScalarField& K = KFluid[i];
     volVectorField& U = UFluid[i];
-    surfaceScalarField phi = phiFluid[i];
+    surfaceScalarField& phi = phiFluid[i];
     compressible::turbulenceModel& turb = turbulence[i];
     volScalarField& DpDt = DpDtFluid[i];
     const volScalarField& gh = ghFluid[i];
diff --git a/applications/solvers/multiphase/interFoam/createFields.H b/applications/solvers/multiphase/interFoam/createFields.H
index af349d79174e164e50dca3d8d48b49b0f8c1349a..53dd01672a274de04ea0c4d5979fb3aaa97a7a7f 100644
--- a/applications/solvers/multiphase/interFoam/createFields.H
+++ b/applications/solvers/multiphase/interFoam/createFields.H
@@ -85,7 +85,7 @@
 
     Info<< "Calculating field g.h\n" << endl;
     volScalarField gh("gh", g & mesh.C());
-    surfaceScalarField ghf("gh", g & mesh.Cf());
+    surfaceScalarField ghf("ghf", g & mesh.Cf());
 
 
     volScalarField p
diff --git a/applications/solvers/multiphase/multiphaseInterFoam/createFields.H b/applications/solvers/multiphase/multiphaseInterFoam/createFields.H
index aa62d0f2a177af49e20ed3cb49ce9ba605029037..9119631d0cc34e4bd366c7f00c43379490a7d71c 100644
--- a/applications/solvers/multiphase/multiphaseInterFoam/createFields.H
+++ b/applications/solvers/multiphase/multiphaseInterFoam/createFields.H
@@ -47,7 +47,7 @@
 
     Info<< "Calculating field g.h\n" << endl;
     volScalarField gh("gh", g & mesh.C());
-    surfaceScalarField ghf("gh", g & mesh.Cf());
+    surfaceScalarField ghf("ghf", g & mesh.Cf());
 
 
     volScalarField p
diff --git a/applications/solvers/multiphase/settlingFoam/createFields.H b/applications/solvers/multiphase/settlingFoam/createFields.H
index 400f89c43bce66ce29f3d9cfe79e4a9cc84be9b3..b13649c3124ddaf5ba06c5e13e3b090b746798ec 100644
--- a/applications/solvers/multiphase/settlingFoam/createFields.H
+++ b/applications/solvers/multiphase/settlingFoam/createFields.H
@@ -339,4 +339,4 @@
     );
 
     Info<< "Calculating field (g.h)f\n" << endl;
-    surfaceScalarField ghf = surfaceScalarField("gh", g & mesh.Cf());
+    surfaceScalarField ghf = surfaceScalarField("ghf", g & mesh.Cf());
diff --git a/applications/test/List/ListTest.C b/applications/test/List/ListTest.C
index bc8901b03beacc65c399053ab5c5d49532009edf..d4834cb1db2b02bc79f4d6e8508e9f3b3361c695 100644
--- a/applications/test/List/ListTest.C
+++ b/applications/test/List/ListTest.C
@@ -43,31 +43,33 @@ using namespace Foam;
 
 int main(int argc, char *argv[])
 {
-    List<vector> list(IStringStream("1 ((0 1 2))")());
-    Info<< list << endl;
+    List<vector> list1(IStringStream("1 ((0 1 2))")());
+    Info<< "list1: " << list1 << endl;
 
     List<vector> list2(IStringStream("((0 1 2) (3 4 5) (6 7 8))")());
-    Info<< list2 << endl;
+    Info<< "list2: " << list2 << endl;
+
+    list1.append(list2);
+    Info<< "list1.append(list2): " << list1 << endl;
 
     Info<< findIndex(list2, vector(3, 4, 5)) << endl;
 
     list2.setSize(10, vector(1, 2, 3));
-    Info<< list2 << endl;
+    Info<< "list2: " << list2 << endl;
 
     List<vector> list3(list2.xfer());
     Info<< "Transferred via the xfer() method" << endl;
-    Info<< list2 << nl
-        << list3 << endl;
+    Info<< "list2: " << list2 << nl
+        << "list3: " << list3 << endl;
 
 
     // Subset
     const labelList map(IStringStream("2 (0 2)")());
     List<vector> subList3(list3, map);
     Info<< "Elements " << map << " out of " << list3
-        << " : " << subList3 << endl;
+        << " => " << subList3 << endl;
 
     return 0;
 }
 
-
 // ************************************************************************* //
diff --git a/applications/utilities/mesh/advanced/refineHexMesh/refineHexMesh.C b/applications/utilities/mesh/advanced/refineHexMesh/refineHexMesh.C
index 364aed2e16c4196938e76e0bd9839f67899f470f..c18e0af978a147ca1b9b2dc522f6d8773f85b947 100644
--- a/applications/utilities/mesh/advanced/refineHexMesh/refineHexMesh.C
+++ b/applications/utilities/mesh/advanced/refineHexMesh/refineHexMesh.C
@@ -182,6 +182,7 @@ int main(int argc, char *argv[])
     if (overwrite)
     {
         mesh.setInstance(oldInstance);
+        meshCutter.setInstance(oldInstance);
     }
     Info<< "Writing mesh to " << runTime.timeName() << endl;
 
diff --git a/applications/utilities/mesh/conversion/writeMeshObj/writeMeshObj.C b/applications/utilities/mesh/conversion/writeMeshObj/writeMeshObj.C
index d8042fdaa8a2b522f332592793817d67e50b4e1e..9eaaf2c199ffb24ce064ab888d5739b8ec63160e 100644
--- a/applications/utilities/mesh/conversion/writeMeshObj/writeMeshObj.C
+++ b/applications/utilities/mesh/conversion/writeMeshObj/writeMeshObj.C
@@ -344,6 +344,7 @@ int main(int argc, char *argv[])
     argList::validOptions.insert("point", "pointI");
     argList::validOptions.insert("cellSet", "setName");
     argList::validOptions.insert("faceSet", "setName");
+#   include "addRegionOption.H"
 
 #   include "setRootCase.H"
 #   include "createTime.H"
@@ -364,7 +365,7 @@ int main(int argc, char *argv[])
 
     instantList timeDirs = timeSelector::select0(runTime, args);
 
-#   include "createPolyMesh.H"
+#   include "createNamedPolyMesh.H"
 
     forAll(timeDirs, timeI)
     {
diff --git a/applications/utilities/mesh/generation/extrudeMesh/extrudeMesh.C b/applications/utilities/mesh/generation/extrudeMesh/extrudeMesh.C
index 0bb37f6727d2be3001f3fc05265ed45d263e9cec..37860e27b25d217c4ddef3a765058fa6f7b1d8fb 100644
--- a/applications/utilities/mesh/generation/extrudeMesh/extrudeMesh.C
+++ b/applications/utilities/mesh/generation/extrudeMesh/extrudeMesh.C
@@ -52,19 +52,18 @@ using namespace Foam;
 
 int main(int argc, char *argv[])
 {
-#   include "setRoots.H"
-#   include "createTimeExtruded.H"
+    #include "setRoots.H"
+    #include "createTimeExtruded.H"
 
-
-    if (args.options().found("sourceRoot") == args.options().found("surface"))
+    if (args.options().found("sourceCase") == args.options().found("surface"))
     {
         FatalErrorIn(args.executable())
-            << "Need to specify either -sourceRoot/Case/Patch or -surface"
-            << " option to specify the source of the patch to extrude"
+            << "Specify either -sourceCase and -sourcePatch"
+               " or -surface options\n"
+               "    to specify the source of the patch to extrude"
             << exit(FatalError);
     }
 
-
     autoPtr<extrudedMesh> meshPtr(NULL);
 
     autoPtr<extrudeModel> model
@@ -84,23 +83,24 @@ int main(int argc, char *argv[])
         )
     );
 
-    if (args.options().found("sourceRoot"))
+    if (args.options().found("sourceCase"))
     {
-        fileName rootDirSource(args.options()["sourceRoot"]);
-        fileName caseDirSource(args.options()["sourceCase"]);
-        fileName patchName(args.options()["sourcePatch"]);
+        fileName sourceCasePath(args.options()["sourceCase"]);
+        fileName sourceRootDir = sourceCasePath.path();
+        fileName sourceCaseDir = sourceCasePath.name();
+        word patchName(args.options()["sourcePatch"]);
 
         Info<< "Extruding patch " << patchName
-            << " on mesh " << rootDirSource << ' ' << caseDirSource << nl
+            << " on mesh " << sourceCasePath << nl
             << endl;
 
         Time runTime
         (
             Time::controlDictName,
-            rootDirSource,
-            caseDirSource
+            sourceRootDir,
+            sourceCaseDir
         );
-#       include "createPolyMesh.H"
+        #include "createPolyMesh.H"
 
         label patchID = mesh.boundaryMesh().findPatchID(patchName);
 
@@ -171,7 +171,7 @@ int main(int argc, char *argv[])
                 fMesh,
                 model()
             )
-        );        
+        );
     }
     extrudedMesh& mesh = meshPtr();
 
@@ -180,7 +180,7 @@ int main(int argc, char *argv[])
     const vector span = bb.span();
     const scalar mergeDim = 1E-4 * bb.minDim();
 
-    Pout<< "Mesh bounding box:" << bb << nl
+    Info<< "Mesh bounding box:" << bb << nl
         << "        with span:" << span << nl
         << "Merge distance   :" << mergeDim << nl
         << endl;
@@ -201,7 +201,7 @@ int main(int argc, char *argv[])
     // ~~~~~~~~~~~~~~
 
     {
-        Pout<< "Collapsing edges < " << mergeDim << " ..." << nl << endl;
+        Info<< "Collapsing edges < " << mergeDim << " ..." << nl << endl;
 
         // Edge collapsing engine
         edgeCollapser collapser(mesh);
@@ -217,7 +217,7 @@ int main(int argc, char *argv[])
 
             if (d < mergeDim)
             {
-                Pout<< "Merging edge " << e << " since length " << d
+                Info<< "Merging edge " << e << " since length " << d
                     << " << " << mergeDim << nl;
 
                 // Collapse edge to e[0]
@@ -252,8 +252,8 @@ int main(int argc, char *argv[])
 
     if (args.options().found("mergeFaces"))
     {
-        Pout<< "Assuming full 360 degree axisymmetric case;"
-            << " stitching faces on patches " 
+        Info<< "Assuming full 360 degree axisymmetric case;"
+            << " stitching faces on patches "
             << patches[origPatchID].name() << " and "
             << patches[otherPatchID].name() << " together ..." << nl << endl;
 
diff --git a/applications/utilities/mesh/generation/extrudeMesh/extrudeModel/wedge/wedge.C b/applications/utilities/mesh/generation/extrudeMesh/extrudeModel/wedge/wedge.C
index 27dec921b720873f35b0e7a6b7a068c7776e7cc4..6da971a1bf0e2d048976c808abbaa0dea944908c 100644
--- a/applications/utilities/mesh/generation/extrudeMesh/extrudeModel/wedge/wedge.C
+++ b/applications/utilities/mesh/generation/extrudeMesh/extrudeModel/wedge/wedge.C
@@ -48,7 +48,7 @@ wedge::wedge(const dictionary& dict)
 :
     extrudeModel(typeName, dict),
     axisPt_(coeffDict_.lookup("axisPt")),
-    axisNormal_(coeffDict_.lookup("axisNormal")),
+    axis_(coeffDict_.lookup("axis")),
     angle_
     (
         readScalar(coeffDict_.lookup("angle"))
@@ -96,7 +96,7 @@ point wedge::operator()
     // of surface point and surface normal.
     point d = surfacePoint - axisPt_;
 
-    d -= (axisNormal_ & d)*axisNormal_;
+    d -= (axis_ & d)*axis_;
 
     scalar dMag = mag(d);
 
@@ -107,7 +107,7 @@ point wedge::operator()
 
     if (dMag > VSMALL)
     {
-        vector n = (d/dMag) ^ axisNormal_;
+        vector n = (d/dMag) ^ axis_;
 
         rotatedPoint +=
           + cos(sliceAngle)*d
@@ -124,4 +124,3 @@ point wedge::operator()
 } // End namespace Foam
 
 // ************************************************************************* //
-
diff --git a/applications/utilities/mesh/generation/extrudeMesh/extrudeModel/wedge/wedge.H b/applications/utilities/mesh/generation/extrudeMesh/extrudeModel/wedge/wedge.H
index 38b862630d5c804e1d01691baf0ae89fb70cba39..39c4b4a2d3073ade350e8c5db80f6faea29b5d5b 100644
--- a/applications/utilities/mesh/generation/extrudeMesh/extrudeModel/wedge/wedge.H
+++ b/applications/utilities/mesh/generation/extrudeMesh/extrudeModel/wedge/wedge.H
@@ -60,13 +60,13 @@ class wedge
 {
     // Private data
 
-        //- point on axis
+        //- Point on axis
         const point axisPt_;
 
-        //- normalized direction of axis
-        const vector axisNormal_;
+        //- Normalized direction of axis
+        const vector axis_;
 
-        //- overall angle (radians)
+        //- Overall angle (radians)
         const scalar angle_;
 
 
@@ -80,6 +80,7 @@ public:
         //- Construct from components
         wedge(const dictionary& dict);
 
+
     //- Destrcuctor
     ~wedge();
 
diff --git a/applications/utilities/mesh/generation/extrudeMesh/extrudeProperties b/applications/utilities/mesh/generation/extrudeMesh/extrudeProperties
index c9b7977508b29c2e0f6fa454dca2af26c7fe3874..ecbe160a150ab5f1b16ecad4e5fd423a64edc278 100644
--- a/applications/utilities/mesh/generation/extrudeMesh/extrudeProperties
+++ b/applications/utilities/mesh/generation/extrudeMesh/extrudeProperties
@@ -24,7 +24,7 @@ nLayers             1;
 wedgeCoeffs
 {
     axisPt          (0 0 0);
-    axisNormal      (0 -1 0);
+    axis            (0 -1 0);
     angle           2.0;
 }
 
@@ -47,4 +47,3 @@ sigmaRadialCoeffs
 
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
diff --git a/applications/utilities/mesh/generation/extrudeMesh/setRoots.H b/applications/utilities/mesh/generation/extrudeMesh/setRoots.H
index 255949426bae2e399cd8d03f50c812b5145ed9ca..9c13db28d19f93ec3fc4bb9b7be943bc721eed33 100644
--- a/applications/utilities/mesh/generation/extrudeMesh/setRoots.H
+++ b/applications/utilities/mesh/generation/extrudeMesh/setRoots.H
@@ -1,7 +1,6 @@
     argList::validArgs.clear();
     argList::noParallel();
 
-    argList::validOptions.insert("sourceRoot", "source root");
     argList::validOptions.insert("sourceCase", "source case");
     argList::validOptions.insert("sourcePatch", "source patch");
 
@@ -15,4 +14,3 @@
     {
          FatalError.exit();
     }
-
diff --git a/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMeshDict b/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMeshDict
index cc975eb9708ac93b1a478343b34363b0ef3a0587..205c767600bede32ffba05d4a2bd0873598b7511 100644
--- a/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMeshDict
+++ b/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMeshDict
@@ -274,6 +274,14 @@ addLayersControls
 
     // Create buffer region for new layer terminations
     nBufferCellsNoExtrude 0;
+
+
+    // Overall max number of layer addition iterations
+    nLayerIter 50;
+
+    // Max number of iterations after which relaxed meshQuality controls
+    // get used.
+    nRelaxedIter 20;
 }
 
 
@@ -335,6 +343,16 @@ meshQualityControls
     nSmoothScale 4;
     //- amount to scale back displacement at error points
     errorReduction 0.75;
+
+
+
+    // Optional : some meshing phases allow usage of relaxed rules.
+    // See e.g. addLayersControls::nRelaxedIter.
+    relaxed
+    {
+        //- Maximum non-orthogonality allowed. Set to 180 to disable.
+        maxNonOrtho 75;
+    }
 }
 
 
diff --git a/applications/utilities/mesh/manipulation/splitMeshRegions/splitMeshRegions.C b/applications/utilities/mesh/manipulation/splitMeshRegions/splitMeshRegions.C
index 582a6ca9bf6b2bb9da89ca9397576fb5c1bce45e..e71a5f11c0b2ff259f3d3f6b0f997df0efd29f88 100644
--- a/applications/utilities/mesh/manipulation/splitMeshRegions/splitMeshRegions.C
+++ b/applications/utilities/mesh/manipulation/splitMeshRegions/splitMeshRegions.C
@@ -57,6 +57,7 @@ Description
 #include "EdgeMap.H"
 #include "syncTools.H"
 #include "ReadFields.H"
+#include "directMappedWallPolyPatch.H"
 
 using namespace Foam;
 
@@ -1022,13 +1023,13 @@ EdgeMap<label> addRegionPatches
             (
                 mesh,
                 regionNames[e[0]] + "_to_" + regionNames[e[1]],
-                polyPatch::typeName
+                directMappedWallPolyPatch::typeName
             );
             addPatch
             (
                 mesh,
                 regionNames[e[1]] + "_to_" + regionNames[e[0]],
-                polyPatch::typeName
+                directMappedWallPolyPatch::typeName
             );
 
             Info<< "For interface between region " << e[0]
@@ -1100,7 +1101,6 @@ EdgeMap<label> addRegionPatches
 //}
 
 
-//XXXXXXXXX
 // Find region that covers most of cell zone
 label findCorrespondingRegion
 (
@@ -1152,7 +1152,6 @@ label findCorrespondingRegion
 
     return regionI;
 }
-//XXXXXXXXX
 
 
 //// Checks if cellZone has corresponding cellRegion.
diff --git a/applications/utilities/parallelProcessing/decomposePar/decomposePar.C b/applications/utilities/parallelProcessing/decomposePar/decomposePar.C
index 5edafcf561611abb7cab29944b824ccd6bf21cc7..26ee3e062a4b1ae9087b6a37b73aa4bb2bd60c76 100644
--- a/applications/utilities/parallelProcessing/decomposePar/decomposePar.C
+++ b/applications/utilities/parallelProcessing/decomposePar/decomposePar.C
@@ -83,6 +83,7 @@ Usage
 int main(int argc, char *argv[])
 {
     argList::noParallel();
+#   include "addRegionOption.H"
     argList::validOptions.insert("cellDist", "");
     argList::validOptions.insert("copyUniform", "");
     argList::validOptions.insert("fields", "");
@@ -92,6 +93,17 @@ int main(int argc, char *argv[])
 
 #   include "setRootCase.H"
 
+    word regionName = fvMesh::defaultRegion;
+    word regionDir = word::null;
+
+    if (args.options().found("region"))
+    {
+        regionName = args.options()["region"];
+        regionDir = regionName;
+        Info<< "Decomposing mesh " << regionName << nl << endl;
+    }
+
+
     bool writeCellDist(args.options().found("cellDist"));
     bool copyUniform(args.options().found("copyUniform"));
     bool decomposeFieldsOnly(args.options().found("fields"));
@@ -105,7 +117,17 @@ int main(int argc, char *argv[])
 
     // determine the existing processor count directly
     label nProcs = 0;
-    while (isDir(runTime.path()/(word("processor") + name(nProcs))))
+    while
+    (
+        isDir
+        (
+            runTime.path()
+           /(word("processor") + name(nProcs))
+           /runTime.constant()
+           /regionDir
+           /polyMesh::meshSubDir
+        )
+    )
     {
         ++nProcs;
     }
@@ -119,6 +141,7 @@ int main(int argc, char *argv[])
             (
                 "decomposeParDict",
                 runTime.time().system(),
+                regionDir,          // use region if non-standard
                 runTime,
                 IOobject::MUST_READ,
                 IOobject::NO_WRITE,
@@ -196,7 +219,7 @@ int main(int argc, char *argv[])
     (
         IOobject
         (
-            domainDecomposition::defaultRegion,
+            regionName,
             runTime.timeName(),
             runTime
         )
@@ -219,7 +242,7 @@ int main(int argc, char *argv[])
             (
                 runTime.path()
               / mesh.facesInstance()
-              / polyMesh::defaultRegion
+              / regionName
               / "cellDecomposition"
             );
 
@@ -383,7 +406,12 @@ int main(int argc, char *argv[])
 
             label i = 0;
 
-            forAllIter(Cloud<indexedParticle>, lagrangianPositions[cloudI], iter)
+            forAllIter
+            (
+                Cloud<indexedParticle>,
+                lagrangianPositions[cloudI],
+                iter
+            )
             {
                 iter().index() = i++;
 
@@ -405,7 +433,8 @@ int main(int argc, char *argv[])
 
                 if (!cellParticles[cloudI][celli])
                 {
-                    cellParticles[cloudI][celli] = new SLList<indexedParticle*>();
+                    cellParticles[cloudI][celli] = new SLList<indexedParticle*>
+                    ();
                 }
 
                 cellParticles[cloudI][celli]->append(&iter());
@@ -513,7 +542,7 @@ int main(int argc, char *argv[])
         (
             IOobject
             (
-                fvMesh::defaultRegion,
+                regionName,
                 processorDb.timeName(),
                 processorDb
             )
diff --git a/applications/utilities/parallelProcessing/decomposePar/decomposeParDict b/applications/utilities/parallelProcessing/decomposePar/decomposeParDict
index 288797ed1e444b4e1d76b9bd9c053bd7bdbc6873..98ec9b7087f53d7a33edffabac31de7f0b2b7e5e 100644
--- a/applications/utilities/parallelProcessing/decomposePar/decomposeParDict
+++ b/applications/utilities/parallelProcessing/decomposePar/decomposeParDict
@@ -19,7 +19,7 @@ FoamFile
 
 numberOfSubdomains  4;
 
-// preservePatches (inlet);
+//- Keep owner and neighbour on same processor for faces in zones:
 // preserveFaceZones (heater solid1 solid3);
 
 method          simple;
diff --git a/applications/utilities/parallelProcessing/decomposePar/distributeCells.C b/applications/utilities/parallelProcessing/decomposePar/distributeCells.C
index ad78b2a9142c0f1dfa0352b89bc786555d469b46..af47af244ff4848db0587e9db02a44f21cde5574 100644
--- a/applications/utilities/parallelProcessing/decomposePar/distributeCells.C
+++ b/applications/utilities/parallelProcessing/decomposePar/distributeCells.C
@@ -45,35 +45,6 @@ void domainDecomposition::distributeCells()
 
     labelHashSet sameProcFaces;
 
-    if (decompositionDict_.found("preservePatches"))
-    {
-        wordList pNames(decompositionDict_.lookup("preservePatches"));
-
-        Info<< "Keeping owner and neighbour of faces in patches " << pNames
-            << " on same processor" << endl;
-
-        const polyBoundaryMesh& patches = boundaryMesh();
-
-        forAll(pNames, i)
-        {
-            label patchI = patches.findPatchID(pNames[i]);
-
-            if (patchI == -1)
-            {
-                FatalErrorIn("domainDecomposition::distributeCells()")
-                    << "Unknown preservePatch " << pNames[i]
-                    << endl << "Valid patches are " << patches.names()
-                    << exit(FatalError);
-            }
-
-            const polyPatch& pp = patches[patchI];
-
-            forAll(pp, i)
-            {
-                sameProcFaces.insert(pp.start() + i);
-            }
-        }
-    }
     if (decompositionDict_.found("preserveFaceZones"))
     {
         wordList zNames(decompositionDict_.lookup("preserveFaceZones"));
@@ -104,14 +75,6 @@ void domainDecomposition::distributeCells()
         }
     }
 
-    if (sameProcFaces.size())
-    {
-        Info<< "Selected " << sameProcFaces.size()
-            << " faces whose owner and neighbour cell should be kept on the"
-            << " same processor" << endl;
-    }
-
-
 
     // Construct decomposition method and either do decomposition on
     // cell centres or on agglomeration
@@ -129,6 +92,10 @@ void domainDecomposition::distributeCells()
     }
     else
     {
+        Info<< "Selected " << sameProcFaces.size()
+            << " faces whose owner and neighbour cell should be kept on the"
+            << " same processor" << endl;
+
         // Faces where owner and neighbour are not 'connected' (= all except
         // sameProcFaces)
         boolList blockedFace(nFaces(), true);
diff --git a/applications/utilities/parallelProcessing/decomposePar/domainDecomposition.C b/applications/utilities/parallelProcessing/decomposePar/domainDecomposition.C
index 989d384e40325e47deda38efa26df2221a4c4d70..2940577d163722f8dcabbd761ef70215f252d77b 100644
--- a/applications/utilities/parallelProcessing/decomposePar/domainDecomposition.C
+++ b/applications/utilities/parallelProcessing/decomposePar/domainDecomposition.C
@@ -268,7 +268,7 @@ bool domainDecomposition::writeDecomposition()
         (
             IOobject
             (
-                polyMesh::defaultRegion,
+                this->polyMesh::name(),  // region name of undecomposed mesh
                 "constant",
                 processorDb
             ),
diff --git a/applications/utilities/surface/surfaceCheck/surfaceCheck.C b/applications/utilities/surface/surfaceCheck/surfaceCheck.C
index e7b789007475cfd40617116532e1e0a98a0cc3d8..d714c19ec36e5bc5be435b9ac3a02349274954f2 100644
--- a/applications/utilities/surface/surfaceCheck/surfaceCheck.C
+++ b/applications/utilities/surface/surfaceCheck/surfaceCheck.C
@@ -32,6 +32,7 @@ License
 #include "OFstream.H"
 #include "surfaceIntersection.H"
 #include "SortableList.H"
+#include "PatchTools.H"
 
 using namespace Foam;
 
@@ -171,11 +172,11 @@ int main(int argc, char *argv[])
 
     argList::validArgs.clear();
     argList::validArgs.append("surface file");
-    argList::validOptions.insert("noSelfIntersection", "");
+    argList::validOptions.insert("checkSelfIntersection", "");
     argList::validOptions.insert("verbose", "");
     argList args(argc, argv);
 
-    bool checkSelfIntersection = !args.options().found("noSelfIntersection");
+    bool checkSelfIntersection = args.options().found("checkSelfIntersection");
     bool verbose = args.options().found("verbose");
 
     fileName surfFileName(args.additionalArgs()[0]);
@@ -596,13 +597,14 @@ int main(int argc, char *argv[])
     // Check orientation
     // ~~~~~~~~~~~~~~~~~
 
-    boolList borderEdge(surf.checkOrientation(false));
+    labelHashSet borderEdge(surf.size()/1000);
+    PatchTools::checkOrientation(surf, false, &borderEdge);
 
     //
     // Colour all faces into zones using borderEdge
     //
     labelList normalZone;
-    label numNormalZones = surf.markZones(borderEdge, normalZone);
+    label numNormalZones = PatchTools::markZones(surf, borderEdge, normalZone);
 
     Pout<< endl
         << "Number of zones (connected area with consistent normal) : "
diff --git a/applications/utilities/surface/surfaceConvert/surfaceConvert.C b/applications/utilities/surface/surfaceConvert/surfaceConvert.C
index 311dab28f66f01986d584df1bf96aaa237e8a645..fd7b223827334261083e944fb9d559be218c4106 100644
--- a/applications/utilities/surface/surfaceConvert/surfaceConvert.C
+++ b/applications/utilities/surface/surfaceConvert/surfaceConvert.C
@@ -115,15 +115,13 @@ int main(int argc, char *argv[])
     }
 
     Info<< "writing " << exportName;
-    if (scaleFactor <= 0)
+    if (scaleFactor > 0)
     {
-        Info<< " without scaling" << endl;
-    }
-    else
-    {
-        Info<< " with scaling " << scaleFactor << endl;
+        Info<< " with scaling " << scaleFactor;
         surf.scalePoints(scaleFactor);
     }
+    Info<< endl;
+
     surf.write(exportName, sortByRegion);
 
     Info<< "\nEnd\n" << endl;
diff --git a/applications/utilities/surface/surfaceMeshConvert/surfaceMeshConvert.C b/applications/utilities/surface/surfaceMeshConvert/surfaceMeshConvert.C
index 3a48a5deda74c71e13ace6dea886cb5b3fa03c35..4f607e89fb15b477ddc6238805068db482c5d80a 100644
--- a/applications/utilities/surface/surfaceMeshConvert/surfaceMeshConvert.C
+++ b/applications/utilities/surface/surfaceMeshConvert/surfaceMeshConvert.C
@@ -73,7 +73,7 @@ int main(int argc, char *argv[])
     argList::noParallel();
     argList::validArgs.append("inputFile");
     argList::validArgs.append("outputFile");
-    argList::validOptions.insert("clean",  "scale");
+    argList::validOptions.insert("clean", "");
     argList::validOptions.insert("scaleIn",  "scale");
     argList::validOptions.insert("scaleOut", "scale");
     argList::validOptions.insert("dict", "coordinateSystemsDict");
diff --git a/applications/utilities/surface/surfaceMeshExport/surfaceMeshExport.C b/applications/utilities/surface/surfaceMeshExport/surfaceMeshExport.C
index 41c8a43d6dcea882f0d6e4c3c3703d6d11509996..34d93c93ebecb6e0f51f905366c33342b365fde4 100644
--- a/applications/utilities/surface/surfaceMeshExport/surfaceMeshExport.C
+++ b/applications/utilities/surface/surfaceMeshExport/surfaceMeshExport.C
@@ -76,7 +76,7 @@ int main(int argc, char *argv[])
     argList::noParallel();
     argList::validArgs.append("outputFile");
     argList::validOptions.insert("name",  "name");
-    argList::validOptions.insert("clean",  "scale");
+    argList::validOptions.insert("clean", "");
     argList::validOptions.insert("scaleIn",  "scale");
     argList::validOptions.insert("scaleOut", "scale");
     argList::validOptions.insert("dict", "coordinateSystemsDict");
diff --git a/applications/utilities/surface/surfaceMeshImport/surfaceMeshImport.C b/applications/utilities/surface/surfaceMeshImport/surfaceMeshImport.C
index 01ef15d74e60c8bd81b08b9c8842c2aed9c75d77..0cb131e4ebefded7fb56483c137ed23f55b3fc86 100644
--- a/applications/utilities/surface/surfaceMeshImport/surfaceMeshImport.C
+++ b/applications/utilities/surface/surfaceMeshImport/surfaceMeshImport.C
@@ -76,7 +76,7 @@ int main(int argc, char *argv[])
     argList::noParallel();
     argList::validArgs.append("inputFile");
     argList::validOptions.insert("name",  "name");
-    argList::validOptions.insert("clean",  "scale");
+    argList::validOptions.insert("clean", "");
     argList::validOptions.insert("scaleIn",  "scale");
     argList::validOptions.insert("scaleOut", "scale");
     argList::validOptions.insert("dict", "coordinateSystemsDict");
diff --git a/etc/controlDict b/etc/controlDict
index 5cbe331fe591645ef53c22cab6b50f499a53427a..65058af1a6c6a324f826be3d8b22ec9425195b96 100644
--- a/etc/controlDict
+++ b/etc/controlDict
@@ -360,7 +360,7 @@ DebugSwitches
     diagonal            0;
     dictionary          0;
     dimensionSet        1;
-    directMapped        0;
+    directMappedBase    0;
     directMappedPatch   0;
     directMappedVelocityFlux 0;
     directionMixed      0;
diff --git a/src/OpenFOAM/containers/Lists/List/List.C b/src/OpenFOAM/containers/Lists/List/List.C
index 6d20e2b3b72af3b5ec441d8c88668f2c9158b83c..429c91f820675d4ead0d17b1827dcca15fd9fbae 100644
--- a/src/OpenFOAM/containers/Lists/List/List.C
+++ b/src/OpenFOAM/containers/Lists/List/List.C
@@ -404,6 +404,61 @@ void Foam::List<T>::clear()
 }
 
 
+template<class T>
+void Foam::List<T>::append(const UList<T>& lst)
+{
+    if (this == &lst)
+    {
+        FatalErrorIn
+        (
+            "List<T>::append(const UList<T>&)"
+        )   << "attempted appending to self" << abort(FatalError);
+    }
+
+    label nextFree = this->size_;
+    setSize(nextFree + lst.size());
+
+    forAll(lst, elemI)
+    {
+        this->operator[](nextFree++) = lst[elemI];
+    }
+}
+
+
+template<class T>
+void Foam::List<T>::append(const UIndirectList<T>& lst)
+{
+    label nextFree = this->size_;
+    setSize(nextFree + lst.size());
+
+    forAll(lst, elemI)
+    {
+        this->operator[](nextFree++) = lst[elemI];
+    }
+}
+
+
+template<class T>
+void Foam::List<T>::append(const SLList<T>& lst)
+{
+    if (lst.size())
+    {
+        label nextFree = this->size_;
+        setSize(nextFree + lst.size());
+
+        for
+        (
+            typename SLList<T>::const_iterator iter = lst.begin();
+            iter != lst.end();
+            ++iter
+        )
+        {
+            this->operator[](nextFree++) = iter();
+        }
+    }
+}
+
+
 // Transfer the contents of the argument List into this List
 // and anull the argument list
 template<class T>
@@ -559,12 +614,9 @@ void Foam::List<T>::operator=(const IndirectList<T>& lst)
         if (this->size_) this->v_ = new T[this->size_];
     }
 
-    if (this->size_)
+    forAll(*this, i)
     {
-        forAll(*this, i)
-        {
-            this->operator[](i) = lst[i];
-        }
+        this->operator[](i) = lst[i];
     }
 }
 
@@ -581,12 +633,9 @@ void Foam::List<T>::operator=(const UIndirectList<T>& lst)
         if (this->size_) this->v_ = new T[this->size_];
     }
 
-    if (this->size_)
+    forAll(*this, i)
     {
-        forAll(*this, i)
-        {
-            this->operator[](i) = lst[i];
-        }
+        this->operator[](i) = lst[i];
     }
 }
 
@@ -603,12 +652,9 @@ void Foam::List<T>::operator=(const BiIndirectList<T>& lst)
         if (this->size_) this->v_ = new T[this->size_];
     }
 
-    if (this->size_)
+    forAll(*this, i)
     {
-        forAll(*this, i)
-        {
-            this->operator[](i) = lst[i];
-        }
+        this->operator[](i) = lst[i];
     }
 }
 
diff --git a/src/OpenFOAM/containers/Lists/List/List.H b/src/OpenFOAM/containers/Lists/List/List.H
index 86876cff713e4bbba54302df8a51bb127370a9d0..5961ff174793741a484f7955872108c471791d7b 100644
--- a/src/OpenFOAM/containers/Lists/List/List.H
+++ b/src/OpenFOAM/containers/Lists/List/List.H
@@ -109,7 +109,7 @@ public:
         List(const List<T>&);
 
         //- Construct by transferring the parameter contents
-        List(const Xfer<List<T> >&);
+        List(const Xfer< List<T> >&);
 
         //- Construct as copy or re-use as specified.
         List(List<T>&, bool reUse);
@@ -181,6 +181,15 @@ public:
             //- Clear the list, i.e. set size to zero.
             void clear();
 
+            //- Append a List at the end of this list
+            void append(const UList<T>&);
+
+            //- Append a UIndirectList at the end of this list
+            void append(const UIndirectList<T>&);
+
+            //- Append a SLList at the end of this list
+            void append(const SLList<T>&);
+
             //- Transfer the contents of the argument List into this List
             //  and annull the argument list.
             void transfer(List<T>&);
@@ -195,7 +204,7 @@ public:
             void transfer(SortableList<T>&);
 
             //- Transfer contents to the Xfer container
-            inline Xfer<List<T> > xfer();
+            inline Xfer< List<T> > xfer();
 
             //- Return subscript-checked element of UList.
             inline T& newElmt(const label);
diff --git a/src/OpenFOAM/containers/Lists/PackedList/PackedList.H b/src/OpenFOAM/containers/Lists/PackedList/PackedList.H
index af0f5cb5e03940d22f44d0f791650f954430e69e..1e6070e8368ad3a93d765fa112f0febe4ecb9452 100644
--- a/src/OpenFOAM/containers/Lists/PackedList/PackedList.H
+++ b/src/OpenFOAM/containers/Lists/PackedList/PackedList.H
@@ -26,7 +26,7 @@ Class
     Foam::PackedList
 
 Description
-    A Dynamically allocatable list of packed unsigned ints.
+    A dynamically allocatable list of packed unsigned integers.
 
     The list resizing is similar to DynamicList, thus the methods clear()
     and setSize() behave like their DynamicList counterparts and the methods
@@ -38,7 +38,7 @@ Note
     In a const context, the '[]' operator simply returns the stored value,
     with out-of-range elements returned as zero.
     In a non-const context, the '[]' operator returns an iteratorBase, which
-    may not have a valid reference for out-of-range elements.
+    might not have a valid reference for out-of-range elements.
     The iteratorBase class handles the assignment of new values.
 
     Using the iteratorBase as a proxy allows assignment of values
@@ -50,11 +50,11 @@ Note
     @endcode
 
     Using get() or the '[]' operator are similarly fast. Looping and reading
-    with an iterator is approx. 15% slower, but can be more flexible.
+    via an iterator is approx. 15% slower, but can be more flexible.
 
     Using the set() operator (and the '[]' operator) are marginally slower
-    (approx. 5%) than using an iterator, but the set() method has an
-    advantage that it also returns a bool if the value changed.  This can be
+    (approx. 5%) than using an iterator, but the set() method has the
+    advantage of also returning a bool if the value changed.  This can be
     useful for branching on changed values.
 
     @code
@@ -65,7 +65,7 @@ Note
 
     The lazy evaluation used means that reading an out-of-range element
     returns zero, but does not affect the list size.  Even in a non-const
-    context, only the assigment causes the element to be created.
+    context, only the assigment itself causes the element to be created.
     For example,
     @code
         list.resize(4);
@@ -171,7 +171,7 @@ public:
         inline PackedList(const PackedList<nBits>&);
 
         //- Construct by transferring the parameter contents
-        inline PackedList(const Xfer<PackedList<nBits> >&);
+        inline PackedList(const Xfer< PackedList<nBits> >&);
 
         //- Construct from a list of labels
         PackedList(const UList<label>&);
@@ -240,7 +240,6 @@ public:
 
         //- Reserve allocation space for at least this size.
         //  Never shrinks the allocated size.
-        //  Optionally provide an initialization value for new elements.
         inline void reserve(const label);
 
         //- Clear the list, i.e. set addressable size to zero.
@@ -258,7 +257,7 @@ public:
         inline void transfer(PackedList<nBits>&);
 
         //- Transfer contents to the Xfer container
-        inline Xfer<PackedList<nBits> > xfer();
+        inline Xfer< PackedList<nBits> > xfer();
 
 
     // Member operators
@@ -413,7 +412,7 @@ public:
         //- iterator set to the beginning of the PackedList
         inline iterator begin();
 
-        //- iterator set to beyond the end of the HashTable
+        //- iterator set to beyond the end of the PackedList
         inline iterator end();
 
 
diff --git a/src/OpenFOAM/db/IOstreams/Sstreams/ISstream.C b/src/OpenFOAM/db/IOstreams/Sstreams/ISstream.C
index 01b92caceef2b29eddb3b53cfd10a1e2586eefca..482abb8bf38c3bccc018811a791b0df56f1d97ba 100644
--- a/src/OpenFOAM/db/IOstreams/Sstreams/ISstream.C
+++ b/src/OpenFOAM/db/IOstreams/Sstreams/ISstream.C
@@ -224,7 +224,16 @@ Foam::Istream& Foam::ISstream::read(token& t)
                 }
                 else
                 {
-                    t = label(atol(numberBuffer));
+                    long lt = atol(numberBuffer);
+                    t = label(lt);
+
+                    // If the integer is too large to be represented as a label
+                    // return it as a scalar
+                    if (t.labelToken() != lt)
+                    {
+                        isScalar = true;
+                        t = scalar(atof(numberBuffer));
+                    }
                 }
             }
             else
diff --git a/src/OpenFOAM/matrices/solution/solution.C b/src/OpenFOAM/matrices/solution/solution.C
index 8c37d28b427786e3b932ed6bccaf55c5c0fcb1ed..030b3df9ae1296ebc8d42fe69b725e89a29503d4 100644
--- a/src/OpenFOAM/matrices/solution/solution.C
+++ b/src/OpenFOAM/matrices/solution/solution.C
@@ -134,7 +134,7 @@ Foam::label Foam::solution::upgradeSolverDict
 
 
             // write out information to help people adjust to the new syntax
-            if (verbose)
+            if (verbose && Pstream::master())
             {
                 Info<< "// using new solver syntax:\n"
                     << iter().keyword() << subdict << endl;
diff --git a/src/OpenFOAM/meshes/boundBox/boundBox.H b/src/OpenFOAM/meshes/boundBox/boundBox.H
index e41b6efa46139795a8bb8f83f10e2329bc375fd0..38b852ef66a429a414911dd04545d9568e79745a 100644
--- a/src/OpenFOAM/meshes/boundBox/boundBox.H
+++ b/src/OpenFOAM/meshes/boundBox/boundBox.H
@@ -174,7 +174,7 @@ public:
 
         // Query
 
-            //- Completely contains other boundingBox? (inside or on edge)
+            //- Overlaps/touches boundingBox?
             bool overlaps(const boundBox& bb) const
             {
                 return
diff --git a/src/OpenFOAM/meshes/meshShapes/face/face.H b/src/OpenFOAM/meshes/meshShapes/face/face.H
index 07dd39f93fc2cfad8fe3225e0704ecd54e737f1f..25a4f8fbce5b70f44c74ffd36a7c42c45e14ce99 100644
--- a/src/OpenFOAM/meshes/meshShapes/face/face.H
+++ b/src/OpenFOAM/meshes/meshShapes/face/face.H
@@ -222,16 +222,16 @@ public:
         ) const;
 
         //- Fast intersection with a ray.
-        //  For a hit, the pointHit.distance() is the line parameter t :
-        //  intersection=p+t*q. Only defined for FULL_RAY or
-        //  HALF_RAY.
+        //  Does face-center decomposition and returns triangle intersection
+        //  point closest to p. See triangle::intersection for details.
         pointHit intersection
         (
             const point& p,
             const vector& q,
             const point& ctr,
             const pointField& meshPoints,
-            const intersection::algorithm alg
+            const intersection::algorithm alg,
+            const scalar tol = 0.0
         ) const;
 
         //- Return nearest point to face
diff --git a/src/OpenFOAM/meshes/meshShapes/face/faceIntersection.C b/src/OpenFOAM/meshes/meshShapes/face/faceIntersection.C
index b514af77499d00e66844fff35bcf9e78c48e0c9e..c5f9a80250b00e433d139011a9e2d2c7b33b28a3 100644
--- a/src/OpenFOAM/meshes/meshShapes/face/faceIntersection.C
+++ b/src/OpenFOAM/meshes/meshShapes/face/faceIntersection.C
@@ -136,7 +136,8 @@ Foam::pointHit Foam::face::intersection
     const vector& q,
     const point& ctr,
     const pointField& meshPoints,
-    const intersection::algorithm alg
+    const intersection::algorithm alg,
+    const scalar tol
 ) const
 {
     scalar nearestHitDist = VGREAT;
@@ -154,7 +155,7 @@ Foam::pointHit Foam::face::intersection
             meshPoints[f[pI]],
             meshPoints[f[fcIndex(pI)]],
             ctr
-        ).intersection(p, q, alg);
+        ).intersection(p, q, alg, tol);
 
         if (curHit.hit())
         {
diff --git a/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistribute.C b/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistribute.C
index f4cbe6e2f3a60e247b7ca2a384b3845c3dc58eec..4bd093e6412905bda8b5402d828fbdd362777ab0 100644
--- a/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistribute.C
+++ b/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistribute.C
@@ -205,7 +205,7 @@ Foam::mapDistribute::mapDistribute
     const labelList& recvProcs
 )
 :
-    constructSize_(sendProcs.size()),
+    constructSize_(0),
     schedulePtr_()
 {
     if (sendProcs.size() != recvProcs.size())
@@ -266,6 +266,8 @@ Foam::mapDistribute::mapDistribute
         {
             // I am the receiver.
             constructMap_[sendProc][nRecv[sendProc]++] = sampleI;
+            // Largest entry inside constructMap
+            constructSize_ = sampleI+1;
         }
     }
 }
diff --git a/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistribute.H b/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistribute.H
index 4687c8a4b1d080087f06d3845361fd18b50513ec..3ccf81047697164d8cb2e7ed2a004a9feb8157f5 100644
--- a/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistribute.H
+++ b/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistribute.H
@@ -131,18 +131,36 @@ public:
                 return constructSize_;
             }
 
+            //- Constructed data size
+            label& constructSize()
+            {
+                return constructSize_;
+            }
+
             //- From subsetted data back to original data
             const labelListList& subMap() const
             {
                 return subMap_;
             }
 
+            //- From subsetted data back to original data
+            labelListList& subMap()
+            {
+                return subMap_;
+            }
+
             //- From subsetted data to new reconstructed data
             const labelListList& constructMap() const
             {
                 return constructMap_;
             }
 
+            //- From subsetted data to new reconstructed data
+            labelListList& constructMap()
+            {
+                return constructMap_;
+            }
+
             //- Calculate a schedule. See above.
             static List<labelPair> schedule
             (
diff --git a/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistributeTemplates.C b/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistributeTemplates.C
index 08e12b876eda2167a404c8879bda855ddd2ada2e..5f5d7a9fcf9793fe4f0c0df04e8c60e87e9c6d4f 100644
--- a/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistributeTemplates.C
+++ b/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistributeTemplates.C
@@ -52,13 +52,8 @@ void Foam::mapDistribute::distribute
 
             if (domain != Pstream::myProcNo() && map.size())
             {
-                List<T> subField(map.size());
-                forAll(map, i)
-                {
-                    subField[i] = field[map[i]];
-                }
                 OPstream toNbr(Pstream::blocking, domain);
-                toNbr << subField;
+                toNbr << UIndirectList<T>(field, map);
             }
         }
 
@@ -126,13 +121,7 @@ void Foam::mapDistribute::distribute
         List<T> newField(constructSize);
 
         // Subset myself
-        const labelList& mySubMap = subMap[Pstream::myProcNo()];
-
-        List<T> subField(mySubMap.size());
-        forAll(mySubMap, i)
-        {
-            subField[i] = field[mySubMap[i]];
-        }
+        UIndirectList<T> subField(field, subMap[Pstream::myProcNo()]);
 
         // Receive sub field from myself (subField)
         const labelList& map = constructMap[Pstream::myProcNo()];
@@ -152,16 +141,8 @@ void Foam::mapDistribute::distribute
             if (Pstream::myProcNo() == sendProc)
             {
                 // I am sender. Send to recvProc.
-                const labelList& map = subMap[recvProc];
-
-                List<T> subField(map.size());
-                forAll(map, i)
-                {
-                    subField[i] = field[map[i]];
-                }
-
                 OPstream toNbr(Pstream::scheduled, recvProc);
-                toNbr << subField;
+                toNbr << UIndirectList<T>(field, subMap[recvProc]);
             }
             else
             {
@@ -374,13 +355,8 @@ void Foam::mapDistribute::distribute
 
             if (domain != Pstream::myProcNo() && map.size())
             {
-                List<T> subField(map.size());
-                forAll(map, i)
-                {
-                    subField[i] = field[map[i]];
-                }
                 OPstream toNbr(Pstream::blocking, domain);
-                toNbr << subField;
+                toNbr << UIndirectList<T>(field, map);
             }
         }
 
@@ -449,13 +425,7 @@ void Foam::mapDistribute::distribute
         List<T> newField(constructSize, nullValue);
 
         // Subset myself
-        const labelList& mySubMap = subMap[Pstream::myProcNo()];
-
-        List<T> subField(mySubMap.size());
-        forAll(mySubMap, i)
-        {
-            subField[i] = field[mySubMap[i]];
-        }
+        UIndirectList<T> subField(field, subMap[Pstream::myProcNo()]);
 
         // Receive sub field from myself (subField)
         const labelList& map = constructMap[Pstream::myProcNo()];
@@ -475,16 +445,8 @@ void Foam::mapDistribute::distribute
             if (Pstream::myProcNo() == sendProc)
             {
                 // I am sender. Send to recvProc.
-                const labelList& map = subMap[recvProc];
-
-                List<T> subField(map.size());
-                forAll(map, i)
-                {
-                    subField[i] = field[map[i]];
-                }
-
                 OPstream toNbr(Pstream::scheduled, recvProc);
-                toNbr << subField;
+                toNbr << UIndirectList<T>(field, subMap[recvProc]);
             }
             else
             {
diff --git a/src/OpenFOAM/meshes/primitiveMesh/PatchTools/PatchToolsCheck.C b/src/OpenFOAM/meshes/primitiveMesh/PatchTools/PatchToolsCheck.C
index 5fcec15c9586e44f9e52b267d9f02c2ec585e396..a644cd1934901290b85d83305034cb6f2bdf3d9d 100644
--- a/src/OpenFOAM/meshes/primitiveMesh/PatchTools/PatchToolsCheck.C
+++ b/src/OpenFOAM/meshes/primitiveMesh/PatchTools/PatchToolsCheck.C
@@ -58,7 +58,7 @@ Foam::PatchTools::checkOrientation
             {
                 Info<< "Face[" << faceI << "] " << p[faceI]
                     << " has fewer than 3 edges. Edges: " << edgeLabels
-                    << nl;
+                    << endl;
             }
             valid = false;
         }
@@ -70,10 +70,12 @@ Foam::PatchTools::checkOrientation
                 {
                     if (report)
                     {
-                        Info<< "edge number " << edgeLabels[i] << " on face " << faceI
+                        Info<< "edge number " << edgeLabels[i]
+                            << " on face " << faceI
                             << " out-of-range\n"
                             << "This usually means the input surface has "
-                            << "edges with more than 2 faces connected." << nl;
+                            << "edges with more than 2 faces connected."
+                            << endl;
                     }
                     valid = false;
                 }
@@ -91,9 +93,9 @@ Foam::PatchTools::checkOrientation
         //- Compute normal from 3 points, use the first as the origin
         // minor warpage should not be a problem
         const Face& f = p[faceI];
-        const point p0(p.points()[f[0]]);
-        const point p1(p.points()[f[1]]);
-        const point p2(p.points()[f[f.size()-1]]);
+        const point& p0 = p.points()[f[0]];
+        const point& p1 = p.points()[f[1]];
+        const point& p2 = p.points()[f[f.size()-1]];
 
         const vector pointNormal((p1 - p0) ^ (p2 - p0));
         if ((pointNormal & p.faceNormals()[faceI]) < 0)
@@ -103,12 +105,12 @@ Foam::PatchTools::checkOrientation
             if (report)
             {
                 Info
-                    << "Normal calculated from points inconsistent with faceNormal"
-                    << nl
+                    << "Normal calculated from points inconsistent"
+                    << " with faceNormal" << nl
                     << "face: " << f << nl
                     << "points: " << p0 << ' ' << p1 << ' ' << p2 << nl
                     << "pointNormal:" << pointNormal << nl
-                    << "faceNormal:" << p.faceNormals()[faceI] << nl;
+                    << "faceNormal:" << p.faceNormals()[faceI] << endl;
             }
         }
     }
diff --git a/src/OpenFOAM/meshes/primitiveShapes/triangle/triangle.H b/src/OpenFOAM/meshes/primitiveShapes/triangle/triangle.H
index b24149300f5bd1aa8bd7939c0eb2a7f2c13c7671..3bc3ea38a809c1850057de2d25cc73d0cdc2413b 100644
--- a/src/OpenFOAM/meshes/primitiveShapes/triangle/triangle.H
+++ b/src/OpenFOAM/meshes/primitiveShapes/triangle/triangle.H
@@ -153,7 +153,7 @@ public:
             inline scalar sweptVol(const triangle& t) const;
 
             //- Return point intersection with a ray.
-            //  For a hit, the distance is signed.  Positive number
+            //  For a hit, the distance is signed. Positive number
             //  represents the point in front of triangle.
             //  In case of miss pointHit is set to nearest point
             //  on triangle and its distance to the distance between
@@ -169,12 +169,14 @@ public:
             //- Fast intersection with a ray.
             //  For a hit, the pointHit.distance() is the line parameter t :
             //  intersection=p+t*q. Only defined for VISIBLE, FULL_RAY or
-            //  HALF_RAY.
+            //  HALF_RAY. tol increases the virtual size of the triangle
+            // by a relative factor.
             inline pointHit intersection
             (
                 const point& p,
                 const vector& q,
-                const intersection::algorithm alg
+                const intersection::algorithm alg,
+                const scalar tol = 0.0
             ) const;
 
             //- Return nearest point to p on triangle
diff --git a/src/OpenFOAM/meshes/primitiveShapes/triangle/triangleI.H b/src/OpenFOAM/meshes/primitiveShapes/triangle/triangleI.H
index ad7ed2ea8bdd307ad249437a5d0e756ee4e31f74..33b3cab15e67775129d8997818a299add2d687f9 100644
--- a/src/OpenFOAM/meshes/primitiveShapes/triangle/triangleI.H
+++ b/src/OpenFOAM/meshes/primitiveShapes/triangle/triangleI.H
@@ -439,7 +439,8 @@ inline pointHit triangle<Point, PointRef>::intersection
 (
     const point& orig,
     const vector& dir,
-    const intersection::algorithm alg
+    const intersection::algorithm alg,
+    const scalar tol
 ) const
 {
     const vector edge1 = b_ - a_;
@@ -457,99 +458,61 @@ inline pointHit triangle<Point, PointRef>::intersection
     if (alg == intersection::VISIBLE)
     {
         // Culling branch
-        if (det < SMALL)
+        if (det < ROOTVSMALL)
         {
-            // return miss
+            // Ray on wrong side of triangle. Return miss
             return intersection;
         }
-        /* calculate distance from a_ to ray origin */
-        const vector tVec = orig-a_;
-
-        /* calculate U parameter and test bounds */
-        scalar u = tVec & pVec;
-
-        if (u < 0.0 || u > det)
-        {
-            // return miss
-            return intersection;
-        }
-
-        /* prepare to test V parameter */
-        const vector qVec = tVec ^ edge1;
-
-        /* calculate V parameter and test bounds */
-        scalar v = dir & qVec;
-
-        if (v < 0.0 || u + v > det)
-        {
-            // return miss
-            return intersection;
-        }
-
-        /* calculate t, scale parameters, ray intersects triangle */
-        scalar t = edge2 & qVec;
-        scalar inv_det = 1.0 / det;
-        t *= inv_det;
-        u *= inv_det;
-        v *= inv_det;
-
-        intersection.setHit();
-        intersection.setPoint(a_ + u*edge1 + v*edge2);
-        intersection.setDistance(t);
     }
     else if (alg == intersection::HALF_RAY || alg == intersection::FULL_RAY)
     {
         // Non-culling branch
-        if (det > -SMALL && det < SMALL)
+        if (det > -ROOTVSMALL && det < ROOTVSMALL)
         {
-            // return miss
+            // Ray parallel to triangle. Return miss
             return intersection;
         }
-        const scalar inv_det = 1.0 / det;
+    }
 
-        /* calculate distance from a_ to ray origin */
-        const vector tVec = orig - a_;
-        /* calculate U parameter and test bounds */
-        const scalar u = (tVec & pVec)*inv_det;
+    const scalar inv_det = 1.0 / det;
 
-        if (u < 0.0 || u > 1.0)
-        {
-            // return miss
-            return intersection;
-        }
-        /* prepare to test V parameter */
-        const vector qVec = tVec ^ edge1;
-        /* calculate V parameter and test bounds */
-        const scalar v = (dir & qVec) * inv_det;
+    /* calculate distance from a_ to ray origin */
+    const vector tVec = orig-a_;
 
-        if (v < 0.0 || u + v > 1.0)
-        {
-            // return miss
-            return intersection;
-        }
-        /* calculate t, ray intersects triangle */
-        const scalar t = (edge2 & qVec) * inv_det;
+    /* calculate U parameter and test bounds */
+    const scalar u = (tVec & pVec)*inv_det;
 
-        if (alg == intersection::HALF_RAY && t < 0)
-        {
-            // return miss
-            return intersection;
-        }
+    if (u < -tol || u > 1.0+tol)
+    {
+        // return miss
+        return intersection;
+    }
 
-        intersection.setHit();
-        intersection.setPoint(a_ + u*edge1 + v*edge2);
-        intersection.setDistance(t);
+    /* prepare to test V parameter */
+    const vector qVec = tVec ^ edge1;
+
+    /* calculate V parameter and test bounds */
+    const scalar v = (dir & qVec) * inv_det;
+
+    if (v < -tol || u + v > 1.0+tol)
+    {
+        // return miss
+        return intersection;
     }
-    else
+
+    /* calculate t, scale parameters, ray intersects triangle */
+    const scalar t = (edge2 & qVec) * inv_det;
+
+    if (alg == intersection::HALF_RAY && t < -tol)
     {
-        FatalErrorIn
-        (
-            "triangle<Point, PointRef>::intersection(const point&"
-            ", const vector&, const intersection::algorithm)"
-        )   << "intersection only defined for VISIBLE, FULL_RAY or HALF_RAY"
-            << abort(FatalError);
+        // Wrong side of orig. Return miss
+        return intersection;
     }
 
+    intersection.setHit();
+    intersection.setPoint(a_ + u*edge1 + v*edge2);
+    intersection.setDistance(t);
+
     return intersection;
 }
 
@@ -622,7 +585,7 @@ inline bool triangle<Point, PointRef>::classify
 
     bool hit = false;
 
-    if (Foam::mag(u1) < SMALL)
+    if (Foam::mag(u1) < ROOTVSMALL)
     {
         beta = u0/u2;
 
diff --git a/src/autoMesh/autoHexMesh/autoHexMeshDriver/autoHexMeshDriver.H b/src/autoMesh/autoHexMesh/autoHexMeshDriver/autoHexMeshDriver.H
index 9ae910b5a71c19965794151be42ef0d9759603d4..c0b7668d0ac6e68c56ab8a5a6546a61ce48b289d 100644
--- a/src/autoMesh/autoHexMesh/autoHexMeshDriver/autoHexMeshDriver.H
+++ b/src/autoMesh/autoHexMesh/autoHexMeshDriver/autoHexMeshDriver.H
@@ -38,7 +38,6 @@ SourceFiles
 
 #include "autoPtr.H"
 #include "dictionary.H"
-#include "boolList.H"
 #include "wallPoint.H"
 #include "searchableSurfaces.H"
 #include "refinementSurfaces.H"
diff --git a/src/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriver.C b/src/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriver.C
index 8d3c0e1e76bc2adaa66e67ffbc402c8c0f87fa43..ee6cea3e121be5c1a516d7424d82107fa9c0bbee 100644
--- a/src/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriver.C
+++ b/src/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriver.C
@@ -45,6 +45,7 @@ Description
 #include "OFstream.H"
 #include "layerParameters.H"
 #include "combineFaces.H"
+#include "IOmanip.H"
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
@@ -1414,8 +1415,11 @@ void Foam::autoLayerDriver::calculateLayerThickness
     const indirectPrimitivePatch& pp,
     const labelList& patchIDs,
     const scalarField& patchExpansionRatio,
-    const scalarField& patchFinalLayerRatio,
-    const scalarField& patchRelMinThickness,
+
+    const bool relativeSizes,
+    const scalarField& patchFinalLayerThickness,
+    const scalarField& patchMinThickness,
+
     const labelList& cellLevel,
     const labelList& patchNLayers,
     const scalar edge0Len,
@@ -1428,22 +1432,100 @@ void Foam::autoLayerDriver::calculateLayerThickness
     const fvMesh& mesh = meshRefiner_.mesh();
     const polyBoundaryMesh& patches = mesh.boundaryMesh();
 
-    if (min(patchRelMinThickness) < 0 || max(patchRelMinThickness) > 2)
+
+    // Rework patch-wise layer parameters into minimum per point
+    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+    // Reuse input fields
+    expansionRatio.setSize(pp.nPoints());
+    expansionRatio = GREAT;
+    thickness.setSize(pp.nPoints());
+    thickness = GREAT;
+    minThickness.setSize(pp.nPoints());
+    minThickness = GREAT;
+
+    forAll(patchIDs, i)
     {
-        FatalErrorIn("calculateLayerThickness(..)")
-            << "Thickness should be factor of local undistorted cell size."
-            << " Valid values are [0..2]." << nl
-            << " minThickness:" << patchRelMinThickness
-            << exit(FatalError);
+        label patchI = patchIDs[i];
+
+        const labelList& meshPoints = patches[patchI].meshPoints();
+
+        forAll(meshPoints, patchPointI)
+        {
+            label ppPointI = pp.meshPointMap()[meshPoints[patchPointI]];
+
+            expansionRatio[ppPointI] = min
+            (
+                expansionRatio[ppPointI],
+                patchExpansionRatio[patchI]
+            );
+            thickness[ppPointI] = min
+            (
+                thickness[ppPointI],
+                patchFinalLayerThickness[patchI]
+            );
+            minThickness[ppPointI] = min
+            (
+                minThickness[ppPointI],
+                patchMinThickness[patchI]
+            );
+        }
     }
 
+    syncTools::syncPointList
+    (
+        mesh,
+        pp.meshPoints(),
+        expansionRatio,
+        minEqOp<scalar>(),
+        GREAT,              // null value
+        false               // no separation
+    );
+    syncTools::syncPointList
+    (
+        mesh,
+        pp.meshPoints(),
+        thickness,
+        minEqOp<scalar>(),
+        GREAT,              // null value
+        false               // no separation
+    );
+    syncTools::syncPointList
+    (
+        mesh,
+        pp.meshPoints(),
+        minThickness,
+        minEqOp<scalar>(),
+        GREAT,              // null value
+        false               // no separation
+    );
+
 
-    // Per point the max cell level of connected cells
-    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+    // Now the thicknesses are set according to the minimum of connected
+    // patches.
 
-    labelList maxPointLevel(pp.nPoints(), labelMin);
 
+    // Rework relative thickness into absolute
+    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+    // by multiplying with the internal cell size.
+
+    if (relativeSizes)
     {
+        if (min(patchMinThickness) < 0 || max(patchMinThickness) > 2)
+        {
+            FatalErrorIn("calculateLayerThickness(..)")
+                << "Thickness should be factor of local undistorted cell size."
+                << " Valid values are [0..2]." << nl
+                << " minThickness:" << patchMinThickness
+                << exit(FatalError);
+        }
+
+
+        // Determine per point the max cell level of connected cells
+        // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+        labelList maxPointLevel(pp.nPoints(), labelMin);
+
         forAll(pp, i)
         {
             label ownLevel = cellLevel[mesh.faceOwner()[pp.addressing()[i]]];
@@ -1465,113 +1547,44 @@ void Foam::autoLayerDriver::calculateLayerThickness
             labelMin,           // null value
             false               // no separation
         );
-    }
 
 
-    // Rework patch-wise layer parameters into minimum per point
-    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-    expansionRatio.setSize(pp.nPoints());
-    expansionRatio = GREAT;
-    scalarField finalLayerRatio(pp.nPoints(), GREAT);
-    scalarField relMinThickness(pp.nPoints(), GREAT);
-
-    {
-        forAll(patchIDs, i)
+        forAll(maxPointLevel, pointI)
         {
-            label patchI = patchIDs[i];
-
-            const labelList& meshPoints = patches[patchI].meshPoints();
-
-            forAll(meshPoints, patchPointI)
-            {
-                label ppPointI = pp.meshPointMap()[meshPoints[patchPointI]];
-
-                expansionRatio[ppPointI] = min
-                (
-                    expansionRatio[ppPointI],
-                    patchExpansionRatio[patchI]
-                );
-                finalLayerRatio[ppPointI] = min
-                (
-                    finalLayerRatio[ppPointI],
-                    patchFinalLayerRatio[patchI]
-                );
-                relMinThickness[ppPointI] = min
-                (
-                    relMinThickness[ppPointI],
-                    patchRelMinThickness[patchI]
-                );
-            }
+            // Find undistorted edge size for this level.
+            scalar edgeLen = edge0Len/(1<<maxPointLevel[pointI]);
+            thickness[pointI] *= edgeLen;
+            minThickness[pointI] *= edgeLen;
         }
-
-        syncTools::syncPointList
-        (
-            mesh,
-            pp.meshPoints(),
-            expansionRatio,
-            minEqOp<scalar>(),
-            GREAT,              // null value
-            false               // no separation
-        );
-        syncTools::syncPointList
-        (
-            mesh,
-            pp.meshPoints(),
-            finalLayerRatio,
-            minEqOp<scalar>(),
-            GREAT,              // null value
-            false               // no separation
-        );
-        syncTools::syncPointList
-        (
-            mesh,
-            pp.meshPoints(),
-            relMinThickness,
-            minEqOp<scalar>(),
-            GREAT,              // null value
-            false               // no separation
-        );
     }
 
 
 
-    // Per mesh point the expansion parameters
-    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-    thickness.setSize(pp.nPoints());
-    minThickness.setSize(pp.nPoints());
+    // Rework thickness (of final layer) into overall thickness of all layers
+    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-    forAll(maxPointLevel, pointI)
+    forAll(thickness, pointI)
     {
-        // Find undistorted edge size for this level.
-        scalar edgeLen = edge0Len/(1<<maxPointLevel[pointI]);
-
         // Calculate layer thickness based on expansion ratio
         // and final layer height
         if (expansionRatio[pointI] == 1)
         {
-            thickness[pointI] =
-                finalLayerRatio[pointI]
-              * patchNLayers[pointI]
-              * edgeLen;
-            minThickness[pointI] = relMinThickness[pointI]*edgeLen;
+            thickness[pointI] *= patchNLayers[pointI];
         }
         else
         {
+
             scalar invExpansion = 1.0 / expansionRatio[pointI];
             label nLay = patchNLayers[pointI];
-            thickness[pointI] =
-                finalLayerRatio[pointI]
-              * edgeLen
-              * (1.0 - pow(invExpansion, nLay))
+            thickness[pointI] *=
+                (1.0 - pow(invExpansion, nLay))
               / (1.0 - invExpansion);
-            minThickness[pointI] = relMinThickness[pointI]*edgeLen;
         }
     }
 
-    Info<< "calculateLayerThickness : min:" << gMin(thickness)
-        << " max:" << gMax(thickness) << endl;
+
+    //Info<< "calculateLayerThickness : min:" << gMin(thickness)
+    //    << " max:" << gMax(thickness) << endl;
 }
 
 
@@ -2292,7 +2305,7 @@ bool Foam::autoLayerDriver::cellsUseFace
 Foam::label Foam::autoLayerDriver::checkAndUnmark
 (
     const addPatchCellLayer& addLayer,
-    const dictionary& motionDict,
+    const dictionary& meshQualityDict,
     const indirectPrimitivePatch& pp,
     const fvMesh& newMesh,
 
@@ -2304,7 +2317,7 @@ Foam::label Foam::autoLayerDriver::checkAndUnmark
     // Check the resulting mesh for errors
     Info<< nl << "Checking mesh with layer ..." << endl;
     faceSet wrongFaces(newMesh, "wrongFaces", newMesh.nFaces()/1000);
-    motionSmoother::checkMesh(false, newMesh, motionDict, wrongFaces);
+    motionSmoother::checkMesh(false, newMesh, meshQualityDict, wrongFaces);
     Info<< "Detected " << returnReduce(wrongFaces.size(), sumOp<label>())
         << " illegal faces"
         << " (concave, zero area or negative cell pyramid volume)"
@@ -2474,8 +2487,8 @@ void Foam::autoLayerDriver::mergePatchFacesUndo
         << "      (cos:" << minCos << ')' << nl
         << "    - as long as the resulting face doesn't become concave"
         << " by more than "
-        << layerParams.concaveAngle()
-        << " degrees (0=straight, 180=fully concave)" << nl
+        << layerParams.concaveAngle() << " degrees" << nl
+        << "      (0=straight, 180=fully concave)" << nl
         << endl;
 
     label nChanged = mergePatchFacesUndo(minCos, concaveCos, motionDict);
@@ -2621,8 +2634,11 @@ void Foam::autoLayerDriver::addLayers
         pp,
         meshMover.adaptPatchIDs(),
         layerParams.expansionRatio(),
-        layerParams.finalLayerRatio(),
-        layerParams.minThickness(),
+
+        layerParams.relativeSizes(),        // thickness relative to cellsize?
+        layerParams.finalLayerThickness(),  // wanted thicknes
+        layerParams.minThickness(),         // minimum thickness
+
         cellLevel,
         patchNLayers,
         edge0Len,
@@ -2632,6 +2648,79 @@ void Foam::autoLayerDriver::addLayers
         expansionRatio
     );
 
+
+    // Print a bit
+    {
+        const polyBoundaryMesh& patches = mesh.boundaryMesh();
+
+        Info<< nl
+            << "patch               faces    layers avg thickness[m]" << nl
+            << "                                    near-wall overall" << nl
+            << "-----               -----    ------ --------- -------" << endl;
+
+        forAll(meshMover.adaptPatchIDs(), i)
+        {
+            label patchI = meshMover.adaptPatchIDs()[i];
+
+            const labelList& meshPoints = patches[patchI].meshPoints();
+
+            //scalar maxThickness = -VGREAT;
+            //scalar minThickness = VGREAT;
+            scalar sumThickness = 0;
+            scalar sumNearWallThickness = 0;
+
+            forAll(meshPoints, patchPointI)
+            {
+                label ppPointI = pp.meshPointMap()[meshPoints[patchPointI]];
+
+                //maxThickness = max(maxThickness, thickness[ppPointI]);
+                //minThickness = min(minThickness, thickness[ppPointI]);
+                sumThickness += thickness[ppPointI];
+
+                label nLay = patchNLayers[ppPointI];
+                if (nLay > 0)
+                {
+                    if (expansionRatio[ppPointI] == 1)
+                    {
+                        sumNearWallThickness += thickness[ppPointI]/nLay;
+                    }
+                    else
+                    {
+                        scalar s =
+                            (1.0-pow(expansionRatio[ppPointI], nLay))
+                          / (1.0-expansionRatio[ppPointI]);
+                        sumNearWallThickness += thickness[ppPointI]/s;
+                    }
+                }
+            }
+
+            label totNPoints = returnReduce(meshPoints.size(), sumOp<label>());
+
+            //reduce(maxThickness, maxOp<scalar>());
+            //reduce(minThickness, minOp<scalar>());
+            scalar avgThickness =
+                returnReduce(sumThickness, sumOp<scalar>())
+              / totNPoints;
+            scalar avgNearWallThickness =
+                returnReduce(sumNearWallThickness, sumOp<scalar>())
+              / totNPoints;
+
+            Info<< setf(ios_base::left) << setw(19) << patches[patchI].name();
+            //Sout.unsetf(ios_base::left);
+            Info<< setprecision(3)
+                << " " << setw(8)
+                << returnReduce(patches[patchI].size(), sumOp<scalar>())
+                << " " << setw(6) << layerParams.numLayers()[patchI]
+                << " " << setw(8) << avgNearWallThickness
+                << "  " << setw(8) << avgThickness
+                //<< " " << setw(8) << minThickness
+                //<< " " << setw(8) << maxThickness
+                << endl;
+        }
+        Info<< endl;
+    }
+
+
     // Calculate wall to medial axis distance for smoothing displacement
     // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
@@ -2709,8 +2798,12 @@ void Foam::autoLayerDriver::addLayers
     boolList flaggedCells;
     boolList flaggedFaces;
 
-    while (true)
+    for (label iteration = 0; iteration < layerParams.nLayerIter(); iteration++)
     {
+        Info<< nl
+            << "Layer addition iteration " << iteration << nl
+            << "--------------------------" << endl;
+
         // Make sure displacement is equal on both sides of coupled patches.
         syncPatchDisplacement
         (
@@ -2831,7 +2924,8 @@ void Foam::autoLayerDriver::addLayers
             nPatchFaceLayers
         );
 
-        // Calculate displacement for first layer for addPatchLayer
+        // Calculate displacement for first layer for addPatchLayer.
+        // (first layer = layer of cells next to the original mesh)
         vectorField firstDisp(patchNLayers.size(), vector::zero);
 
         forAll(patchNLayers, i)
@@ -2847,9 +2941,9 @@ void Foam::autoLayerDriver::addLayers
                     label nLay = nPatchPointLayers[i];
                     scalar h =
                         pow(expansionRatio[i], nLay - 1)
-                      * (mag(patchDisp[i])*(1.0 - expansionRatio[i]))
+                      * (1.0 - expansionRatio[i])
                       / (1.0 - pow(expansionRatio[i], nLay));
-                    firstDisp[i] = h/mag(patchDisp[i])*patchDisp[i];
+                    firstDisp[i] = h*patchDisp[i];
                 }
             }
         }
@@ -2864,7 +2958,7 @@ void Foam::autoLayerDriver::addLayers
             pp,
             nPatchFaceLayers,   // layers per face
             nPatchPointLayers,  // layers per point
-            firstDisp,          // thickness of first layer
+            firstDisp,          // thickness of layer nearest internal mesh
             meshMod
         );
 
@@ -2951,10 +3045,23 @@ void Foam::autoLayerDriver::addLayers
         }
 
         // Unset the extrusion at the pp.
+        const dictionary& meshQualityDict =
+        (
+            iteration < layerParams.nRelaxedIter()
+          ? motionDict
+          : motionDict.subDict("relaxed")
+        );
+
+        if (iteration >= layerParams.nRelaxedIter())
+        {
+            Info<< "Switched to relaxed meshQuality constraints." << endl;
+        }
+
+
         label nTotChanged = checkAndUnmark
         (
             addLayer,
-            motionDict,
+            meshQualityDict,
             pp,
             newMesh,
 
@@ -2976,6 +3083,8 @@ void Foam::autoLayerDriver::addLayers
         // Reset mesh points and start again
         meshMover.movePoints(oldPoints);
         meshMover.correct();
+
+        Info<< endl;
     }
 
 
diff --git a/src/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriver.H b/src/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriver.H
index 41662df8c92b42f1d66a5466e76fe18cd884b3ee..6cdec2004b68cbe8206b3e71c0dabc7387f0cd1d 100644
--- a/src/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriver.H
+++ b/src/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriver.H
@@ -255,9 +255,12 @@ class autoLayerDriver
                 (
                     const indirectPrimitivePatch& pp,
                     const labelList& patchIDs,
+
                     const scalarField& patchExpansionRatio,
-                    const scalarField& patchFinalLayerRatio,
-                    const scalarField& patchRelMinThickness,
+                    const bool relativeSizes,
+                    const scalarField& patchFinalLayerThickness,
+                    const scalarField& patchMinThickness,
+
                     const labelList& cellLevel,
                     const labelList& patchNLayers,
                     const scalar edge0Len,
diff --git a/src/autoMesh/autoHexMesh/autoHexMeshDriver/autoRefineDriver.C b/src/autoMesh/autoHexMesh/autoHexMeshDriver/autoRefineDriver.C
index e891cf761c7e452fa5003016cb4d92b868312997..9c4e0a17c521b8e06b4b2ecceb18ed80bb917d06 100644
--- a/src/autoMesh/autoHexMesh/autoHexMeshDriver/autoRefineDriver.C
+++ b/src/autoMesh/autoHexMesh/autoHexMeshDriver/autoRefineDriver.C
@@ -95,7 +95,7 @@ Foam::label Foam::autoRefineDriver::readFeatureEdges
         Info<< "Refinement level " << featureLevels[i]
             << " for all cells crossed by feature " << featFileName
             << " (" << featureMeshes[i].points().size() << " points, "
-            << featureMeshes[i].edges().size() << ")." << endl;
+            << featureMeshes[i].edges().size() << " edges)." << endl;
     }
 
     Info<< "Read feature lines in = "
diff --git a/src/autoMesh/autoHexMesh/autoHexMeshDriver/layerParameters/layerParameters.C b/src/autoMesh/autoHexMesh/autoHexMeshDriver/layerParameters/layerParameters.C
index ddf162dd0f2910d2aaaf89a0f2465a26b86926b7..fad664229652a22fa4f2949b69bc226009a7abbe 100644
--- a/src/autoMesh/autoHexMesh/autoHexMeshDriver/layerParameters/layerParameters.C
+++ b/src/autoMesh/autoHexMesh/autoHexMeshDriver/layerParameters/layerParameters.C
@@ -163,7 +163,8 @@ Foam::layerParameters::layerParameters
         numLayers_.size(),
         readScalar(dict.lookup("expansionRatio"))
     ),
-    finalLayerRatio_
+    relativeSizes_(false),
+    finalLayerThickness_
     (
         numLayers_.size(),
         readScalar(dict.lookup("finalLayerRatio"))
@@ -211,8 +212,24 @@ Foam::layerParameters::layerParameters
     (
         readLabel(dict.lookup("nBufferCellsNoExtrude"))
     ),
-    nSnap_(readLabel(dict.lookup("nSnap")))
-{}
+    nSnap_(readLabel(dict.lookup("nSnap"))),
+    nLayerIter_(readLabel(dict.lookup("nLayerIter"))),
+    nRelaxedIter_(labelMax)
+{
+    if (dict.found("nRelaxedIter"))
+    {
+        dict.lookup("nRelaxedIter") >> nRelaxedIter_;
+    }
+
+    if (nLayerIter_ < 0 || nRelaxedIter_ < 0)
+    {
+        FatalErrorIn("layerParameters::layerParameters(..)")
+            << "Layer iterations should be >= 0." << endl
+            << "nLayerIter:" << nLayerIter_
+            << " nRelaxedIter:" << nRelaxedIter_
+            << exit(FatalError);
+    }
+}
 
 
 // Construct from dictionary
@@ -228,10 +245,11 @@ Foam::layerParameters::layerParameters
         boundaryMesh.size(),
         readScalar(dict.lookup("expansionRatio"))
     ),
-    finalLayerRatio_
+    relativeSizes_(dict.lookup("relativeSizes")),
+    finalLayerThickness_
     (
         boundaryMesh.size(),
-        readScalar(dict.lookup("finalLayerRatio"))
+        readScalar(dict.lookup("finalLayerThickness"))
     ),
     minThickness_
     (
@@ -276,8 +294,24 @@ Foam::layerParameters::layerParameters
     (
         readLabel(dict.lookup("nBufferCellsNoExtrude"))
     ),
-    nSnap_(readLabel(dict.lookup("nRelaxIter")))
+    nSnap_(readLabel(dict.lookup("nRelaxIter"))),
+    nLayerIter_(readLabel(dict.lookup("nLayerIter"))),
+    nRelaxedIter_(labelMax)
 {
+    if (dict.found("nRelaxedIter"))
+    {
+        dict.lookup("nRelaxedIter") >> nRelaxedIter_;
+    }
+    if (nLayerIter_ < 0 || nRelaxedIter_ < 0)
+    {
+        FatalErrorIn("layerParameters::layerParameters(..)")
+            << "Layer iterations should be >= 0." << endl
+            << "nLayerIter:" << nLayerIter_
+            << " nRelaxedIter:" << nRelaxedIter_
+            << exit(FatalError);
+    }
+
+
     const dictionary& layersDict = dict.subDict("layers");
 
     forAll(boundaryMesh, patchI)
@@ -291,14 +325,21 @@ Foam::layerParameters::layerParameters
             numLayers_[patchI] =
                 readLabel(layerDict.lookup("nSurfaceLayers"));
 
-            //- Patch-wise layer parameters disabled for now. Just remove
-            //  settings in initialiser list and uncomment below.
-            //expansionRatio_[patchI] =
-            //    readScalar(layerDict.lookup("expansionRatio"));
-            //finalLayerRatio_[patchI] =
-            //    readScalar(layerDict.lookup("finalLayerRatio"));
-            //minThickness_[patchI] =
-            //    readScalar(layerDict.lookup("minThickness"));
+            layerDict.readIfPresent
+            (
+                "expansionRatio",
+                expansionRatio_[patchI]
+            );
+            layerDict.readIfPresent
+            (
+                "finalLayerThickness",
+                finalLayerThickness_[patchI]
+            );
+            layerDict.readIfPresent
+            (
+                "minThickness",
+                minThickness_[patchI]
+            );
         }
     }
 
diff --git a/src/autoMesh/autoHexMesh/autoHexMeshDriver/layerParameters/layerParameters.H b/src/autoMesh/autoHexMesh/autoHexMeshDriver/layerParameters/layerParameters.H
index d96ce97cbd2167d6f1aa51d736e5fd6a9baca943..766897f43f83cc31b30ce3e2967d00edf15d7620 100644
--- a/src/autoMesh/autoHexMesh/autoHexMeshDriver/layerParameters/layerParameters.H
+++ b/src/autoMesh/autoHexMesh/autoHexMeshDriver/layerParameters/layerParameters.H
@@ -39,6 +39,7 @@ SourceFiles
 #include "dictionary.H"
 #include "scalarField.H"
 #include "labelList.H"
+#include "Switch.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -70,14 +71,10 @@ class layerParameters
 
             scalarField expansionRatio_;
 
-            //- Wanted thickness of final added cell layer. If multiple layers
-            //  is the thickness of the layer furthest away from the wall.
-            //  Relative to undistorted size of cell outside layer.
-            scalarField finalLayerRatio_;
+            Switch relativeSizes_;
+
+            scalarField finalLayerThickness_;
 
-            //- Minimum thickness of cell layer. If for any reason layer
-            //  cannot be above minThickness do not add layer.
-            //  Relative to undistorted size of cell outside layer.
             scalarField minThickness_;
 
 
@@ -105,6 +102,10 @@ class layerParameters
 
         label nSnap_;
 
+        label nLayerIter_;
+
+        label nRelaxedIter_;
+
 
     // Private Member Functions
 
@@ -160,18 +161,27 @@ public:
                     return expansionRatio_;
                 }
 
+                //- Are size parameters relative to inner cell size or
+                //  absolute distances.
+                bool relativeSizes() const
+                {
+                    return relativeSizes_;
+                }
+
                 //- Wanted thickness of final added cell layer. If multiple
-                //  layers
-                //  is the thickness of the layer furthest away from the wall.
-                //  Relative to undistorted size of cell outside layer.
-                const scalarField& finalLayerRatio() const
+                //  layers is the thickness of the layer furthest away
+                //  from the wall (i.e. nearest the original mesh)
+                //  If relativeSize() this number is relative to undistorted
+                //  size of the cell outside layer.
+                const scalarField& finalLayerThickness() const
                 {
-                    return finalLayerRatio_;
+                    return finalLayerThickness_;
                 }
 
                 //- Minimum thickness of cell layer. If for any reason layer
                 //  cannot be above minThickness do not add layer.
-                //  Relative to undistorted size of cell outside layer.
+                //  If relativeSize() this number is relative to undistorted
+                //  size of the cell outside layer.
                 const scalarField& minThickness() const
                 {
                     return minThickness_;
@@ -196,26 +206,20 @@ public:
                 return nGrow_;
             }
 
-            // Number of smoothing iterations of surface normals 
+            //- Number of smoothing iterations of surface normals 
             label nSmoothSurfaceNormals() const
             {
                 return nSmoothSurfaceNormals_;
             }
 
-            // Number of smoothing iterations of interior mesh movement
-            // direction  
+            //- Number of smoothing iterations of interior mesh movement
+            //  direction  
             label nSmoothNormals() const
             {
                 return nSmoothNormals_;
             }
 
-            // Smooth layer thickness over surface patches
-            label nSmoothThickness() const
-            {
-                return nSmoothThickness_;
-            }
-
-            // Stop layer growth on highly warped cells 
+            //- Stop layer growth on highly warped cells 
             scalar maxFaceThicknessRatio() const
             {
                 return maxFaceThicknessRatio_;
@@ -226,20 +230,26 @@ public:
                 return layerTerminationCos_;
             }
 
-            // Reduce layer growth where ratio thickness to medial 
-            // distance is large 
+            //- Smooth layer thickness over surface patches
+            label nSmoothThickness() const
+            {
+                return nSmoothThickness_;
+            }
+
+            //- Reduce layer growth where ratio thickness to medial 
+            //  distance is large 
             scalar maxThicknessToMedialRatio() const
             {
                 return maxThicknessToMedialRatio_;
             }
 
-            // Angle used to pick up medial axis points
+            //- Angle used to pick up medial axis points
             scalar minMedianAxisAngleCos() const
             {
                 return minMedianAxisAngleCos_;
             }
 
-            // Create buffer region for new layer terminations
+            //- Create buffer region for new layer terminations
             label nBufferCellsNoExtrude() const
             {
                 return nBufferCellsNoExtrude_;
@@ -249,6 +259,24 @@ public:
             {
                 return nSnap_;
             }
+
+            // Overall
+
+                //- Number of overall layer addition iterations
+                label nLayerIter() const
+                {
+                    return nLayerIter_;
+                }
+
+                //- Number of iterations after which relaxed motion rules
+                //  are to be used.
+                label nRelaxedIter() const
+                {
+                    return nRelaxedIter_;
+                }
+
+
+
 };
 
 
diff --git a/src/autoMesh/autoHexMesh/autoHexMeshDriver/pointData/pointData.H b/src/autoMesh/autoHexMesh/autoHexMeshDriver/pointData/pointData.H
index ffb8a15d05505dbc74ec6703a1afdda3d7d53012..d27c62929d94e9ab167682fe5df98e6cb394cb1a 100644
--- a/src/autoMesh/autoHexMesh/autoHexMeshDriver/pointData/pointData.H
+++ b/src/autoMesh/autoHexMesh/autoHexMeshDriver/pointData/pointData.H
@@ -42,9 +42,7 @@ SourceFiles
 
 #include "point.H"
 #include "label.H"
-#include "scalar.H"
 #include "tensor.H"
-#include "pTraits.H"
 
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
diff --git a/src/autoMesh/autoHexMesh/autoHexMeshDriver/pointData/pointDataI.H b/src/autoMesh/autoHexMesh/autoHexMeshDriver/pointData/pointDataI.H
index 234d569f85010eb6feac5c26a70acf52cb57102a..9832bbf877d0fe53c81b2f679a21aecd091dfbc9 100644
--- a/src/autoMesh/autoHexMesh/autoHexMeshDriver/pointData/pointDataI.H
+++ b/src/autoMesh/autoHexMesh/autoHexMeshDriver/pointData/pointDataI.H
@@ -22,8 +22,6 @@ License
     along with OpenFOAM; if not, write to the Free Software Foundation,
     Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 
-Description
-
 \*---------------------------------------------------------------------------*/
 
 #include "polyMesh.H"
diff --git a/src/autoMesh/autoHexMesh/meshRefinement/meshRefinement.H b/src/autoMesh/autoHexMesh/meshRefinement/meshRefinement.H
index 0025f333323020779c7b72e7bbac2984afcf8121..06004c8a6e00bc12c093cb36afb2782638b4b2d3 100644
--- a/src/autoMesh/autoHexMesh/meshRefinement/meshRefinement.H
+++ b/src/autoMesh/autoHexMesh/meshRefinement/meshRefinement.H
@@ -47,7 +47,6 @@ SourceFiles
 #include "hexRef8.H"
 #include "mapPolyMesh.H"
 #include "autoPtr.H"
-#include "pointIOField.H"
 #include "labelPair.H"
 #include "indirectPrimitivePatch.H"
 #include "pointFieldsFwd.H"
diff --git a/src/autoMesh/autoHexMesh/meshRefinement/meshRefinementRefine.C b/src/autoMesh/autoHexMesh/meshRefinement/meshRefinementRefine.C
index d42ac05b2233d1657f30a6511c825344c531924e..7aabbc6321cf9132e9e5c271d46e15abd7e00673 100644
--- a/src/autoMesh/autoHexMesh/meshRefinement/meshRefinementRefine.C
+++ b/src/autoMesh/autoHexMesh/meshRefinement/meshRefinementRefine.C
@@ -328,7 +328,7 @@ Foam::label Foam::meshRefinement::markFeatureRefinement
     // Database to pass into trackedParticle::move
     trackedParticle::trackData td(cloud, maxFeatureLevel);
 
-    // Track all particles to their end position.
+    // Track all particles to their end position (= starting feature point)
     cloud.move(td);
 
     // Reset level
diff --git a/src/autoMesh/autoHexMesh/refinementSurfaces/refinementSurfaces.H b/src/autoMesh/autoHexMesh/refinementSurfaces/refinementSurfaces.H
index e8fd3614018be8a862d01814eb150be7de5aa953..cee48bbe1f5effc3ed9cc0f6ad59193c87dce62e 100644
--- a/src/autoMesh/autoHexMesh/refinementSurfaces/refinementSurfaces.H
+++ b/src/autoMesh/autoHexMesh/refinementSurfaces/refinementSurfaces.H
@@ -38,7 +38,6 @@ SourceFiles
 #ifndef refinementSurfaces_H
 #define refinementSurfaces_H
 
-#include "PackedBoolList.H"
 #include "triSurfaceGeoMesh.H"
 #include "triSurfaceFields.H"
 #include "vectorList.H"
diff --git a/src/autoMesh/autoHexMesh/trackedParticle/ExactParticle.C b/src/autoMesh/autoHexMesh/trackedParticle/ExactParticle.C
index bcf92e9747c92c3cdfd18c5ab63a002d47917681..237e35276c33e528be26b13430bc078ea66baab4 100644
--- a/src/autoMesh/autoHexMesh/trackedParticle/ExactParticle.C
+++ b/src/autoMesh/autoHexMesh/trackedParticle/ExactParticle.C
@@ -102,23 +102,7 @@ Foam::scalar Foam::ExactParticle<ParticleType>::trackToFace
         }
     }
 
-
-    if (hitFacei != -1)
-    {
-        if (trackFraction > 1.0)
-        {
-            // Nearest intersection beyond endPosition so we hit endPosition.
-            this->position_ = endPosition;
-            this->facei_ = -1;
-            return 1.0;
-        }
-        else
-        {
-            this->position_ = intersection;
-            this->facei_ = hitFacei;
-        }
-    }
-    else
+    if (hitFacei == -1)
     {
         // Did not find any intersection. Fall back to original approximate
         // algorithm
@@ -129,8 +113,23 @@ Foam::scalar Foam::ExactParticle<ParticleType>::trackToFace
         );
     }
 
+    if (trackFraction >= (1.0-SMALL))
+    {
+        // Nearest intersection beyond endPosition so we hit endPosition.
+        trackFraction = 1.0;
+        this->position_ = endPosition;
+        this->facei_ = -1;
+        return 1.0;
+    }
+    else
+    {
+        this->position_ = intersection;
+        this->facei_ = hitFacei;
+    }
+
 
-    // Normal situation (trackFraction 0..1)
+    // Normal situation (trackFraction 0..1). Straight copy
+    // of Particle::trackToFace.
 
     bool internalFace = this->cloud().internalFace(this->facei_);
 
diff --git a/src/decompositionMethods/decompositionMethods/Make/files b/src/decompositionMethods/decompositionMethods/Make/files
index 9707bc7f2e9852519615faea8ae993dfa2cf7c2b..2acbfd56060aa85ed912373d83bb9e58a00b675e 100644
--- a/src/decompositionMethods/decompositionMethods/Make/files
+++ b/src/decompositionMethods/decompositionMethods/Make/files
@@ -2,7 +2,10 @@ decompositionMethod/decompositionMethod.C
 geomDecomp/geomDecomp.C
 simpleGeomDecomp/simpleGeomDecomp.C
 hierarchGeomDecomp/hierarchGeomDecomp.C
-metisDecomp/metisDecomp.C
 manualDecomp/manualDecomp.C
 
+scotchDecomp/scotchDecomp.C
+
+metisDecomp/metisDecomp.C
+
 LIB = $(FOAM_LIBBIN)/libdecompositionMethods
diff --git a/src/decompositionMethods/decompositionMethods/Make/options b/src/decompositionMethods/decompositionMethods/Make/options
index 9ccb652d2bc1b807bb48da05d6b82456ffeabedb..97569aa663f2a4ab623cf3c5f30ec77cdbebd3c8 100644
--- a/src/decompositionMethods/decompositionMethods/Make/options
+++ b/src/decompositionMethods/decompositionMethods/Make/options
@@ -1,6 +1,8 @@
 EXE_INC = \
+    -I$(WM_THIRD_PARTY_DIR)/scotch_5.1/src/libscotch/lnInclude \
     -I$(WM_THIRD_PARTY_DIR)/metis-5.0pre2/include
 
 LIB_LIBS = \
+    -lscotch \
     -lmetis \
     -lGKlib
diff --git a/src/decompositionMethods/decompositionMethods/scotchDecomp/scotchDecomp.C b/src/decompositionMethods/decompositionMethods/scotchDecomp/scotchDecomp.C
new file mode 100644
index 0000000000000000000000000000000000000000..2746d8f4e9b86b3fb17bb178dfe6c61436f2cdad
--- /dev/null
+++ b/src/decompositionMethods/decompositionMethods/scotchDecomp/scotchDecomp.C
@@ -0,0 +1,425 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  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
+
+S       Strat=b{job=t,map=t,poli=S,sep=(m{asc=b{bnd=d{pass=40,dif=1,rem=1}f{move=80,pass=-1,bal=0.005},org=f{move=80,pass=-1,bal=0.005},width=3},low=h{pass=10}f{move=80,pass=-1,bal=0.0005},type=h,vert=80,rat=0.8}|m{asc=b{bnd=d{pass=40,dif=1,rem=1}f{move=80,pass=-1,bal=0.005},org=f{move=80,pass=-1,bal=0.005},width=3},low=h{pass=10}f{move=80,pass=-1,bal=0.0005},type=h,vert=80,rat=0.8})}
+\*---------------------------------------------------------------------------*/
+
+#include "scotchDecomp.H"
+#include "addToRunTimeSelectionTable.H"
+#include "floatScalar.H"
+#include "IFstream.H"
+#include "Time.H"
+#include "cyclicPolyPatch.H"
+
+extern "C"
+{
+#define OMPI_SKIP_MPICXX
+#include "module.h"
+#include "common.h"
+#include "scotch.h"
+}
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+    defineTypeNameAndDebug(scotchDecomp, 0);
+
+    addToRunTimeSelectionTable
+    (
+        decompositionMethod,
+        scotchDecomp,
+        dictionaryMesh
+    );
+}
+
+// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
+
+void Foam::scotchDecomp::check(const int retVal, const char* str)
+{
+    if (retVal)
+    {
+        FatalErrorIn("scotchDecomp::decompose(..)")
+            << "Called to scotch routine " << str << " failed."
+            << exit(FatalError);
+    }
+}
+
+
+// Call Metis with options from dictionary.
+Foam::label Foam::scotchDecomp::decompose
+(
+    const List<int>& adjncy,
+    const List<int>& xadj,
+
+    List<int>& finalDecomp
+)
+{
+    // Strategy
+    // ~~~~~~~~
+    // Default.
+    SCOTCH_Strat stradat;
+    check(SCOTCH_stratInit(&stradat), "SCOTCH_stratInit");
+    //SCOTCH_stratGraphMap(&stradat, &argv[i][2]);
+    //fprintf(stdout, "S\tStrat=");
+    //SCOTCH_stratSave(&stradat, stdout);
+    //fprintf(stdout, "\n");
+
+
+    // Graph
+    // ~~~~~
+
+    SCOTCH_Graph grafdat;
+    check(SCOTCH_graphInit(&grafdat), "SCOTCH_graphInit");
+    check
+    (
+        SCOTCH_graphBuild
+        (
+            &grafdat,
+            0,                      // baseval, c-style numbering
+            xadj.size()-1,          // vertnbr, nCells
+            xadj.begin(),           // verttab, start index per cell into adjncy
+            &xadj[1],               // vendtab, end index  ,,
+            NULL,                   // velotab, vertex weights
+            NULL,                   // vlbltab
+            adjncy.size(),          // edgenbr, number of arcs
+            adjncy.begin(),         // edgetab
+            NULL                    // edlotab, edge weights
+        ),
+        "SCOTCH_graphBuild"
+    );
+    check(SCOTCH_graphCheck(&grafdat), "SCOTCH_graphCheck");
+
+
+
+    //// Architecture
+    //// ~~~~~~~~~~~~
+    //// (fully connected network topology since using switch)
+    //
+    //SCOTCH_Arch archdat;
+    //check(SCOTCH_archInit(&archdat), "SCOTCH_archInit");
+    //check
+    //(
+    //    // SCOTCH_archCmpltw for weighted.
+    //    SCOTCH_archCmplt(&archdat, nProcessors_),
+    //    "SCOTCH_archCmplt"
+    //);
+
+
+
+
+    //SCOTCH_Mapping mapdat;
+    //SCOTCH_graphMapInit(&grafdat, &mapdat, &archdat, NULL);
+    //SCOTCH_graphMapCompute(&grafdat, &mapdat, &stradat); /* Perform mapping */
+
+
+    finalDecomp.setSize(xadj.size()-1);
+    check
+    (
+        SCOTCH_graphPart
+        (
+            &grafdat,
+            nProcessors_,       // partnbr
+            &stradat,           // const SCOTCH_Strat * 
+            finalDecomp.begin() // parttab
+        ),
+        "SCOTCH_graphPart"
+    );
+
+    // Release storage for graph
+    SCOTCH_graphExit(&grafdat);
+    SCOTCH_stratExit(&stradat);
+    //// Release storage for network topology
+    //SCOTCH_archExit(&archdat);
+
+    return 0;
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::scotchDecomp::scotchDecomp
+(
+    const dictionary& decompositionDict,
+    const polyMesh& mesh
+)
+:
+    decompositionMethod(decompositionDict),
+    mesh_(mesh)
+{}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+Foam::labelList Foam::scotchDecomp::decompose(const pointField& points)
+{
+    if (points.size() != mesh_.nCells())
+    {
+        FatalErrorIn("scotchDecomp::decompose(const pointField&)")
+            << "Can use this decomposition method only for the whole mesh"
+            << endl
+            << "and supply one coordinate (cellCentre) for every cell." << endl
+            << "The number of coordinates " << points.size() << endl
+            << "The number of cells in the mesh " << mesh_.nCells()
+            << exit(FatalError);
+    }
+
+    // Make Metis CSR (Compressed Storage Format) storage
+    //   adjncy      : contains neighbours (= edges in graph)
+    //   xadj(celli) : start of information in adjncy for celli
+
+    List<int> xadj(mesh_.nCells()+1);
+
+    // Initialise the number of internal faces of the cells to twice the
+    // number of internal faces
+    label nInternalFaces = 2*mesh_.nInternalFaces();
+
+    // Check the boundary for coupled patches and add to the number of
+    // internal faces
+    const polyBoundaryMesh& pbm = mesh_.boundaryMesh();
+
+    forAll(pbm, patchi)
+    {
+        if (isA<cyclicPolyPatch>(pbm[patchi]))
+        {
+            nInternalFaces += pbm[patchi].size();
+        }
+    }
+
+    // Create the adjncy array the size of the total number of internal and
+    // coupled faces
+    List<int> adjncy(nInternalFaces);
+
+    // Fill in xadj
+    // ~~~~~~~~~~~~
+    label freeAdj = 0;
+
+    for (label cellI = 0; cellI < mesh_.nCells(); cellI++)
+    {
+        xadj[cellI] = freeAdj;
+
+        const labelList& cFaces = mesh_.cells()[cellI];
+
+        forAll(cFaces, i)
+        {
+            label faceI = cFaces[i];
+
+            if
+            (
+                mesh_.isInternalFace(faceI)
+             || isA<cyclicPolyPatch>(pbm[pbm.whichPatch(faceI)])
+            )
+            {
+                freeAdj++;
+            }
+        }
+    }
+    xadj[mesh_.nCells()] = freeAdj;
+
+
+    // Fill in adjncy
+    // ~~~~~~~~~~~~~~
+
+    labelList nFacesPerCell(mesh_.nCells(), 0);
+
+    // Internal faces
+    for (label faceI = 0; faceI < mesh_.nInternalFaces(); faceI++)
+    {
+        label own = mesh_.faceOwner()[faceI];
+        label nei = mesh_.faceNeighbour()[faceI];
+
+        adjncy[xadj[own] + nFacesPerCell[own]++] = nei;
+        adjncy[xadj[nei] + nFacesPerCell[nei]++] = own;
+    }
+
+    // Coupled faces. Only cyclics done.
+    forAll(pbm, patchi)
+    {
+        if (isA<cyclicPolyPatch>(pbm[patchi]))
+        {
+            const unallocLabelList& faceCells = pbm[patchi].faceCells();
+
+            label sizeby2 = faceCells.size()/2;
+
+            for (label facei=0; facei<sizeby2; facei++)
+            {
+                label own = faceCells[facei];
+                label nei = faceCells[facei + sizeby2];
+
+                adjncy[xadj[own] + nFacesPerCell[own]++] = nei;
+                adjncy[xadj[nei] + nFacesPerCell[nei]++] = own;
+            }
+        }
+    }
+
+    // Decompose using default weights
+    List<int> finalDecomp;
+    decompose(adjncy, xadj, finalDecomp);
+
+    // Copy back to labelList
+    labelList decomp(finalDecomp.size());
+    forAll(decomp, i)
+    {
+        decomp[i] = finalDecomp[i];
+    }
+    return decomp;
+}
+
+
+// From cell-cell connections to Metis format (like CompactListList)
+void Foam::scotchDecomp::calcMetisCSR
+(
+    const labelListList& cellCells,
+    List<int>& adjncy,
+    List<int>& xadj
+)
+{
+    // Count number of internal faces
+    label nConnections = 0;
+
+    forAll(cellCells, coarseI)
+    {
+        nConnections += cellCells[coarseI].size();
+    }
+
+    // Create the adjncy array as twice the size of the total number of
+    // internal faces
+    adjncy.setSize(nConnections);
+
+    xadj.setSize(cellCells.size()+1);
+
+
+    // Fill in xadj
+    // ~~~~~~~~~~~~
+    label freeAdj = 0;
+
+    forAll(cellCells, coarseI)
+    {
+        xadj[coarseI] = freeAdj;
+
+        const labelList& cCells = cellCells[coarseI];
+
+        forAll(cCells, i)
+        {
+            adjncy[freeAdj++] = cCells[i];
+        }
+    }
+    xadj[cellCells.size()] = freeAdj;
+}
+
+
+Foam::labelList Foam::scotchDecomp::decompose
+(
+    const labelList& agglom,
+    const pointField& agglomPoints
+)
+{
+    if (agglom.size() != mesh_.nCells())
+    {
+        FatalErrorIn
+        (
+            "parMetisDecomp::decompose(const labelList&, const pointField&)"
+        )   << "Size of cell-to-coarse map " << agglom.size()
+            << " differs from number of cells in mesh " << mesh_.nCells()
+            << exit(FatalError);
+    }
+
+    // Make Metis CSR (Compressed Storage Format) storage
+    //   adjncy      : contains neighbours (= edges in graph)
+    //   xadj(celli) : start of information in adjncy for celli
+    List<int> adjncy;
+    List<int> xadj;
+    {
+        // Get cellCells on coarse mesh.
+        labelListList cellCells;
+        calcCellCells
+        (
+            mesh_,
+            agglom,
+            agglomPoints.size(),
+            cellCells
+        );
+
+        calcMetisCSR(cellCells, adjncy, xadj);
+    }
+
+    // Decompose using default weights
+    List<int> finalDecomp;
+    decompose(adjncy, xadj, finalDecomp);
+
+
+    // Rework back into decomposition for original mesh_
+    labelList fineDistribution(agglom.size());
+
+    forAll(fineDistribution, i)
+    {
+        fineDistribution[i] = finalDecomp[agglom[i]];
+    }
+
+    return fineDistribution;
+}
+
+
+Foam::labelList Foam::scotchDecomp::decompose
+(
+    const labelListList& globalCellCells,
+    const pointField& cellCentres
+)
+{
+    if (cellCentres.size() != globalCellCells.size())
+    {
+        FatalErrorIn
+        (
+            "scotchDecomp::decompose(const pointField&, const labelListList&)"
+        )   << "Inconsistent number of cells (" << globalCellCells.size()
+            << ") and number of cell centres (" << cellCentres.size()
+            << ")." << exit(FatalError);
+    }
+
+
+    // Make Metis CSR (Compressed Storage Format) storage
+    //   adjncy      : contains neighbours (= edges in graph)
+    //   xadj(celli) : start of information in adjncy for celli
+
+    List<int> adjncy;
+    List<int> xadj;
+    calcMetisCSR(globalCellCells, adjncy, xadj);
+
+
+    // Decompose using default weights
+    List<int> finalDecomp;
+    decompose(adjncy, xadj, finalDecomp);
+
+    // Copy back to labelList
+    labelList decomp(finalDecomp.size());
+    forAll(decomp, i)
+    {
+        decomp[i] = finalDecomp[i];
+    }
+    return decomp;
+}
+
+
+// ************************************************************************* //
diff --git a/src/decompositionMethods/decompositionMethods/scotchDecomp/scotchDecomp.H b/src/decompositionMethods/decompositionMethods/scotchDecomp/scotchDecomp.H
new file mode 100644
index 0000000000000000000000000000000000000000..e470f84f98c58170ee7bcc0f8e9298a1ba8f3a9e
--- /dev/null
+++ b/src/decompositionMethods/decompositionMethods/scotchDecomp/scotchDecomp.H
@@ -0,0 +1,150 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  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::scotchDecomp
+
+Description
+    Scotch domain decomposition
+
+SourceFiles
+    scotchDecomp.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef scotchDecomp_H
+#define scotchDecomp_H
+
+#include "decompositionMethod.H"
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+                           Class scotchDecomp Declaration
+\*---------------------------------------------------------------------------*/
+
+class scotchDecomp
+:
+    public decompositionMethod
+{
+    // Private data
+
+        const polyMesh& mesh_;
+
+
+    // Private Member Functions
+
+        //- Check and print error message
+        static void check(const int, const char*);
+
+        label decompose
+        (
+            const List<int>& adjncy,
+            const List<int>& xadj,
+            List<int>& finalDecomp
+        );
+
+        //- Disallow default bitwise copy construct and assignment
+        void operator=(const scotchDecomp&);
+        scotchDecomp(const scotchDecomp&);
+
+
+public:
+
+    //- Runtime type information
+    TypeName("scotch");
+
+
+    // Constructors
+
+        //- Construct given the decomposition dictionary and mesh
+        scotchDecomp
+        (
+            const dictionary& decompositionDict,
+            const polyMesh& mesh
+        );
+
+
+    // Destructor
+
+        virtual ~scotchDecomp()
+        {}
+
+
+    // Member Functions
+
+        virtual bool parallelAware() const
+        {
+            // Metis does not know about proc boundaries
+            return false;
+        }
+
+        //- Return for every coordinate the wanted processor number. Use the
+        //  mesh connectivity (if needed)
+        virtual labelList decompose(const pointField&);
+
+        //- Return for every coordinate the wanted processor number. Gets
+        //  passed agglomeration map (from fine to coarse cells) and coarse cell
+        //  location. Can be overridden by decomposers that provide this
+        //  functionality natively.
+        virtual labelList decompose
+        (
+            const labelList& agglom,
+            const pointField&
+        );
+
+        //- Return for every coordinate the wanted processor number. Explicitly
+        //  provided mesh connectivity.
+        //  The connectivity is equal to mesh.cellCells() except for
+        //  - in parallel the cell numbers are global cell numbers (starting
+        //    from 0 at processor0 and then incrementing all through the
+        //    processors)
+        //  - the connections are across coupled patches
+        virtual labelList decompose
+        (
+            const labelListList& globalCellCells,
+            const pointField& cc
+        );
+
+        //- Helper to convert cellcells into compact row storage
+        static void calcMetisCSR
+        (
+            const labelListList& globalCellCells,
+            List<int>& adjncy,
+            List<int>& xadj
+        );
+
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/dynamicMesh/motionSmoother/motionSmoother.C b/src/dynamicMesh/motionSmoother/motionSmoother.C
index 18f5c85478e301085d49ca0eb05980d00a96e333..4f40827f4b3a8030217e79098e6716f8db96e018 100644
--- a/src/dynamicMesh/motionSmoother/motionSmoother.C
+++ b/src/dynamicMesh/motionSmoother/motionSmoother.C
@@ -825,6 +825,28 @@ bool Foam::motionSmoother::scaleMesh
     const bool smoothMesh,
     const label nAllowableErrors
 )
+{
+    return scaleMesh
+    (
+        checkFaces,
+        baffles,
+        paramDict_,
+        paramDict_,
+        smoothMesh,
+        nAllowableErrors
+    );
+}
+
+
+bool Foam::motionSmoother::scaleMesh
+(
+    labelList& checkFaces,
+    const List<labelPair>& baffles,
+    const dictionary& paramDict,
+    const dictionary& meshQualityDict,
+    const bool smoothMesh,
+    const label nAllowableErrors
+)
 {
     if (!smoothMesh && adaptPatchIDs_.empty())
     {
@@ -859,9 +881,9 @@ bool Foam::motionSmoother::scaleMesh
     }
 
     const scalar errorReduction =
-        readScalar(paramDict_.lookup("errorReduction"));
+        readScalar(paramDict.lookup("errorReduction"));
     const label nSmoothScale =
-        readLabel(paramDict_.lookup("nSmoothScale"));
+        readLabel(paramDict.lookup("nSmoothScale"));
 
 
     // Note: displacement_ should already be synced already from setDisplacement
@@ -921,7 +943,7 @@ bool Foam::motionSmoother::scaleMesh
 
     // Check. Returns parallel number of incorrect faces.
     faceSet wrongFaces(mesh_, "wrongFaces", mesh_.nFaces()/100+100);
-    checkMesh(false, mesh_, paramDict_, checkFaces, baffles, wrongFaces);
+    checkMesh(false, mesh_, meshQualityDict, checkFaces, baffles, wrongFaces);
 
     if (returnReduce(wrongFaces.size(), sumOp<label>()) <= nAllowableErrors)
     {
diff --git a/src/dynamicMesh/motionSmoother/motionSmoother.H b/src/dynamicMesh/motionSmoother/motionSmoother.H
index e5777a366459e75bde147a3e7e420a719ea3a361..e4aeac6f50756ec9a5f27da2602aa80ddad26036 100644
--- a/src/dynamicMesh/motionSmoother/motionSmoother.H
+++ b/src/dynamicMesh/motionSmoother/motionSmoother.H
@@ -52,7 +52,7 @@ Description
     @endverbatim
 
 Note
-    Shared points (parallel): a processor can have points which are part of
+    - Shared points (parallel): a processor can have points which are part of
     pp on another processor but have no pp itself (i.e. it has points
     and/or edges but no faces of pp). Hence we have to be careful when e.g.
     synchronising displacements that the value from the processor which has
@@ -61,10 +61,13 @@ Note
     else. The combine operator used will give preference to non-zero
     values.
 
-    Various routines take baffles. These are sets of boundary faces that
+    - Various routines take baffles. These are sets of boundary faces that
     are treated as a single internal face. This is a hack used to apply
     movement to internal faces.
 
+    - Mesh constraints are looked up from the supplied dictionary. (uses
+    recursive lookup)
+
 SourceFiles
     motionSmoother.C
     motionSmootherTemplates.C
@@ -395,6 +398,17 @@ public:
                 const label nAllow = 0
             );
 
+            //- Move mesh with externally provided mesh constraints
+            bool scaleMesh
+            (
+                labelList& checkFaces,
+                const List<labelPair>& baffles,
+                const dictionary& paramDict,
+                const dictionary& meshQualityDict,
+                const bool smoothMesh = true,
+                const label nAllow = 0
+            );
+
             //- Update topology
             void updateMesh();
 
diff --git a/src/dynamicMesh/motionSmoother/motionSmootherCheck.C b/src/dynamicMesh/motionSmoother/motionSmootherCheck.C
index 06996c541f9270b8300eb5da110c9dfc521ed95b..7fcb9f1e7ac70660201f2a760565ac691aefd526 100644
--- a/src/dynamicMesh/motionSmoother/motionSmootherCheck.C
+++ b/src/dynamicMesh/motionSmoother/motionSmootherCheck.C
@@ -28,19 +28,6 @@ License
 #include "polyMeshGeometry.H"
 #include "IOmanip.H"
 
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-
-// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
-
-
-// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
-
-
-// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
-
-
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
 bool Foam::motionSmoother::checkMesh
@@ -74,17 +61,50 @@ bool Foam::motionSmoother::checkMesh
     labelHashSet& wrongFaces
 )
 {
-    const scalar maxNonOrtho(readScalar(dict.lookup("maxNonOrtho")));
-    const scalar minVol(readScalar(dict.lookup("minVol")));
-    const scalar maxConcave(readScalar(dict.lookup("maxConcave")));
-    const scalar minArea(readScalar(dict.lookup("minArea")));
-    const scalar maxIntSkew(readScalar(dict.lookup("maxInternalSkewness")));
-    const scalar maxBounSkew(readScalar(dict.lookup("maxBoundarySkewness")));
-    const scalar minWeight(readScalar(dict.lookup("minFaceWeight")));
-    const scalar minVolRatio(readScalar(dict.lookup("minVolRatio")));
-    const scalar minTwist(readScalar(dict.lookup("minTwist")));
-    const scalar minTriangleTwist(readScalar(dict.lookup("minTriangleTwist")));
-    const scalar minDet(readScalar(dict.lookup("minDeterminant")));
+    const scalar maxNonOrtho
+    (
+        readScalar(dict.lookup("maxNonOrtho", true))
+    );
+    const scalar minVol
+    (
+        readScalar(dict.lookup("minVol", true))
+    );
+    const scalar maxConcave
+    (
+        readScalar(dict.lookup("maxConcave", true))
+    );
+    const scalar minArea
+    (
+        readScalar(dict.lookup("minArea", true))
+    );
+    const scalar maxIntSkew
+    (
+        readScalar(dict.lookup("maxInternalSkewness", true))
+    );
+    const scalar maxBounSkew
+    (
+        readScalar(dict.lookup("maxBoundarySkewness", true))
+    );
+    const scalar minWeight
+    (
+        readScalar(dict.lookup("minFaceWeight", true))
+    );
+    const scalar minVolRatio
+    (
+        readScalar(dict.lookup("minVolRatio", true))
+    );
+    const scalar minTwist
+    (
+        readScalar(dict.lookup("minTwist", true))
+    );
+    const scalar minTriangleTwist
+    (
+        readScalar(dict.lookup("minTriangleTwist", true))
+    );
+    const scalar minDet
+    (
+        readScalar(dict.lookup("minDeterminant", true))
+    );
 
     label nWrongFaces = 0;
 
@@ -389,17 +409,50 @@ bool Foam::motionSmoother::checkMesh
     labelHashSet& wrongFaces
 )
 {
-    const scalar maxNonOrtho(readScalar(dict.lookup("maxNonOrtho")));
-    const scalar minVol(readScalar(dict.lookup("minVol")));
-    const scalar maxConcave(readScalar(dict.lookup("maxConcave")));
-    const scalar minArea(readScalar(dict.lookup("minArea")));
-    const scalar maxIntSkew(readScalar(dict.lookup("maxInternalSkewness")));
-    const scalar maxBounSkew(readScalar(dict.lookup("maxBoundarySkewness")));
-    const scalar minWeight(readScalar(dict.lookup("minFaceWeight")));
-    const scalar minVolRatio(readScalar(dict.lookup("minVolRatio")));
-    const scalar minTwist(readScalar(dict.lookup("minTwist")));
-    const scalar minTriangleTwist(readScalar(dict.lookup("minTriangleTwist")));
-    const scalar minDet(readScalar(dict.lookup("minDeterminant")));
+    const scalar maxNonOrtho
+    (
+        readScalar(dict.lookup("maxNonOrtho", true))
+    );
+    const scalar minVol
+    (
+        readScalar(dict.lookup("minVol", true))
+    );
+    const scalar maxConcave
+    (
+        readScalar(dict.lookup("maxConcave", true))
+    );
+    const scalar minArea
+    (
+        readScalar(dict.lookup("minArea", true))
+    );
+    const scalar maxIntSkew
+    (
+        readScalar(dict.lookup("maxInternalSkewness", true))
+    );
+    const scalar maxBounSkew
+    (
+        readScalar(dict.lookup("maxBoundarySkewness", true))
+    );
+    const scalar minWeight
+    (
+        readScalar(dict.lookup("minFaceWeight", true))
+    );
+    const scalar minVolRatio
+    (
+        readScalar(dict.lookup("minVolRatio", true))
+    );
+    const scalar minTwist
+    (
+        readScalar(dict.lookup("minTwist", true))
+    );
+    const scalar minTriangleTwist
+    (
+        readScalar(dict.lookup("minTriangleTwist", true))
+    );
+    const scalar minDet
+    (
+        readScalar(dict.lookup("minDeterminant", true))
+    );
 
     label nWrongFaces = 0;
 
diff --git a/src/dynamicMesh/polyTopoChange/polyTopoChange/addPatchCellLayer.H b/src/dynamicMesh/polyTopoChange/polyTopoChange/addPatchCellLayer.H
index ea6a7674e46d6d11275b6990497944c39c0e9002..f03d23e2144fb22c5a9f093f221ed5fd86dc4a42 100644
--- a/src/dynamicMesh/polyTopoChange/polyTopoChange/addPatchCellLayer.H
+++ b/src/dynamicMesh/polyTopoChange/polyTopoChange/addPatchCellLayer.H
@@ -294,9 +294,10 @@ public:
             //  - nPointLayers : number of layers per (patch)point
             //  - nFaceLayers : number of layers per (patch) face
             //  - firstDisplacement : displacement per point for first
-            //    layer of points. If zero do not add point.
+            //    layer of points (i.e. nearest to original mesh). If zero
+            //    do not add point.
             //  Layer thicknesses are calculated to constant geometric
-            //  expansion. Use expansionRatio for constant size.
+            //  expansion. Use expansionRatio 1 for constant size.
             //  Sets addedPoints_ which is per pp point a list of points
             //  added.
             //  Note: firstDisplacement has to be parallel synchronised before
diff --git a/src/engine/engineMesh/engineMesh/engineMesh.C b/src/engine/engineMesh/engineMesh/engineMesh.C
index d425ee75f272278007111890a5f7d43efe4a7c81..329c1a3963d68f3ecc8b50a82e151ce5c4fca55d 100644
--- a/src/engine/engineMesh/engineMesh/engineMesh.C
+++ b/src/engine/engineMesh/engineMesh/engineMesh.C
@@ -43,7 +43,7 @@ Foam::engineMesh::engineMesh(const IOobject& io)
     linerIndex_(-1),
     cylinderHeadIndex_(-1),
     deckHeight_("deckHeight", dimLength, GREAT),
-    pistonPosition_("deckHeight", dimLength, GREAT)
+    pistonPosition_("pistonPosition", dimLength, -GREAT)
 {
     bool foundPiston = false;
     bool foundLiner = false;
@@ -80,14 +80,14 @@ Foam::engineMesh::engineMesh(const IOobject& io)
     }
 
     if (!foundLiner)
-    { 
+    {
         FatalErrorIn("engineMesh::engineMesh(const IOobject& io)")
             << "cannot find liner patch"
             << exit(FatalError);
     }
 
     if (!foundCylinderHead)
-    { 
+    {
         FatalErrorIn("engineMesh::engineMesh(const IOobject& io)")
             << "cannot find cylinderHead patch"
             << exit(FatalError);
@@ -96,17 +96,25 @@ Foam::engineMesh::engineMesh(const IOobject& io)
     {
         if (pistonIndex_ != -1)
         {
-            pistonPosition_.value() =
-                max(boundary()[pistonIndex_].patch().localPoints()).z();
+            pistonPosition_.value() = -GREAT;
+            if (boundary()[pistonIndex_].patch().localPoints().size())
+            {
+                pistonPosition_.value() =
+                    max(boundary()[pistonIndex_].patch().localPoints()).z();
+            }
         }
-        reduce(pistonPosition_.value(), minOp<scalar>());
+        reduce(pistonPosition_.value(), maxOp<scalar>());
 
         if (cylinderHeadIndex_ != -1)
         {
-            deckHeight_.value() = min
-            (
-                boundary()[cylinderHeadIndex_].patch().localPoints()
-            ).z();
+            deckHeight_.value() = GREAT;
+            if (boundary()[cylinderHeadIndex_].patch().localPoints().size())
+            {
+                deckHeight_.value() = min
+                (
+                    boundary()[cylinderHeadIndex_].patch().localPoints()
+                ).z();
+            }
         }
         reduce(deckHeight_.value(), minOp<scalar>());
 
diff --git a/src/finiteVolume/Make/files b/src/finiteVolume/Make/files
index 34a4606e088ade62d6f128c2c021c9524e81c33c..1ad24ecd168a95c73cb89317680c4f02915f82e9 100644
--- a/src/finiteVolume/Make/files
+++ b/src/finiteVolume/Make/files
@@ -24,6 +24,7 @@ $(constraintFvPatches)/processor/processorFvPatch.C
 derivedFvPatches = $(fvPatches)/derived
 $(derivedFvPatches)/wall/wallFvPatch.C
 $(derivedFvPatches)/directMapped/directMappedFvPatch.C
+$(derivedFvPatches)/directMapped/directMappedWallFvPatch.C
 
 wallDist = fvMesh/wallDist
 $(wallDist)/wallPointYPlus/wallPointYPlus.C
@@ -105,6 +106,7 @@ $(derivedFvPatchFields)/inletOutlet/inletOutletFvPatchFields.C
 $(derivedFvPatchFields)/inletOutletTotalTemperature/inletOutletTotalTemperatureFvPatchScalarField.C
 $(derivedFvPatchFields)/flowRateInletVelocity/flowRateInletVelocityFvPatchVectorField.C
 $(derivedFvPatchFields)/movingWallVelocity/movingWallVelocityFvPatchVectorField.C
+$(derivedFvPatchFields)/rotatingWallVelocity/rotatingWallVelocityFvPatchVectorField.C
 $(derivedFvPatchFields)/oscillatingFixedValue/oscillatingFixedValueFvPatchFields.C
 $(derivedFvPatchFields)/outletInlet/outletInletFvPatchFields.C
 $(derivedFvPatchFields)/partialSlip/partialSlipFvPatchFields.C
diff --git a/src/finiteVolume/fields/fvPatchFields/derived/directMappedFixedValue/directMappedFixedValueFvPatchField.C b/src/finiteVolume/fields/fvPatchFields/derived/directMappedFixedValue/directMappedFixedValueFvPatchField.C
index 5322cbf47b20cd663696118452b6bdc382dd49a6..0c3bf4340838d01e7dbbf264a9fb6fdb948ed6ce 100644
--- a/src/finiteVolume/fields/fvPatchFields/derived/directMappedFixedValue/directMappedFixedValueFvPatchField.C
+++ b/src/finiteVolume/fields/fvPatchFields/derived/directMappedFixedValue/directMappedFixedValueFvPatchField.C
@@ -25,7 +25,7 @@ License
 \*---------------------------------------------------------------------------*/
 
 #include "directMappedFixedValueFvPatchField.H"
-#include "directMappedFvPatch.H"
+#include "directMappedPatchBase.H"
 #include "volFields.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@@ -61,7 +61,7 @@ directMappedFixedValueFvPatchField<Type>::directMappedFixedValueFvPatchField
     setAverage_(ptf.setAverage_),
     average_(ptf.average_)
 {
-    if (!isType<directMappedFvPatch>(this->patch()))
+    if (!isA<directMappedPatchBase>(this->patch().patch()))
     {
         FatalErrorIn
         (
@@ -74,7 +74,7 @@ directMappedFixedValueFvPatchField<Type>::directMappedFixedValueFvPatchField
             "    const fvPatchFieldMapper&\n"
             ")\n"
         )   << "\n    patch type '" << p.type()
-            << "' not type '" << typeName << "'"
+            << "' not type '" << directMappedPatchBase::typeName << "'"
             << "\n    for patch " << p.name()
             << " of field " << this->dimensionedInternalField().name()
             << " in file " << this->dimensionedInternalField().objectPath()
@@ -95,7 +95,7 @@ directMappedFixedValueFvPatchField<Type>::directMappedFixedValueFvPatchField
     setAverage_(readBool(dict.lookup("setAverage"))),
     average_(pTraits<Type>(dict.lookup("average")))
 {
-    if (!isType<directMappedFvPatch>(this->patch()))
+    if (!isA<directMappedPatchBase>(this->patch().patch()))
     {
         FatalErrorIn
         (
@@ -107,12 +107,19 @@ directMappedFixedValueFvPatchField<Type>::directMappedFixedValueFvPatchField
             "    const dictionary& dict\n"
             ")\n"
         )   << "\n    patch type '" << p.type()
-            << "' not type '" << typeName << "'"
+            << "' not type '" << directMappedPatchBase::typeName << "'"
             << "\n    for patch " << p.name()
             << " of field " << this->dimensionedInternalField().name()
             << " in file " << this->dimensionedInternalField().objectPath()
             << exit(FatalError);
     }
+
+    // Force calculation of schedule (uses parallel comms)
+    const directMappedPatchBase& mpp = refCast<const directMappedPatchBase>
+    (
+        this->patch().patch()
+    );
+    (void)mpp.map().schedule();
 }
 
 
@@ -143,70 +150,6 @@ directMappedFixedValueFvPatchField<Type>::directMappedFixedValueFvPatchField
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
-template<class Type>
-void directMappedFixedValueFvPatchField<Type>::getNewValues
-(
-    const directMappedPolyPatch& mpp,
-    const Field<Type>& sendValues,
-    Field<Type>& newValues
-) const
-{
-    // Get the scheduling information
-    const List<labelPair>& schedule = mpp.schedule();
-    const labelListList& sendLabels = mpp.sendLabels();
-    const labelListList& receiveFaceLabels = mpp.receiveFaceLabels();
-
-    forAll(schedule, i)
-    {
-        const labelPair& twoProcs = schedule[i];
-        label sendProc = twoProcs[0];
-        label recvProc = twoProcs[1];
-
-        if (Pstream::myProcNo() == sendProc)
-        {
-            OPstream toProc(Pstream::scheduled, recvProc);
-            toProc<< UIndirectList<Type>(sendValues, sendLabels[recvProc])();
-        }
-        else
-        {
-            // I am receiver. Receive from sendProc.
-            IPstream fromProc(Pstream::scheduled, sendProc);
-
-            Field<Type> fromFld(fromProc);
-
-            // Destination faces
-            const labelList& faceLabels = receiveFaceLabels[sendProc];
-
-            forAll(fromFld, i)
-            {
-                label patchFaceI = faceLabels[i];
-
-                newValues[patchFaceI] = fromFld[i];
-            }
-        }
-    }
-
-    // Do data from myself
-    {
-        UIndirectList<Type> fromFld
-        (
-            sendValues,
-            sendLabels[Pstream::myProcNo()]
-        );
-
-        // Destination faces
-        const labelList& faceLabels = receiveFaceLabels[Pstream::myProcNo()];
-
-        forAll(fromFld, i)
-        {
-            label patchFaceI = faceLabels[i];
-
-            newValues[patchFaceI] = fromFld[i];
-        }
-    }
-}
-
-
 template<class Type>
 void directMappedFixedValueFvPatchField<Type>::updateCoeffs()
 {
@@ -215,65 +158,94 @@ void directMappedFixedValueFvPatchField<Type>::updateCoeffs()
         return;
     }
 
-    // Get the directMappedPolyPatch
-    const directMappedPolyPatch& mpp = refCast<const directMappedPolyPatch>
+    typedef GeometricField<Type, fvPatchField, volMesh> fieldType;
+
+    // Get the scheduling information from the directMappedPatchBase
+    const directMappedPatchBase& mpp = refCast<const directMappedPatchBase>
     (
         directMappedFixedValueFvPatchField<Type>::patch().patch()
     );
+    const mapDistribute& distMap = mpp.map();
+    const fvMesh& nbrMesh = refCast<const fvMesh>(mpp.sampleMesh());
+    const word& fldName = this->dimensionedInternalField().name();
 
-    Field<Type> newValues(this->size());
+    // Result of obtaining remote values
+    Field<Type> newValues;
 
     switch (mpp.mode())
     {
-        case directMappedPolyPatch::NEARESTCELL:
+        case directMappedPatchBase::NEARESTCELL:
         {
-            getNewValues(mpp, this->internalField(), newValues);
+            if (mpp.sameRegion())
+            {
+                newValues = this->internalField();
+            }
+            else
+            {
+                newValues = nbrMesh.lookupObject<fieldType>
+                (
+                    fldName
+                ).internalField();
+            }
+            mapDistribute::distribute
+            (
+                Pstream::defaultCommsType,
+                distMap.schedule(),
+                distMap.constructSize(),
+                distMap.subMap(),
+                distMap.constructMap(),
+                newValues
+            );
 
             break;
         }
-        case directMappedPolyPatch::NEARESTPATCHFACE:
+        case directMappedPatchBase::NEARESTPATCHFACE:
         {
-            const label patchID =
-                 this->patch().patch().boundaryMesh().findPatchID
-                 (
-                    mpp.samplePatch()
-                 );
-            if (patchID < 0)
+            const label nbrPatchID = nbrMesh.boundaryMesh().findPatchID
+            (
+                mpp.samplePatch()
+            );
+            if (nbrPatchID < 0)
             {
                 FatalErrorIn
                 (
                     "void directMappedFixedValueFvPatchField<Type>::"
                     "updateCoeffs()"
                 )<< "Unable to find sample patch " << mpp.samplePatch()
+                 << " in region " << mpp.sampleRegion()
                  << " for patch " << this->patch().name() << nl
                  << abort(FatalError);
             }
-            typedef GeometricField<Type, fvPatchField, volMesh> fieldType;
-            const word& fieldName = this->dimensionedInternalField().name();
-            const fieldType& sendField =
-                this->db().objectRegistry::lookupObject<fieldType>(fieldName);
 
-            getNewValues(mpp, sendField.boundaryField()[patchID], newValues);
+            const fieldType& nbrField = nbrMesh.lookupObject<fieldType>
+            (
+                fldName
+            );
+            newValues = nbrField.boundaryField()[nbrPatchID];
+            mapDistribute::distribute
+            (
+                Pstream::defaultCommsType,
+                distMap.schedule(),
+                distMap.constructSize(),
+                distMap.subMap(),
+                distMap.constructMap(),
+                newValues
+            );
 
             break;
         }
-        case directMappedPolyPatch::NEARESTFACE:
+        case directMappedPatchBase::NEARESTFACE:
         {
-            typedef GeometricField<Type, fvPatchField, volMesh> fieldType;
-            const word& fieldName = this->dimensionedInternalField().name();
-            const fieldType& sendField =
-                this->db().objectRegistry::lookupObject<fieldType>(fieldName);
+            Field<Type> allValues(nbrMesh.nFaces(), pTraits<Type>::zero);
 
-            Field<Type> allValues
+            const fieldType& nbrField = nbrMesh.lookupObject<fieldType>
             (
-                this->patch().patch().boundaryMesh().mesh().nFaces(),
-                pTraits<Type>::zero
+                fldName
             );
-
-            forAll(sendField.boundaryField(), patchI)
+            forAll(nbrField.boundaryField(), patchI)
             {
                 const fvPatchField<Type>& pf =
-                    sendField.boundaryField()[patchI];
+                    nbrField.boundaryField()[patchI];
                 label faceStart = pf.patch().patch().start();
 
                 forAll(pf, faceI)
@@ -282,9 +254,17 @@ void directMappedFixedValueFvPatchField<Type>::updateCoeffs()
                 }
             }
 
-            getNewValues(mpp, allValues, newValues);
+            mapDistribute::distribute
+            (
+                Pstream::defaultCommsType,
+                distMap.schedule(),
+                distMap.constructSize(),
+                distMap.subMap(),
+                distMap.constructMap(),
+                allValues
+            );
 
-            newValues = this->patch().patchSlice(newValues);
+            newValues = this->patch().patchSlice(allValues);
 
             break;
         }
diff --git a/src/finiteVolume/fields/fvPatchFields/derived/directMappedFixedValue/directMappedFixedValueFvPatchField.H b/src/finiteVolume/fields/fvPatchFields/derived/directMappedFixedValue/directMappedFixedValueFvPatchField.H
index 8c8da590a8c78bef3865a28b0d3841159f08d719..2382b32db83dd06e21576e643123197ef2322086 100644
--- a/src/finiteVolume/fields/fvPatchFields/derived/directMappedFixedValue/directMappedFixedValueFvPatchField.H
+++ b/src/finiteVolume/fields/fvPatchFields/derived/directMappedFixedValue/directMappedFixedValueFvPatchField.H
@@ -62,18 +62,6 @@ class directMappedFixedValueFvPatchField
         //  setAverage_ is set true
         Type average_;
 
-
-   // Private member functions
-
-        // Helper function to return the new field values
-        void getNewValues
-        (
-            const directMappedPolyPatch& mpp,
-            const Field<Type>& sendValues,
-            Field<Type>& newValues
-        ) const;
-
-
 public:
 
     //- Runtime type information
diff --git a/src/finiteVolume/fields/fvPatchFields/derived/directMappedVelocityFluxFixedValue/directMappedVelocityFluxFixedValueFvPatchField.C b/src/finiteVolume/fields/fvPatchFields/derived/directMappedVelocityFluxFixedValue/directMappedVelocityFluxFixedValueFvPatchField.C
index 92bf63e8c64c96a9722f3ebea511785b4e60dbb3..5ac329fe31a371fcb357c7b288ef43b56df873c7 100644
--- a/src/finiteVolume/fields/fvPatchFields/derived/directMappedVelocityFluxFixedValue/directMappedVelocityFluxFixedValueFvPatchField.C
+++ b/src/finiteVolume/fields/fvPatchFields/derived/directMappedVelocityFluxFixedValue/directMappedVelocityFluxFixedValueFvPatchField.C
@@ -26,7 +26,7 @@ License
 
 #include "directMappedVelocityFluxFixedValueFvPatchField.H"
 #include "fvPatchFieldMapper.H"
-#include "directMappedFvPatch.H"
+#include "directMappedPatchBase.H"
 #include "volFields.H"
 #include "surfaceFields.H"
 #include "addToRunTimeSelectionTable.H"
@@ -62,12 +62,12 @@ directMappedVelocityFluxFixedValueFvPatchField
     fixedValueFvPatchVectorField(ptf, p, iF, mapper),
     phiName_(ptf.phiName_)
 {
-    if (!isType<directMappedFvPatch>(patch()))
+    if (!isType<directMappedPatchBase>(this->patch().patch()))
     {
         FatalErrorIn
         (
             "directMappedVelocityFluxFixedValueFvPatchField::"
-            "directMappedFixedValueFvPatchField\n"
+            "directMappedVelocityFluxFixedValueFvPatchField\n"
             "(\n"
             "    const directMappedVelocityFluxFixedValueFvPatchField&,\n"
             "    const fvPatch&,\n"
@@ -75,7 +75,7 @@ directMappedVelocityFluxFixedValueFvPatchField
             "    const fvPatchFieldMapper&\n"
             ")\n"
         )   << "\n    patch type '" << p.type()
-            << "' not type '" << typeName << "'"
+            << "' not type '" << directMappedPatchBase::typeName << "'"
             << "\n    for patch " << p.name()
             << " of field " << dimensionedInternalField().name()
             << " in file " << dimensionedInternalField().objectPath()
@@ -95,24 +95,31 @@ directMappedVelocityFluxFixedValueFvPatchField
     fixedValueFvPatchVectorField(p, iF, dict),
     phiName_(dict.lookup("phi"))
 {
-    if (!isType<directMappedFvPatch>(patch()))
+    if (!isType<directMappedPatchBase>(this->patch().patch()))
     {
         FatalErrorIn
         (
             "directMappedVelocityFluxFixedValueFvPatchField::"
-            "directMappedFixedValueFvPatchField\n"
+            "directMappedVelocityFluxFixedValueFvPatchField\n"
             "(\n"
             "    const fvPatch& p,\n"
             "    const DimensionedField<vector, volMesh>& iF,\n"
             "    const dictionary& dict\n"
             ")\n"
         )   << "\n    patch type '" << p.type()
-            << "' not type '" << typeName << "'"
+            << "' not type '" << directMappedPatchBase::typeName << "'"
             << "\n    for patch " << p.name()
             << " of field " << dimensionedInternalField().name()
             << " in file " << dimensionedInternalField().objectPath()
             << exit(FatalError);
     }
+
+    // Force calculation of schedule (uses parallel comms)
+    const directMappedPolyPatch& mpp = refCast<const directMappedPolyPatch>
+    (
+        patch().patch()
+    );
+    (void)mpp.map().schedule();
 }
 
 
@@ -139,85 +146,6 @@ directMappedVelocityFluxFixedValueFvPatchField
 {}
 
 
-void directMappedVelocityFluxFixedValueFvPatchField::getNewValues
-(
-    const directMappedPolyPatch& mpp,
-    const vectorField& sendUValues,
-    const scalarField& sendPhiValues,
-    vectorField& newUValues,
-    scalarField& newPhiValues
-) const
-{
-    // Get the scheduling information
-    const List<labelPair>& schedule = mpp.schedule();
-    const labelListList& sendLabels = mpp.sendLabels();
-    const labelListList& receiveFaceLabels = mpp.receiveFaceLabels();
-
-    forAll(schedule, i)
-    {
-        const labelPair& twoProcs = schedule[i];
-        label sendProc = twoProcs[0];
-        label recvProc = twoProcs[1];
-
-        if (Pstream::myProcNo() == sendProc)
-        {
-            OPstream toProc(Pstream::scheduled, recvProc);
-            toProc<< UIndirectList<vector>(sendUValues, sendLabels[recvProc])();
-            toProc<< UIndirectList<scalar>
-                (
-                    sendPhiValues,
-                    sendLabels[recvProc]
-                )();
-        }
-        else
-        {
-            // I am receiver. Receive from sendProc.
-            IPstream fromProc(Pstream::scheduled, sendProc);
-
-            vectorField fromUFld(fromProc);
-            scalarField fromPhiFld(fromProc);
-
-            // Destination faces
-            const labelList& faceLabels = receiveFaceLabels[sendProc];
-
-            forAll(fromUFld, i)
-            {
-                label patchFaceI = faceLabels[i];
-
-                newUValues[patchFaceI] = fromUFld[i];
-                newPhiValues[patchFaceI] = fromPhiFld[i];
-            }
-        }
-    }
-
-    // Do data from myself
-    {
-        UIndirectList<vector> fromUFld
-            (
-                sendUValues,
-                sendLabels[Pstream::myProcNo()]
-            );
-
-        UIndirectList<scalar> fromPhiFld
-            (
-                sendPhiValues,
-                sendLabels[Pstream::myProcNo()]
-            );
-
-        // Destination faces
-        const labelList& faceLabels = receiveFaceLabels[Pstream::myProcNo()];
-
-        forAll(fromUFld, i)
-        {
-            label patchFaceI = faceLabels[i];
-
-            newUValues[patchFaceI] = fromUFld[i];
-            newPhiValues[patchFaceI] = fromPhiFld[i];
-        }
-    }
-}
-
-
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
 void directMappedVelocityFluxFixedValueFvPatchField::updateCoeffs()
@@ -227,37 +155,33 @@ void directMappedVelocityFluxFixedValueFvPatchField::updateCoeffs()
         return;
     }
 
-    // Get the directMappedPolyPatch
-    const directMappedPolyPatch& mpp = refCast<const directMappedPolyPatch>
+    // Get the directMappedPatchBase
+    const directMappedPatchBase& mpp = refCast<const directMappedPatchBase>
     (
         directMappedVelocityFluxFixedValueFvPatchField::patch().patch()
     );
-
-    vectorField newUValues(size());
-    scalarField newPhiValues(size());
-
+    const mapDistribute& distMap = mpp.map();
+    const fvMesh& nbrMesh = refCast<const fvMesh>(mpp.sampleMesh());
     const word& fieldName = dimensionedInternalField().name();
-    const volVectorField& UField = db().lookupObject<volVectorField>(fieldName);
+    const volVectorField& UField = nbrMesh.lookupObject<volVectorField>
+    (
+        fieldName
+    );
 
     surfaceScalarField& phiField = const_cast<surfaceScalarField&>
     (
-        db().lookupObject<surfaceScalarField>(phiName_)
+        nbrMesh.lookupObject<surfaceScalarField>(phiName_)
     );
 
+    vectorField newUValues;
+    scalarField newPhiValues;
+
     switch (mpp.mode())
     {
         case directMappedPolyPatch::NEARESTFACE:
         {
-            vectorField allUValues
-            (
-                patch().patch().boundaryMesh().mesh().nFaces(),
-                vector::zero
-            );
-            scalarField allPhiValues
-            (
-                patch().patch().boundaryMesh().mesh().nFaces(),
-                0.0
-            );
+            vectorField allUValues(nbrMesh.nFaces(), vector::zero);
+            scalarField allPhiValues(nbrMesh.nFaces(), 0.0);
 
             forAll(UField.boundaryField(), patchI)
             {
@@ -273,34 +197,58 @@ void directMappedVelocityFluxFixedValueFvPatchField::updateCoeffs()
                 }
             }
 
-            getNewValues
+            mapDistribute::distribute
             (
-                mpp,
-                allUValues,
-                allPhiValues,
-                newUValues,
-                newPhiValues
+                Pstream::defaultCommsType,
+                distMap.schedule(),
+                distMap.constructSize(),
+                distMap.subMap(),
+                distMap.constructMap(),
+                allUValues
             );
-
             newUValues = patch().patchSlice(newUValues);
+            
+            mapDistribute::distribute
+            (
+                Pstream::defaultCommsType,
+                distMap.schedule(),
+                distMap.constructSize(),
+                distMap.subMap(),
+                distMap.constructMap(),
+                newPhiValues
+            );
             newPhiValues = patch().patchSlice(newPhiValues);
 
             break;
         }
         case directMappedPolyPatch::NEARESTPATCHFACE:
         {
-            const label patchID =
-                patch().patch().boundaryMesh().findPatchID
-                (
-                    mpp.samplePatch()
-                );
+            const label nbrPatchID = nbrMesh.boundaryMesh().findPatchID
+            (
+                mpp.samplePatch()
+            );
+
+            newUValues = UField.boundaryField()[nbrPatchID];
+
+            mapDistribute::distribute
+            (
+                Pstream::defaultCommsType,
+                distMap.schedule(),
+                distMap.constructSize(),
+                distMap.subMap(),
+                distMap.constructMap(),
+                newUValues
+            );
+
+            newPhiValues = phiField.boundaryField()[nbrPatchID];
 
-            getNewValues
+            mapDistribute::distribute
             (
-                mpp,
-                UField.boundaryField()[patchID],
-                phiField.boundaryField()[patchID],
-                newUValues,
+                Pstream::defaultCommsType,
+                distMap.schedule(),
+                distMap.constructSize(),
+                distMap.subMap(),
+                distMap.constructMap(),
                 newPhiValues
             );
 
diff --git a/src/finiteVolume/fields/fvPatchFields/derived/directMappedVelocityFluxFixedValue/directMappedVelocityFluxFixedValueFvPatchField.H b/src/finiteVolume/fields/fvPatchFields/derived/directMappedVelocityFluxFixedValue/directMappedVelocityFluxFixedValueFvPatchField.H
index b92372eb3a30b37789d87c74b771ac6beaf32d37..6ec34d62e100683ed147cd544d88554bf90f71bf 100644
--- a/src/finiteVolume/fields/fvPatchFields/derived/directMappedVelocityFluxFixedValue/directMappedVelocityFluxFixedValueFvPatchField.H
+++ b/src/finiteVolume/fields/fvPatchFields/derived/directMappedVelocityFluxFixedValue/directMappedVelocityFluxFixedValueFvPatchField.H
@@ -57,20 +57,6 @@ class directMappedVelocityFluxFixedValueFvPatchField
         //- Name of flux field
         word phiName_;
 
-
-   // Private member functions
-
-        // Helper function to return the new field values
-        void getNewValues
-        (
-            const directMappedPolyPatch& mpp,
-            const vectorField& sendUValues,
-            const scalarField& sendPhiValues,
-            vectorField& newUValues,
-            scalarField& newPhiValues
-        ) const;
-
-
 public:
 
     //- Runtime type information
diff --git a/src/finiteVolume/fields/fvPatchFields/derived/fixedInternalValueFvPatchField/fixedInternalValueFvPatchField.C b/src/finiteVolume/fields/fvPatchFields/derived/fixedInternalValueFvPatchField/fixedInternalValueFvPatchField.C
index eba3522e36ec98f0cc4f3447de0cdabf52b2ffc3..1cbd6fd72dd3c97596c7cb8d9e53cdacaf982e2c 100644
--- a/src/finiteVolume/fields/fvPatchFields/derived/fixedInternalValueFvPatchField/fixedInternalValueFvPatchField.C
+++ b/src/finiteVolume/fields/fvPatchFields/derived/fixedInternalValueFvPatchField/fixedInternalValueFvPatchField.C
@@ -63,9 +63,7 @@ Foam::fixedInternalValueFvPatchField<Type>::fixedInternalValueFvPatchField
 )
 :
     zeroGradientFvPatchField<Type>(p, iF, dict)
-{
-    fvPatchField<Type>::operator=(this->patchInternalField());
-}
+{}
 
 
 template<class Type>
diff --git a/src/finiteVolume/fields/fvPatchFields/derived/inletOutletTotalTemperature/inletOutletTotalTemperatureFvPatchScalarField.C b/src/finiteVolume/fields/fvPatchFields/derived/inletOutletTotalTemperature/inletOutletTotalTemperatureFvPatchScalarField.C
index 7d316f21fa812d741966846d2dddd1bdb42800b4..d6a83b07cbd6e53f16793b3b6e62fd55e5aa2315 100644
--- a/src/finiteVolume/fields/fvPatchFields/derived/inletOutletTotalTemperature/inletOutletTotalTemperatureFvPatchScalarField.C
+++ b/src/finiteVolume/fields/fvPatchFields/derived/inletOutletTotalTemperature/inletOutletTotalTemperatureFvPatchScalarField.C
@@ -189,7 +189,8 @@ void Foam::inletOutletTotalTemperatureFvPatchScalarField::updateCoeffs()
 }
 
 
-void Foam::inletOutletTotalTemperatureFvPatchScalarField::write(Ostream& os) const
+void Foam::inletOutletTotalTemperatureFvPatchScalarField::write(Ostream& os)
+const
 {
     fvPatchScalarField::write(os);
     if (UName_ != "U")
diff --git a/src/finiteVolume/fields/fvPatchFields/derived/rotatingWallVelocity/rotatingWallVelocityFvPatchVectorField.C b/src/finiteVolume/fields/fvPatchFields/derived/rotatingWallVelocity/rotatingWallVelocityFvPatchVectorField.C
new file mode 100644
index 0000000000000000000000000000000000000000..7b5a1dbc45bfe8f5b2b743a7098dde6cf91d323d
--- /dev/null
+++ b/src/finiteVolume/fields/fvPatchFields/derived/rotatingWallVelocity/rotatingWallVelocityFvPatchVectorField.C
@@ -0,0 +1,153 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 1991-2007 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 "rotatingWallVelocityFvPatchVectorField.H"
+#include "addToRunTimeSelectionTable.H"
+#include "volFields.H"
+#include "surfaceFields.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+rotatingWallVelocityFvPatchVectorField::rotatingWallVelocityFvPatchVectorField
+(
+    const fvPatch& p,
+    const DimensionedField<vector, volMesh>& iF
+)
+:
+    fixedValueFvPatchField<vector>(p, iF),
+    origin_(vector::zero),
+    axis_(vector::zero),
+    omega_(0)
+{}
+
+
+rotatingWallVelocityFvPatchVectorField::rotatingWallVelocityFvPatchVectorField
+(
+    const rotatingWallVelocityFvPatchVectorField& ptf,
+    const fvPatch& p,
+    const DimensionedField<vector, volMesh>& iF,
+    const fvPatchFieldMapper& mapper
+)
+:
+    fixedValueFvPatchField<vector>(ptf, p, iF, mapper),
+    origin_(ptf.origin_),
+    axis_(ptf.axis_),
+    omega_(ptf.omega_)
+{}
+
+
+rotatingWallVelocityFvPatchVectorField::rotatingWallVelocityFvPatchVectorField
+(
+    const fvPatch& p,
+    const DimensionedField<vector, volMesh>& iF,
+    const dictionary& dict
+)
+:
+    fixedValueFvPatchField<vector>(p, iF),
+    origin_(dict.lookup("origin")),
+    axis_(dict.lookup("axis")),
+    omega_(readScalar(dict.lookup("omega")))
+{
+    // Evaluate the wall velocity
+    updateCoeffs();
+}
+
+
+rotatingWallVelocityFvPatchVectorField::rotatingWallVelocityFvPatchVectorField
+(
+    const rotatingWallVelocityFvPatchVectorField& pivpvf
+)
+:
+    fixedValueFvPatchField<vector>(pivpvf),
+    origin_(pivpvf.origin_),
+    axis_(pivpvf.axis_),
+    omega_(pivpvf.omega_)
+{}
+
+
+rotatingWallVelocityFvPatchVectorField::rotatingWallVelocityFvPatchVectorField
+(
+    const rotatingWallVelocityFvPatchVectorField& pivpvf,
+    const DimensionedField<vector, volMesh>& iF
+)
+:
+    fixedValueFvPatchField<vector>(pivpvf, iF),
+    origin_(pivpvf.origin_),
+    axis_(pivpvf.axis_),
+    omega_(pivpvf.omega_)
+{}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+void rotatingWallVelocityFvPatchVectorField::updateCoeffs()
+{
+    if (updated())
+    {
+        return;
+    }
+
+    // Calculate the rotating wall velocity from the specification of the motion
+    vectorField Up = (-omega_)*((patch().Cf() - origin_) ^ (axis_/mag(axis_)));
+
+    // Remove the component of Up normal to the wall
+    // just in case it is not exactly circular
+    vectorField n = patch().nf();
+    vectorField::operator=(Up - n*(n & Up));
+
+    fixedValueFvPatchVectorField::updateCoeffs();
+}
+
+
+void rotatingWallVelocityFvPatchVectorField::write(Ostream& os) const
+{
+    fvPatchVectorField::write(os);
+    os.writeKeyword("origin") << origin_ << token::END_STATEMENT << nl;
+    os.writeKeyword("axis") << axis_ << token::END_STATEMENT << nl;
+    os.writeKeyword("omega") << omega_ << token::END_STATEMENT << nl;
+    writeEntry("value", os);
+}
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+makePatchTypeField
+(
+    fvPatchVectorField,
+    rotatingWallVelocityFvPatchVectorField
+);
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// ************************************************************************* //
diff --git a/src/finiteVolume/fields/fvPatchFields/derived/rotatingWallVelocity/rotatingWallVelocityFvPatchVectorField.H b/src/finiteVolume/fields/fvPatchFields/derived/rotatingWallVelocity/rotatingWallVelocityFvPatchVectorField.H
new file mode 100644
index 0000000000000000000000000000000000000000..5eed0e60ea464e39bf176e0448c67f90a32533b7
--- /dev/null
+++ b/src/finiteVolume/fields/fvPatchFields/derived/rotatingWallVelocity/rotatingWallVelocityFvPatchVectorField.H
@@ -0,0 +1,192 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  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::rotatingWallVelocityFvPatchVectorField
+
+Description
+    Foam::rotatingWallVelocityFvPatchVectorField
+
+SourceFiles
+    rotatingWallVelocityFvPatchVectorField.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef rotatingWallVelocityFvPatchVectorField_H
+#define rotatingWallVelocityFvPatchVectorField_H
+
+#include "fixedValueFvPatchFields.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+                 Class rotatingWallVelocityFvPatch Declaration
+\*---------------------------------------------------------------------------*/
+
+class rotatingWallVelocityFvPatchVectorField
+:
+    public fixedValueFvPatchVectorField
+{
+    // Private data
+
+        //- Origin of the rotation
+        vector origin_;
+
+        //- Axis of the rotation
+        vector axis_;
+
+        //- Rotational speed
+        scalar omega_;
+
+
+public:
+
+    //- Runtime type information
+    TypeName("rotatingWallVelocity");
+
+
+    // Constructors
+
+        //- Construct from patch and internal field
+        rotatingWallVelocityFvPatchVectorField
+        (
+            const fvPatch&,
+            const DimensionedField<vector, volMesh>&
+        );
+
+        //- Construct from patch, internal field and dictionary
+        rotatingWallVelocityFvPatchVectorField
+        (
+            const fvPatch&,
+            const DimensionedField<vector, volMesh>&,
+            const dictionary&
+        );
+
+        //- Construct by mapping given rotatingWallVelocityFvPatchVectorField
+        //  onto a new patch
+        rotatingWallVelocityFvPatchVectorField
+        (
+            const rotatingWallVelocityFvPatchVectorField&,
+            const fvPatch&,
+            const DimensionedField<vector, volMesh>&,
+            const fvPatchFieldMapper&
+        );
+
+        //- Construct as copy
+        rotatingWallVelocityFvPatchVectorField
+        (
+            const rotatingWallVelocityFvPatchVectorField&
+        );
+
+        //- Construct and return a clone
+        virtual tmp<fvPatchVectorField> clone() const
+        {
+            return tmp<fvPatchVectorField>
+            (
+                new rotatingWallVelocityFvPatchVectorField(*this)
+            );
+        }
+
+        //- Construct as copy setting internal field reference
+        rotatingWallVelocityFvPatchVectorField
+        (
+            const rotatingWallVelocityFvPatchVectorField&,
+            const DimensionedField<vector, volMesh>&
+        );
+
+        //- Construct and return a clone setting internal field reference
+        virtual tmp<fvPatchVectorField> clone
+        (
+             const DimensionedField<vector, volMesh>& iF
+        ) const
+        {
+            return tmp<fvPatchVectorField>
+            (
+                new rotatingWallVelocityFvPatchVectorField(*this, iF)
+            );
+        }
+
+
+
+    // Member functions
+
+        // Access functions
+
+            //- Return the origin of the rotation
+            const vector& origin() const
+            {
+                return origin_;
+            }
+
+            //- Return the axis of the rotation
+            const vector& axis() const
+            {
+                return axis_;
+            }
+
+            //- Return the rotational speed
+            const scalar& omega() const
+            {
+                return omega_;
+            }
+
+            //- Return non-const access to the origin of the rotation
+            vector& origin()
+            {
+                return origin_;
+            }
+
+            //- Return non-const access to the axis of the rotation
+            vector& axis()
+            {
+                return axis_;
+            }
+
+            //- Return non-const access to the rotational speed
+            scalar& omega()
+            {
+                return omega_;
+            }
+
+
+        //- Update the coefficients associated with the patch field
+        virtual void updateCoeffs();
+
+        //- Write
+        virtual void write(Ostream&) const;
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/finiteVolume/fvMesh/fvPatches/derived/directMapped/directMappedWallFvPatch.C b/src/finiteVolume/fvMesh/fvPatches/derived/directMapped/directMappedWallFvPatch.C
new file mode 100644
index 0000000000000000000000000000000000000000..413d5f86c2df747298ba770019f9efcea96b8fb4
--- /dev/null
+++ b/src/finiteVolume/fvMesh/fvPatches/derived/directMapped/directMappedWallFvPatch.C
@@ -0,0 +1,38 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  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 "directMappedWallFvPatch.H"
+#include "addToRunTimeSelectionTable.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+    defineTypeNameAndDebug(directMappedWallFvPatch, 0);
+    addToRunTimeSelectionTable(fvPatch, directMappedWallFvPatch, polyPatch);
+}
+
+// ************************************************************************* //
diff --git a/src/finiteVolume/fvMesh/fvPatches/derived/directMapped/directMappedWallFvPatch.H b/src/finiteVolume/fvMesh/fvPatches/derived/directMapped/directMappedWallFvPatch.H
new file mode 100644
index 0000000000000000000000000000000000000000..4be7eed59274e264b6cf7acda28aa1bea1e001ed
--- /dev/null
+++ b/src/finiteVolume/fvMesh/fvPatches/derived/directMapped/directMappedWallFvPatch.H
@@ -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
+
+Class
+    Foam::directMappedWallFvPatch
+
+Description
+    Foam::directMappedWallFvPatch
+
+SourceFiles
+    directMappedWallFvPatch.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef directMappedWallFvPatch_H
+#define directMappedWallFvPatch_H
+
+#include "fvPatch.H"
+#include "directMappedWallPolyPatch.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+                           Class directMappedWallFvPatch Declaration
+\*---------------------------------------------------------------------------*/
+
+class directMappedWallFvPatch
+:
+    public fvPatch
+{
+
+public:
+
+    //- Runtime type information
+    TypeName(directMappedWallPolyPatch::typeName_());
+
+
+    // Constructors
+
+        //- Construct from components
+        directMappedWallFvPatch
+        (
+            const polyPatch& patch,
+            const fvBoundaryMesh& bm
+        )
+        :
+            fvPatch(patch, bm)
+        {}
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/meshTools/Make/files b/src/meshTools/Make/files
index 9f849c58945b11d04d9193da1fe201653c09f01d..d5133cb33dad9e45beb50fa4785fdaee749b2d39 100644
--- a/src/meshTools/Make/files
+++ b/src/meshTools/Make/files
@@ -141,7 +141,10 @@ triSurface/triSurfaceTools/geompack/geompack.C
 
 twoDPointCorrector/twoDPointCorrector.C
 
+directMapped/directMappedPolyPatch/directMappedPatchBase.C
 directMapped/directMappedPolyPatch/directMappedPolyPatch.C
+directMapped/directMappedPolyPatch/directMappedWallPolyPatch.C
 directMapped/directMappedPointPatch/directMappedPointPatch.C
+directMapped/directMappedPointPatch/directMappedWallPointPatch.C
 
 LIB = $(FOAM_LIBBIN)/libmeshTools
diff --git a/src/meshTools/directMapped/directMappedPointPatch/directMappedWallPointPatch.C b/src/meshTools/directMapped/directMappedPointPatch/directMappedWallPointPatch.C
new file mode 100644
index 0000000000000000000000000000000000000000..4633d73ecf64e16932247f36966b30fcc0ea6261
--- /dev/null
+++ b/src/meshTools/directMapped/directMappedPointPatch/directMappedWallPointPatch.C
@@ -0,0 +1,52 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  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 "directMappedWallPointPatch.H"
+#include "addToRunTimeSelectionTable.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+defineTypeNameAndDebug(directMappedWallPointPatch, 0);
+
+// Add the patch constructor functions to the hash tables
+addToRunTimeSelectionTable
+(
+    facePointPatch,
+    directMappedWallPointPatch,
+    polyPatch
+);
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// ************************************************************************* //
diff --git a/src/meshTools/directMapped/directMappedPointPatch/directMappedWallPointPatch.H b/src/meshTools/directMapped/directMappedPointPatch/directMappedWallPointPatch.H
new file mode 100644
index 0000000000000000000000000000000000000000..28bb87710518a8537bcdca5fafea01132081da5c
--- /dev/null
+++ b/src/meshTools/directMapped/directMappedPointPatch/directMappedWallPointPatch.H
@@ -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
+
+Class
+    Foam::directMappedWallPointPatch
+
+Description
+    DirectMapped patch.
+
+SourceFiles
+    directMappedWallPointPatch.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef directMappedWallPointPatch_H
+#define directMappedWallPointPatch_H
+
+#include "facePointPatch.H"
+#include "directMappedWallPolyPatch.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+                       Class directMappedWallPointPatch Declaration
+\*---------------------------------------------------------------------------*/
+
+class directMappedWallPointPatch
+:
+    public facePointPatch
+{
+
+public:
+
+    //- Runtime type information
+    TypeName(directMappedWallPolyPatch::typeName_());
+
+
+    // Constructors
+
+        //- Construct from polyPatch
+        directMappedWallPointPatch
+        (
+            const polyPatch& patch,
+            const pointBoundaryMesh& bm
+        )
+        :
+            facePointPatch(patch, bm)
+        {}
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/meshTools/directMapped/directMappedPolyPatch/directMappedPatchBase.C b/src/meshTools/directMapped/directMappedPolyPatch/directMappedPatchBase.C
new file mode 100644
index 0000000000000000000000000000000000000000..81ef42bee9bd9e7813ae0a091c83cd2841c419e0
--- /dev/null
+++ b/src/meshTools/directMapped/directMappedPolyPatch/directMappedPatchBase.C
@@ -0,0 +1,657 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  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 "directMappedPatchBase.H"
+#include "addToRunTimeSelectionTable.H"
+#include "ListListOps.H"
+#include "meshSearch.H"
+#include "meshTools.H"
+#include "OFstream.H"
+#include "Random.H"
+#include "treeDataFace.H"
+#include "indexedOctree.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+    defineTypeNameAndDebug(directMappedPatchBase, 0);
+
+    template<>
+    const char* NamedEnum<directMappedPatchBase::sampleMode, 3>::names[] =
+    {
+        "nearestCell",
+        "nearestPatchFace",
+        "nearestFace"
+    };
+
+    const NamedEnum<directMappedPatchBase::sampleMode, 3>
+        directMappedPatchBase::sampleModeNames_;
+}
+
+
+// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
+
+void Foam::directMappedPatchBase::collectSamples
+(
+    pointField& samples,
+    labelList& patchFaceProcs,
+    labelList& patchFaces,
+    pointField& patchFc
+) const
+{
+
+    // Collect all sample points and the faces they come from.
+    List<pointField> globalFc(Pstream::nProcs());
+    List<pointField> globalSamples(Pstream::nProcs());
+    labelListList globalFaces(Pstream::nProcs());
+
+    globalFc[Pstream::myProcNo()] = patch_.faceCentres();
+    globalSamples[Pstream::myProcNo()] = globalFc[Pstream::myProcNo()]+offset_;
+    globalFaces[Pstream::myProcNo()] = identity(patch_.size());
+
+    // Distribute to all processors
+    Pstream::gatherList(globalSamples);
+    Pstream::scatterList(globalSamples);
+    Pstream::gatherList(globalFaces);
+    Pstream::scatterList(globalFaces);
+    Pstream::gatherList(globalFc);
+    Pstream::scatterList(globalFc);
+
+    // Rework into straight list
+    samples = ListListOps::combine<pointField>
+    (
+        globalSamples,
+        accessOp<pointField>()
+    );
+    patchFaces = ListListOps::combine<labelList>
+    (
+        globalFaces,
+        accessOp<labelList>()
+    );
+    patchFc = ListListOps::combine<pointField>
+    (
+        globalFc,
+        accessOp<pointField>()
+    );
+
+    patchFaceProcs.setSize(patchFaces.size());
+    labelList nPerProc
+    (
+        ListListOps::subSizes
+        (
+            globalFaces,
+            accessOp<labelList>()
+        )
+    );
+    label sampleI = 0;
+    forAll(nPerProc, procI)
+    {
+        for (label i = 0; i < nPerProc[procI]; i++)
+        {
+            patchFaceProcs[sampleI++] = procI;
+        }
+    }
+}
+
+
+// Find the processor/cell containing the samples. Does not account
+// for samples being found in two processors.
+void Foam::directMappedPatchBase::findSamples
+(
+    const pointField& samples,
+    labelList& sampleProcs,
+    labelList& sampleIndices,
+    pointField& sampleLocations
+) const
+{
+    // Lookup the correct region
+    const polyMesh& mesh = sampleMesh();
+
+    // All the info for nearest. Construct to miss
+    List<nearInfo> nearest(samples.size());
+
+    switch (mode_)
+    {
+        case NEARESTCELL:
+        {
+            if (samplePatch_.size() && samplePatch_ != "none")
+            {
+                FatalErrorIn
+                (
+                    "directMappedPatchBase::findSamples(const pointField&,"
+                    " labelList&, labelList&, pointField&) const"
+                )   << "No need to supply a patch name when in "
+                    << sampleModeNames_[mode_] << " mode." << exit(FatalError);
+            }
+
+            // Octree based search engine
+            meshSearch meshSearchEngine(mesh, false);
+
+            forAll(samples, sampleI)
+            {
+                const point& sample = samples[sampleI];
+
+                label cellI = meshSearchEngine.findCell(sample);
+
+                if (cellI == -1)
+                {
+                    nearest[sampleI].second().first() = Foam::sqr(GREAT);
+                    nearest[sampleI].second().second() = Pstream::myProcNo();
+                }
+                else
+                {
+                    const point& cc = mesh.cellCentres()[cellI];
+
+                    nearest[sampleI].first() = pointIndexHit
+                    (
+                        true,
+                        cc,
+                        cellI
+                    );
+                    nearest[sampleI].second().first() = magSqr(cc-sample);
+                    nearest[sampleI].second().second() = Pstream::myProcNo();
+                }
+            }
+            break;
+        }
+
+        case NEARESTPATCHFACE:
+        {
+            Random rndGen(123456);
+
+            const polyPatch& pp = samplePolyPatch();
+
+            if (pp.empty())
+            {
+                forAll(samples, sampleI)
+                {
+                    nearest[sampleI].second().first() = Foam::sqr(GREAT);
+                    nearest[sampleI].second().second() = Pstream::myProcNo();
+                }
+            }
+            else
+            {
+                // patch faces
+                const labelList patchFaces(identity(pp.size()) + pp.start());
+
+                treeBoundBox patchBb
+                (
+                    treeBoundBox(pp.points(), pp.meshPoints()).extend
+                    (
+                        rndGen,
+                        1E-4
+                    )
+                );
+                patchBb.min() -= point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL);
+                patchBb.max() += point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL);
+
+                indexedOctree<treeDataFace> boundaryTree
+                (
+                    treeDataFace    // all information needed to search faces
+                    (
+                        false,      // do not cache bb
+                        mesh,
+                        patchFaces  // boundary faces only
+                    ),
+                    patchBb,        // overall search domain
+                    8,              // maxLevel
+                    10,             // leafsize
+                    3.0             // duplicity
+                );
+
+                forAll(samples, sampleI)
+                {
+                    const point& sample = samples[sampleI];
+
+                    pointIndexHit& nearInfo = nearest[sampleI].first();
+                    nearInfo = boundaryTree.findNearest
+                    (
+                        sample,
+                        magSqr(patchBb.span())
+                    );
+
+                    if (!nearInfo.hit())
+                    {
+                        nearest[sampleI].second().first() = Foam::sqr(GREAT);
+                        nearest[sampleI].second().second() =
+                            Pstream::myProcNo();
+                    }
+                    else
+                    {
+                        point fc(pp[nearInfo.index()].centre(pp.points()));
+                        nearInfo.setPoint(fc);
+                        nearest[sampleI].second().first() = magSqr(fc-sample);
+                        nearest[sampleI].second().second() =
+                            Pstream::myProcNo();
+                    }
+                }
+            }
+            break;
+        }
+
+        case NEARESTFACE:
+        {
+            if (samplePatch_.size() && samplePatch_ != "none")
+            {
+                FatalErrorIn
+                (
+                    "directMappedPatchBase::findSamples(const pointField&,"
+                    " labelList&, labelList&, pointField&) const"
+                )   << "No need to supply a patch name when in "
+                    << sampleModeNames_[mode_] << " mode." << exit(FatalError);
+            }
+
+            // Octree based search engine
+            meshSearch meshSearchEngine(mesh, false);
+
+            forAll(samples, sampleI)
+            {
+                const point& sample = samples[sampleI];
+
+                label faceI = meshSearchEngine.findNearestFace(sample);
+
+                if (faceI == -1)
+                {
+                    nearest[sampleI].second().first() = Foam::sqr(GREAT);
+                    nearest[sampleI].second().second() = Pstream::myProcNo();
+                }
+                else
+                {
+                    const point& fc = mesh.faceCentres()[faceI];
+
+                    nearest[sampleI].first() = pointIndexHit
+                    (
+                        true,
+                        fc,
+                        faceI
+                    );
+                    nearest[sampleI].second().first() = magSqr(fc-sample);
+                    nearest[sampleI].second().second() = Pstream::myProcNo();
+                }
+            }
+            break;
+        }
+
+        default:
+        {
+            FatalErrorIn("directMappedPatchBase::findSamples(..)")
+                << "problem." << abort(FatalError);
+        }
+    }
+
+
+    // Find nearest.
+    Pstream::listCombineGather(nearest, nearestEqOp());
+    Pstream::listCombineScatter(nearest);
+
+    if (debug)
+    {
+        Info<< "directMappedPatchBase::findSamples on mesh " << sampleRegion_
+            << " : " << endl;
+        forAll(nearest, sampleI)
+        {
+            label procI = nearest[sampleI].second().second();
+            label localI = nearest[sampleI].first().index();
+
+            Info<< "    " << sampleI << " coord:"<< samples[sampleI]
+                << " found on processor:" << procI
+                << " in local cell/face:" << localI
+                << " with cc:" << nearest[sampleI].first().rawPoint() << endl;
+        }
+    }
+
+    // Check for samples not being found
+    forAll(nearest, sampleI)
+    {
+        if (!nearest[sampleI].first().hit())
+        {
+            FatalErrorIn
+            (
+                "directMappedPatchBase::findSamples"
+                "(const pointField&, labelList&"
+                ", labelList&, pointField&)"
+            )   << "Did not find sample " << samples[sampleI]
+                << " on any processor of region" << sampleRegion_
+                << exit(FatalError);
+        }
+    }
+
+
+    // Convert back into proc+local index
+    sampleProcs.setSize(samples.size());
+    sampleIndices.setSize(samples.size());
+    sampleLocations.setSize(samples.size());
+
+    forAll(nearest, sampleI)
+    {
+        sampleProcs[sampleI] = nearest[sampleI].second().second();
+        sampleIndices[sampleI] = nearest[sampleI].first().index();
+        sampleLocations[sampleI] = nearest[sampleI].first().hitPoint();
+    }
+}
+
+
+void Foam::directMappedPatchBase::calcMapping() const
+{
+    if (mapPtr_.valid())
+    {
+        FatalErrorIn("directMappedPatchBase::calcMapping() const")
+            << "Mapping already calculated" << exit(FatalError);
+    }
+
+    if
+    (
+        offset_ == vector::zero
+     && sampleRegion_ == patch_.boundaryMesh().mesh().name()
+    )
+    {
+        FatalErrorIn("directMappedPatchBase::calcMapping() const")
+            << "Invalid offset " << offset_ << endl
+            << "Offset is the vector added to the patch face centres to"
+            << " find the cell supplying the data."
+            << exit(FatalError);
+    }
+
+
+    // Get global list of all samples and the processor and face they come from.
+    pointField samples;
+    labelList patchFaceProcs;
+    labelList patchFaces;
+    pointField patchFc;
+    collectSamples(samples, patchFaceProcs, patchFaces, patchFc);
+
+    // Find processor and cell/face samples are in and actual location.
+    labelList sampleProcs;
+    labelList sampleIndices;
+    pointField sampleLocations;
+    findSamples(samples, sampleProcs, sampleIndices, sampleLocations);
+
+
+    // Now we have all the data we need:
+    // - where sample originates from (so destination when mapping):
+    //   patchFaces, patchFaceProcs.
+    // - cell/face sample is in (so source when mapping)
+    //   sampleIndices, sampleProcs.
+
+    //forAll(samples, i)
+    //{
+    //    Info<< i << " need data in region "
+    //        << patch_.boundaryMesh().mesh().name()
+    //        << " for proc:" << patchFaceProcs[i]
+    //        << " face:" << patchFaces[i]
+    //        << " at:" << patchFc[i] << endl
+    //        << "Found data in region " << sampleRegion_
+    //        << " at proc:" << sampleProcs[i]
+    //        << " face:" << sampleIndices[i]
+    //        << " at:" << sampleLocations[i]
+    //        << nl << endl;
+    //}
+
+
+
+    if (debug && Pstream::master())
+    {
+        OFstream str
+        (
+            patch_.boundaryMesh().mesh().time().path()
+          / patch_.name()
+          + "_directMapped.obj"
+        );
+        Pout<< "Dumping mapping as lines from patch faceCentres to"
+            << " sampled cellCentres to file " << str.name() << endl;
+
+        label vertI = 0;
+
+        forAll(patchFc, i)
+        {
+            meshTools::writeOBJ(str, patchFc[i]);
+            vertI++;
+            meshTools::writeOBJ(str, sampleLocations[i]);
+            vertI++;
+            str << "l " << vertI-1 << ' ' << vertI << nl;
+        }
+    }
+
+
+    // Check that actual offset vector (sampleLocations - patchFc) is more or
+    // less constant.
+    if (Pstream::master())
+    {
+        const scalarField magOffset(mag(sampleLocations - patchFc));
+        const scalar avgOffset(average(magOffset));
+
+        forAll(magOffset, sampleI)
+        {
+            if (mag(magOffset[sampleI]-avgOffset) > max(SMALL, 0.001*avgOffset))
+            {
+                WarningIn("directMappedPatchBase::calcMapping() const")
+                    << "The actual cell/face centres picked up using offset "
+                    << offset_ << " are not" << endl
+                    << "    on a single plane."
+                    << " This might give numerical problems." << endl
+                    << "    At patchface " << patchFc[sampleI]
+                    << " the sampled cell/face " << sampleLocations[sampleI]
+                    << endl
+                    << "    is not on a plane " << avgOffset
+                    << " offset from the patch." << endl
+                    << "    You might want to shift your plane offset."
+                    << " Set the debug flag to get a dump of sampled cells."
+                    << endl;
+                break;
+            }
+        }
+    }
+
+
+    // Determine schedule.
+    mapPtr_.reset(new mapDistribute(sampleProcs, patchFaceProcs));
+
+    // Rework the schedule from indices into samples to cell data to send,
+    // face data to receive.
+
+    labelListList& subMap = mapPtr_().subMap();
+    labelListList& constructMap = mapPtr_().constructMap();
+
+    forAll(subMap, procI)
+    {
+        subMap[procI] = UIndirectList<label>
+        (
+            sampleIndices,
+            subMap[procI]
+        );
+        constructMap[procI] = UIndirectList<label>
+        (
+            patchFaces,
+            constructMap[procI]
+        );
+
+        if (debug)
+        {
+            Pout<< "To proc:" << procI << " sending values of cells/faces:"
+                << subMap[procI] << endl;
+            Pout<< "From proc:" << procI << " receiving values of patch faces:"
+                << constructMap[procI] << endl;
+        }
+    }
+
+    // Redo constructSize
+    mapPtr_().constructSize() = patch_.size();
+
+    if (debug)
+    {
+        // Check that all elements get a value.
+        PackedBoolList used(patch_.size());
+        forAll(constructMap, procI)
+        {
+            const labelList& map = constructMap[procI];
+
+            forAll(map, i)
+            {
+                label faceI = map[i];
+
+                if (used[faceI] == 0)
+                {
+                    used[faceI] = 1;
+                }
+                else
+                {
+                    FatalErrorIn("directMappedPatchBase::calcMapping() const")
+                        << "On patch " << patch_.name()
+                        << " patchface " << faceI
+                        << " is assigned to more than once."
+                        << abort(FatalError);
+                }
+            }
+        }
+        forAll(used, faceI)
+        {
+            if (used[faceI] == 0)
+            {
+                FatalErrorIn("directMappedPatchBase::calcMapping() const")
+                    << "On patch " << patch_.name()
+                    << " patchface " << faceI
+                    << " is never assigned to."
+                    << abort(FatalError);
+            }
+        }
+    }
+}
+
+
+// * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * * * * * //
+
+Foam::directMappedPatchBase::directMappedPatchBase
+(
+     const polyPatch& pp
+)
+:
+    patch_(pp),
+    sampleRegion_(patch_.boundaryMesh().mesh().name()),
+    mode_(NEARESTPATCHFACE),
+    samplePatch_("none"),
+    offset_(vector::zero),
+    sameRegion_(sampleRegion_ == patch_.boundaryMesh().mesh().name()),
+    mapPtr_(NULL)
+{}
+
+
+Foam::directMappedPatchBase::directMappedPatchBase
+(
+    const polyPatch& pp,
+    const dictionary& dict
+)
+:
+    patch_(pp),
+    sampleRegion_
+    (
+        dict.lookupOrDefault
+        (
+            "sampleRegion",
+            patch_.boundaryMesh().mesh().name()
+        )
+    ),
+    mode_(sampleModeNames_.read(dict.lookup("sampleMode"))),
+    samplePatch_(dict.lookup("samplePatch")),
+    offset_(dict.lookup("offset")),
+    sameRegion_(sampleRegion_ == patch_.boundaryMesh().mesh().name()),
+    mapPtr_(NULL)
+{}
+
+
+Foam::directMappedPatchBase::directMappedPatchBase
+(
+    const polyPatch& pp,
+    const directMappedPatchBase& dmp
+)
+:
+    patch_(pp),
+    sampleRegion_(dmp.sampleRegion_),
+    mode_(dmp.mode_),
+    samplePatch_(dmp.samplePatch_),
+    offset_(dmp.offset_),
+    sameRegion_(dmp.sameRegion_),
+    mapPtr_(NULL)
+{}
+
+
+// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
+
+Foam::directMappedPatchBase::~directMappedPatchBase()
+{
+    clearOut();
+}
+
+
+void Foam::directMappedPatchBase::clearOut()
+{
+    mapPtr_.clear();
+}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+const Foam::polyMesh& Foam::directMappedPatchBase::sampleMesh() const
+{
+    return patch_.boundaryMesh().mesh().time().lookupObject<polyMesh>
+    (
+        sampleRegion_
+    );
+}
+
+
+const Foam::polyPatch& Foam::directMappedPatchBase::samplePolyPatch() const
+{
+    const polyMesh& nbrMesh = sampleMesh();
+
+    label patchI = nbrMesh.boundaryMesh().findPatchID(samplePatch_);
+
+    if (patchI == -1)
+    {
+        FatalErrorIn("directMappedPatchBase::samplePolyPatch() ")
+            << "Cannot find patch " << samplePatch_
+            << " in region " << sampleRegion_ << endl
+            << "Valid patches are " << nbrMesh.boundaryMesh().names()
+            << exit(FatalError);
+    }
+
+    return nbrMesh.boundaryMesh()[patchI];
+}
+
+
+void Foam::directMappedPatchBase::write(Ostream& os) const
+{
+    os.writeKeyword("sampleMode") << sampleModeNames_[mode_]
+        << token::END_STATEMENT << nl;
+    os.writeKeyword("sampleRegion") << sampleRegion_
+        << token::END_STATEMENT << nl;
+    os.writeKeyword("samplePatch") << samplePatch_
+        << token::END_STATEMENT << nl;
+    os.writeKeyword("offset") << offset_ << token::END_STATEMENT << nl;
+}
+
+
+// ************************************************************************* //
diff --git a/src/meshTools/directMapped/directMappedPolyPatch/directMappedPatchBase.H b/src/meshTools/directMapped/directMappedPolyPatch/directMappedPatchBase.H
new file mode 100644
index 0000000000000000000000000000000000000000..1a476f66a9eb392021ac0d8085bfbe804f82bccf
--- /dev/null
+++ b/src/meshTools/directMapped/directMappedPolyPatch/directMappedPatchBase.H
@@ -0,0 +1,248 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  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::directMappedPatchBase
+
+Description
+    Determines a mapping between patch face centres and mesh cell or face
+    centres and processors they're on.
+
+Note
+    Storage is not optimal. It temporary collects all (patch)face centres
+    on all processors to keep the addressing calculation simple.
+
+SourceFiles
+    directMappedPatchBase.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef directMappedPatchBase_H
+#define directMappedPatchBase_H
+
+#include "pointField.H"
+#include "Tuple2.H"
+#include "pointIndexHit.H"
+#include "mapDistribute.H"
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+class polyPatch;
+class polyMesh;
+
+/*---------------------------------------------------------------------------*\
+                      Class directMappedPatchBase Declaration
+\*---------------------------------------------------------------------------*/
+
+class directMappedPatchBase
+{
+
+public:
+
+        //- Mesh items to sample
+        enum sampleMode
+        {
+            NEARESTCELL,
+            NEARESTPATCHFACE,
+            NEARESTFACE
+        };
+
+private:
+
+    // Private data
+
+        static const NamedEnum<sampleMode, 3> sampleModeNames_;
+
+        //- Patch to sample
+        const polyPatch& patch_;
+
+        //- Region to sample
+        const word sampleRegion_;
+
+        //- What to sample
+        const sampleMode mode_;
+
+        //- Patch (only if NEARESTBOUNDARY)
+        const word samplePatch_;
+
+        //- Offset vector
+        const vector offset_;
+
+        //- Same region
+        const bool sameRegion_;
+
+
+        // Derived information
+
+            //- Communication schedule:
+            //  - Cells/faces to sample per processor
+            //  - Patch faces to receive per processor
+            //  - schedule
+            mutable autoPtr<mapDistribute> mapPtr_;
+
+    // Private Member Functions
+
+        //- Collect single list of samples and originating processor+face.
+        void collectSamples
+        (
+            pointField&,
+            labelList& patchFaceProcs,
+            labelList& patchFaces,
+            pointField& patchFc
+        ) const;
+
+        //- Find cells/faces containing samples
+        void findSamples
+        (
+            const pointField&,
+            labelList& sampleProcs,     // processor containing sample
+            labelList& sampleIndices,   // local index of cell/face
+            pointField& sampleLocations // actual representative location
+        ) const;
+
+        //- Calculate matching
+        void calcMapping() const;
+
+
+    // Private class
+
+        //- Private class for finding nearest
+        //  - point+local index
+        //  - sqr(distance)
+        //  - processor
+        typedef Tuple2<pointIndexHit, Tuple2<scalar, label> > nearInfo;
+
+        class nearestEqOp
+        {
+
+        public:
+
+            void operator()(nearInfo& x, const nearInfo& y) const
+            {
+                if (y.first().hit())
+                {
+                    if (!x.first().hit())
+                    {
+                        x = y;
+                    }
+                    else if (y.second().first() < x.second().first())
+                    {
+                        x = y;
+                    }
+                }
+            }
+        };
+
+
+public:
+
+    //- Runtime type information
+    ClassName("directMappedPatchBase");
+
+
+    // Constructors
+
+        //- Construct from components
+        directMappedPatchBase(const polyPatch&);
+
+        //- Construct from dictionary
+        directMappedPatchBase(const polyPatch&, const dictionary&);
+
+        //- Construct as copy, resetting patch
+        directMappedPatchBase(const polyPatch&, const directMappedPatchBase&);
+
+
+    // Destructor
+
+        ~directMappedPatchBase();
+
+        void clearOut();
+
+
+    // Member functions
+
+        //- What to sample
+        const sampleMode& mode() const
+        {
+            return mode_;
+        }
+
+        //- Region to sample
+        const word& sampleRegion() const
+        {
+            return sampleRegion_;
+        }
+
+        //- Patch (only if NEARESTBOUNDARY)
+        const word& samplePatch() const
+        {
+            return samplePatch_;
+        }
+
+        //- Offset vector (from patch faces to destination mesh objects)
+        const vector& offset() const
+        {
+            return offset_;
+        }
+
+        //- Return reference to the parallel distribution map
+        const mapDistribute& map() const
+        {
+            if (mapPtr_.empty())
+            {
+                calcMapping();
+            }
+            return mapPtr_();
+        }
+
+        //- Cached sampleRegion != mesh.name()
+        bool sameRegion() const
+        {
+            return sameRegion_;
+        }
+
+        //- Get the region mesh
+        const polyMesh& sampleMesh() const;
+
+        //- Get the patch on the region
+        const polyPatch& samplePolyPatch() const;
+
+        //- Write as a dictionary
+        virtual void write(Ostream&) const;
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/meshTools/directMapped/directMappedPolyPatch/directMappedPolyPatch.C b/src/meshTools/directMapped/directMappedPolyPatch/directMappedPolyPatch.C
index 9dbe7e8c1331ef7a68bdb0d4ade891b8aa002aef..0058c84d0df42bd5448ff9e3ba15fd4f1674c95e 100644
--- a/src/meshTools/directMapped/directMappedPolyPatch/directMappedPolyPatch.C
+++ b/src/meshTools/directMapped/directMappedPolyPatch/directMappedPolyPatch.C
@@ -26,11 +26,6 @@ License
 
 #include "directMappedPolyPatch.H"
 #include "addToRunTimeSelectionTable.H"
-#include "ListListOps.H"
-#include "meshSearch.H"
-#include "mapDistribute.H"
-#include "meshTools.H"
-#include "OFstream.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -40,469 +35,11 @@ namespace Foam
 
     addToRunTimeSelectionTable(polyPatch, directMappedPolyPatch, word);
     addToRunTimeSelectionTable(polyPatch, directMappedPolyPatch, dictionary);
-
-
-    template<>
-    const char* NamedEnum<directMappedPolyPatch::sampleMode, 3>::names[] =
-    {
-        "nearestCell",
-        "nearestPatchFace",
-        "nearestFace"
-    };
-
-    const NamedEnum<directMappedPolyPatch::sampleMode, 3>
-        directMappedPolyPatch::sampleModeNames_;
 }
 
 
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
-void Foam::directMappedPolyPatch::collectSamples
-(
-    pointField& samples,
-    labelList& patchFaceProcs,
-    labelList& patchFaces,
-    pointField& patchFc
-) const
-{
-
-    // Collect all sample points and the faces they come from.
-    List<pointField> globalFc(Pstream::nProcs());
-    List<pointField> globalSamples(Pstream::nProcs());
-    labelListList globalFaces(Pstream::nProcs());
-
-    globalFc[Pstream::myProcNo()] = this->faceCentres();
-    globalSamples[Pstream::myProcNo()] = globalFc[Pstream::myProcNo()]+offset_;
-    globalFaces[Pstream::myProcNo()] = identity(size());
-
-    // Distribute to all processors
-    Pstream::gatherList(globalSamples);
-    Pstream::scatterList(globalSamples);
-    Pstream::gatherList(globalFaces);
-    Pstream::scatterList(globalFaces);
-    Pstream::gatherList(globalFc);
-    Pstream::scatterList(globalFc);
-
-    // Rework into straight list
-    samples = ListListOps::combine<pointField>
-    (
-        globalSamples,
-        accessOp<pointField>()
-    );
-    patchFaces = ListListOps::combine<labelList>
-    (
-        globalFaces,
-        accessOp<labelList>()
-    );
-    patchFc = ListListOps::combine<pointField>
-    (
-        globalFc,
-        accessOp<pointField>()
-    );
-
-    patchFaceProcs.setSize(patchFaces.size());
-    labelList nPerProc
-    (
-        ListListOps::subSizes
-        (
-            globalFaces,
-            accessOp<labelList>()
-        )
-    );
-    label sampleI = 0;
-    forAll(nPerProc, procI)
-    {
-        for (label i = 0; i < nPerProc[procI]; i++)
-        {
-            patchFaceProcs[sampleI++] = procI;
-        }
-    }
-}
-
-
-// Find the processor/cell containing the samples. Does not account
-// for samples being found in two processors.
-void Foam::directMappedPolyPatch::findSamples
-(
-    const pointField& samples,
-    labelList& sampleProcs,
-    labelList& sampleIndices,
-    pointField& sampleLocations
-) const
-{
-    const polyMesh& mesh = boundaryMesh().mesh();
-
-    // All the info for nearest. Construct to miss
-    List<nearInfo> nearest(samples.size());
-
-    switch (mode_)
-    {
-        case NEARESTCELL:
-        {
-            if (samplePatch_.size() && samplePatch_ != "none")
-            {
-                FatalErrorIn
-                (
-                    "directMappedPolyPatch::findSamples(const pointField&,"
-                    " labelList&, labelList&, pointField&) const"
-                )   << "No need to supply a patch name when in "
-                    << sampleModeNames_[mode_] << " mode." << exit(FatalError);
-            }
-
-            // Octree based search engine
-            meshSearch meshSearchEngine(mesh, false);
-
-            forAll(samples, sampleI)
-            {
-                const point& sample = samples[sampleI];
-
-                label cellI = meshSearchEngine.findCell(sample);
-
-                if (cellI == -1)
-                {
-                    nearest[sampleI].second().first() = Foam::sqr(GREAT);
-                    nearest[sampleI].second().second() = Pstream::myProcNo();
-                }
-                else
-                {
-                    const point& cc = mesh.cellCentres()[cellI];
-
-                    nearest[sampleI].first() = pointIndexHit
-                    (
-                        true,
-                        cc,
-                        cellI
-                    );
-                    nearest[sampleI].second().first() = magSqr(cc-sample);
-                    nearest[sampleI].second().second() = Pstream::myProcNo();
-                }
-            }
-            break;
-        }
-
-        case NEARESTPATCHFACE:
-        {
-            label patchI = boundaryMesh().findPatchID(samplePatch_);
-
-            if (patchI == -1)
-            {
-                FatalErrorIn("directMappedPolyPatch::findSamples(..)")
-                    << "Cannot find patch " << samplePatch_ << endl
-                    << "Valid patches are " << boundaryMesh().names()
-                    << exit(FatalError);
-            }
-
-            Random rndGen(123456);
-
-            const polyPatch& pp = boundaryMesh()[patchI];
-
-            if (pp.empty())
-            {
-                forAll(samples, sampleI)
-                {
-                    nearest[sampleI].second().first() = Foam::sqr(GREAT);
-                    nearest[sampleI].second().second() = Pstream::myProcNo();
-                }
-            }
-            else
-            {
-                // patch faces
-                const labelList patchFaces(identity(pp.size()) + pp.start());
-
-                treeBoundBox patchBb
-                (
-                    treeBoundBox(pp.points(), pp.meshPoints()).extend
-                    (
-                        rndGen,
-                        1E-4
-                    )
-                );
-                patchBb.min() -= point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL);
-                patchBb.max() += point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL);
-
-                autoPtr<indexedOctree<treeDataFace> > boundaryTree
-                (
-                    new indexedOctree<treeDataFace>
-                    (
-                        treeDataFace  // all information needed to search faces
-                        (
-                            false,                      // do not cache bb
-                            mesh,
-                            patchFaces                  // boundary faces only
-                        ),
-                        patchBb,   // overall search domain
-                        8,                              // maxLevel
-                        10,                             // leafsize
-                        3.0                             // duplicity
-                    )
-                );
-
-                forAll(samples, sampleI)
-                {
-                    const point& sample = samples[sampleI];
-
-                    pointIndexHit& nearInfo = nearest[sampleI].first();
-                    nearInfo = boundaryTree().findNearest
-                    (
-                        sample,
-                        magSqr(patchBb.span())
-                    );
-
-                    if (!nearInfo.hit())
-                    {
-                        nearest[sampleI].second().first() = Foam::sqr(GREAT);
-                        nearest[sampleI].second().second() =
-                            Pstream::myProcNo();
-                    }
-                    else
-                    {
-                        point fc(pp[nearInfo.index()].centre(pp.points()));
-                        nearInfo.setPoint(fc);
-                        nearest[sampleI].second().first() = magSqr(fc-sample);
-                        nearest[sampleI].second().second() =
-                            Pstream::myProcNo();
-                    }
-                }
-            }
-            break;
-        }
-
-        case NEARESTFACE:
-        {
-            if (samplePatch_.size() && samplePatch_ != "none")
-            {
-                FatalErrorIn
-                (
-                    "directMappedPolyPatch::findSamples(const pointField&,"
-                    " labelList&, labelList&, pointField&) const"
-                )   << "No need to supply a patch name when in "
-                    << sampleModeNames_[mode_] << " mode." << exit(FatalError);
-            }
-
-            // Octree based search engine
-            meshSearch meshSearchEngine(mesh, false);
-
-            forAll(samples, sampleI)
-            {
-                const point& sample = samples[sampleI];
-
-                label faceI = meshSearchEngine.findNearestFace(sample);
-
-                if (faceI == -1)
-                {
-                    nearest[sampleI].second().first() = Foam::sqr(GREAT);
-                    nearest[sampleI].second().second() = Pstream::myProcNo();
-                }
-                else
-                {
-                    const point& fc = mesh.faceCentres()[faceI];
-
-                    nearest[sampleI].first() = pointIndexHit
-                    (
-                        true,
-                        fc,
-                        faceI
-                    );
-                    nearest[sampleI].second().first() = magSqr(fc-sample);
-                    nearest[sampleI].second().second() = Pstream::myProcNo();
-                }
-            }
-            break;
-        }
-
-        default:
-        {
-            FatalErrorIn("directMappedPolyPatch::findSamples(..)")
-                << "problem." << abort(FatalError);
-        }
-    }
-
-
-    // Find nearest.
-    Pstream::listCombineGather(nearest, nearestEqOp());
-    Pstream::listCombineScatter(nearest);
-
-    if (debug)
-    {
-        Info<< "directMappedPolyPatch::findSamples : " << endl;
-        forAll(nearest, sampleI)
-        {
-            label procI = nearest[sampleI].second().second();
-            label localI = nearest[sampleI].first().index();
-
-            Info<< "    " << sampleI << " coord:"<< samples[sampleI]
-                << " found on processor:" << procI
-                << " in local cell/face:" << localI
-                << " with cc:" << nearest[sampleI].first().rawPoint() << endl;
-        }
-    }
-
-    // Check for samples not being found
-    forAll(nearest, sampleI)
-    {
-        if (!nearest[sampleI].first().hit())
-        {
-            FatalErrorIn
-            (
-                "directMappedPolyPatch::findSamples"
-                "(const pointField&, labelList&"
-                ", labelList&, pointField&)"
-            )   << "Did not find sample " << samples[sampleI]
-                << " on any processor." << exit(FatalError);
-        }
-    }
-
-
-    // Convert back into proc+local index
-    sampleProcs.setSize(samples.size());
-    sampleIndices.setSize(samples.size());
-    sampleLocations.setSize(samples.size());
-
-    forAll(nearest, sampleI)
-    {
-        sampleProcs[sampleI] = nearest[sampleI].second().second();
-        sampleIndices[sampleI] = nearest[sampleI].first().index();
-        sampleLocations[sampleI] = nearest[sampleI].first().hitPoint();
-    }
-}
-
-
-void Foam::directMappedPolyPatch::calcMapping() const
-{
-    if (sendLabelsPtr_.valid())
-    {
-        FatalErrorIn("directMappedPolyPatch::calcMapping() const")
-            << "Mapping already calculated" << exit(FatalError);
-    }
-
-    if (offset_ == vector::zero)
-    {
-        FatalErrorIn("directMappedPolyPatch::calcMapping() const")
-            << "Invalid offset " << offset_ << endl
-            << "Offset is the vector added to the patch face centres to"
-            << " find the cell supplying the data."
-            << exit(FatalError);
-    }
-
-
-    // Get global list of all samples and the processor and face they come from.
-    pointField samples;
-    labelList patchFaceProcs;
-    labelList patchFaces;
-    pointField patchFc;
-    collectSamples(samples, patchFaceProcs, patchFaces, patchFc);
-
-    // Find processor and cell/face samples are in and actual location.
-    labelList sampleProcs;
-    labelList sampleIndices;
-    pointField sampleLocations;
-    findSamples(samples, sampleProcs, sampleIndices, sampleLocations);
-
-
-    // Now we have all the data we need:
-    // - where sample originates from (so destination when mapping):
-    //   patchFaces, patchFaceProcs.
-    // - cell/face sample is in (so source when mapping)
-    //   sampleIndices, sampleProcs.
-
-
-    if (debug && Pstream::master())
-    {
-        OFstream str
-        (
-            boundaryMesh().mesh().time().path()
-          / name()
-          + "_directMapped.obj"
-        );
-        Pout<< "Dumping mapping as lines from patch faceCentres to"
-            << " sampled cellCentres to file " << str.name() << endl;
-
-        label vertI = 0;
-
-        forAll(patchFc, i)
-        {
-            meshTools::writeOBJ(str, patchFc[i]);
-            vertI++;
-            meshTools::writeOBJ(str, sampleLocations[i]);
-            vertI++;
-            str << "l " << vertI-1 << ' ' << vertI << nl;
-        }
-    }
-
-
-    // Check that actual offset vector (sampleLocations - patchFc) is more or
-    // less constant.
-    if (Pstream::master())
-    {
-        const scalarField magOffset(mag(sampleLocations - patchFc));
-        const scalar avgOffset(average(magOffset));
-
-        forAll(magOffset, sampleI)
-        {
-            if (mag(magOffset[sampleI]-avgOffset) > 0.001*avgOffset)
-            {
-                WarningIn("directMappedPolyPatch::calcMapping() const")
-                    << "The actual cell centres picked up using offset "
-                    << offset_ << " are not" << endl
-                    << "    on a single plane."
-                    << " This might give numerical problems." << endl
-                    << "    At patchface " << patchFc[sampleI]
-                    << " the sampled cell " << sampleLocations[sampleI] << endl
-                    << "    is not on a plane " << avgOffset
-                    << " offset from the patch." << endl
-                    << "    You might want to shift your plane offset."
-                    << " Set the debug flag to get a dump of sampled cells."
-                    << endl;
-                break;
-            }
-        }
-    }
-
-
-    // Determine schedule.
-    mapDistribute distMap(sampleProcs, patchFaceProcs);
-
-    // Rework the schedule to cell data to send, face data to receive.
-    schedulePtr_.reset(new List<labelPair>(distMap.schedule()));
-
-    const labelListList& subMap = distMap.subMap();
-    const labelListList& constructMap = distMap.constructMap();
-
-    // Extract the particular data I need to send and receive.
-    sendLabelsPtr_.reset(new labelListList(subMap.size()));
-    labelListList& sendLabels = sendLabelsPtr_();
-
-    forAll(subMap, procI)
-    {
-        sendLabels[procI] = UIndirectList<label>
-        (
-            sampleIndices,
-            subMap[procI]
-        );
-
-        if (debug)
-        {
-            Pout<< "To proc:" << procI << " sending values of cells/faces:"
-                << sendLabels[procI] << endl;
-        }
-    }
-
-    receiveFaceLabelsPtr_.reset(new labelListList(constructMap.size()));
-    labelListList& receiveFaceLabels = receiveFaceLabelsPtr_();
-
-    forAll(constructMap, procI)
-    {
-        receiveFaceLabels[procI] =
-            UIndirectList<label>(patchFaces, constructMap[procI]);
-
-        if (debug)
-        {
-            Pout<< "From proc:" << procI << " receiving values of patch faces:"
-                << receiveFaceLabels[procI] << endl;
-        }
-    }
-}
-
 
 // * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * * * * * //
 
@@ -516,12 +53,7 @@ Foam::directMappedPolyPatch::directMappedPolyPatch
 )
 :
     polyPatch(name, size, start, index, bm),
-    mode_(NEARESTPATCHFACE),
-    samplePatch_("none"),
-    offset_(vector::zero),
-    schedulePtr_(NULL),
-    sendLabelsPtr_(NULL),
-    receiveFaceLabelsPtr_(NULL)
+    directMappedPatchBase(static_cast<const polyPatch&>(*this))
 {}
 
 
@@ -534,12 +66,7 @@ Foam::directMappedPolyPatch::directMappedPolyPatch
 )
 :
     polyPatch(name, dict, index, bm),
-    mode_(sampleModeNames_.read(dict.lookup("sampleMode"))),
-    samplePatch_(dict.lookup("samplePatch")),
-    offset_(dict.lookup("offset")),
-    schedulePtr_(NULL),
-    sendLabelsPtr_(NULL),
-    receiveFaceLabelsPtr_(NULL)
+    directMappedPatchBase(*this, dict)
 {}
 
 
@@ -550,12 +77,7 @@ Foam::directMappedPolyPatch::directMappedPolyPatch
 )
 :
     polyPatch(pp, bm),
-    mode_(pp.mode_),
-    samplePatch_(pp.samplePatch_),
-    offset_(pp.offset_),
-    schedulePtr_(NULL),
-    sendLabelsPtr_(NULL),
-    receiveFaceLabelsPtr_(NULL)
+    directMappedPatchBase(*this, pp)
 {}
 
 
@@ -569,12 +91,7 @@ Foam::directMappedPolyPatch::directMappedPolyPatch
 )
 :
     polyPatch(pp, bm, index, newSize, newStart),
-    mode_(pp.mode_),
-    samplePatch_(pp.samplePatch_),
-    offset_(pp.offset_),
-    schedulePtr_(NULL),
-    sendLabelsPtr_(NULL),
-    receiveFaceLabelsPtr_(NULL)
+    directMappedPatchBase(*this, pp)
 {}
 
 
@@ -582,28 +99,59 @@ Foam::directMappedPolyPatch::directMappedPolyPatch
 
 Foam::directMappedPolyPatch::~directMappedPolyPatch()
 {
-    clearOut();
+    directMappedPatchBase::clearOut();
 }
 
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
-void Foam::directMappedPolyPatch::clearOut()
+//- Initialise the calculation of the patch geometry
+void Foam::directMappedPolyPatch::initGeometry()
+{
+    polyPatch::initGeometry();
+    directMappedPatchBase::clearOut();
+}
+
+//- Calculate the patch geometry
+void Foam::directMappedPolyPatch::calcGeometry()
+{
+    polyPatch::calcGeometry();
+    directMappedPatchBase::clearOut();
+}
+
+//- Initialise the patches for moving points
+void Foam::directMappedPolyPatch::initMovePoints(const pointField& p)
+{
+    polyPatch::initMovePoints(p);
+    directMappedPatchBase::clearOut();
+}
+
+//- Correct patches after moving points
+void Foam::directMappedPolyPatch::movePoints(const pointField& p)
+{
+    polyPatch::movePoints(p);
+    directMappedPatchBase::clearOut();
+}
+
+//- Initialise the update of the patch topology
+void Foam::directMappedPolyPatch::initUpdateMesh()
+{
+    polyPatch::initUpdateMesh();
+    directMappedPatchBase::clearOut();
+}
+
+//- Update of the patch topology
+void Foam::directMappedPolyPatch::updateMesh()
 {
-    schedulePtr_.clear();
-    sendLabelsPtr_.clear();
-    receiveFaceLabelsPtr_.clear();
+    polyPatch::updateMesh();
+    directMappedPatchBase::clearOut();
 }
 
 
 void Foam::directMappedPolyPatch::write(Ostream& os) const
 {
     polyPatch::write(os);
-    os.writeKeyword("sampleMode") << sampleModeNames_[mode_]
-        << token::END_STATEMENT << nl;
-    os.writeKeyword("samplePatch") << samplePatch_
-        << token::END_STATEMENT << nl;
-    os.writeKeyword("offset") << offset_ << token::END_STATEMENT << nl;
+    directMappedPatchBase::write(os);
 }
 
 
diff --git a/src/meshTools/directMapped/directMappedPolyPatch/directMappedPolyPatch.H b/src/meshTools/directMapped/directMappedPolyPatch/directMappedPolyPatch.H
index 413737aa80c5cbb694fccb8dc8db7866c8d643b5..e07f78a958cfc3c85c4d361b253f9f068a342433 100644
--- a/src/meshTools/directMapped/directMappedPolyPatch/directMappedPolyPatch.H
+++ b/src/meshTools/directMapped/directMappedPolyPatch/directMappedPolyPatch.H
@@ -42,9 +42,7 @@ SourceFiles
 #define directMappedPolyPatch_H
 
 #include "polyPatch.H"
-#include "labelPair.H"
-#include "Tuple2.H"
-#include "pointIndexHit.H"
+#include "directMappedPatchBase.H"
 
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@@ -52,154 +50,43 @@ SourceFiles
 namespace Foam
 {
 
+class polyMesh;
+
 /*---------------------------------------------------------------------------*\
                       Class directMappedPolyPatch Declaration
 \*---------------------------------------------------------------------------*/
 
 class directMappedPolyPatch
 :
-    public polyPatch
+    public polyPatch,
+    public directMappedPatchBase
 {
 
-public:
-
-        //- Mesh items to sample
-        enum sampleMode
-        {
-            NEARESTCELL,
-            NEARESTPATCHFACE,
-            NEARESTFACE
-        };
-
-private:
-
-    // Private data
-
-        static const NamedEnum<sampleMode, 3> sampleModeNames_;
-
-        //- What to sample
-        sampleMode mode_;
-
-        //- Patch (only if NEARESTBOUNDARY)
-        const word samplePatch_;
-
-        //- Offset vector
-        const vector offset_;
-
-
-
-        // Derived information
-
-            //- Communication schedule.
-            mutable autoPtr<List<labelPair> > schedulePtr_;
-
-            //- Cells/faces to sample per processor
-            mutable autoPtr<labelListList> sendLabelsPtr_;
-
-            //- Patch faces to receive per processor
-            mutable autoPtr<labelListList> receiveFaceLabelsPtr_;
-
-
-    // Private Member Functions
-
-        //- Collect single list of samples and originating processor+face.
-        void collectSamples
-        (
-            pointField&,
-            labelList& patchFaceProcs,
-            labelList& patchFaces,
-            pointField& patchFc
-        ) const;
-
-        //- Find cells/faces containing samples
-        void findSamples
-        (
-            const pointField&,
-            labelList& sampleProcs,     // processor containing sample
-            labelList& sampleIndices,   // local index of cell/face
-            pointField& sampleLocations // actual representative location
-        ) const;
-
-        //- Calculate matching
-        void calcMapping() const;
-
-
-    // Private class
-
-        //- Private class for finding nearest
-        //  - point+local index
-        //  - sqr(distance)
-        //  - processor
-        typedef Tuple2<pointIndexHit, Tuple2<scalar, label> > nearInfo;
-
-        class nearestEqOp
-        {
-
-        public:
-
-            void operator()(nearInfo& x, const nearInfo& y) const
-            {
-                if (y.first().hit())
-                {
-                    if (!x.first().hit())
-                    {
-                        x = y;
-                    }
-                    else if (y.second().first() < x.second().first())
-                    {
-                        x = y;
-                    }
-                }
-            }
-        };
-
-
-
 protected:
 
-        void clearOut();
-
         //- Initialise the calculation of the patch geometry
-        virtual void initGeometry()
-        {
-            clearOut();
-        }
+        virtual void initGeometry();
 
         //- Calculate the patch geometry
-        virtual void calcGeometry()
-        {
-            clearOut();
-        }
+        virtual void calcGeometry();
 
         //- Initialise the patches for moving points
-        virtual void initMovePoints(const pointField&)
-        {
-            clearOut();
-        }
+        virtual void initMovePoints(const pointField&);
 
         //- Correct patches after moving points
-        virtual void movePoints(const pointField& p)
-        {
-            clearOut();
-        }
+        virtual void movePoints(const pointField&);
 
         //- Initialise the update of the patch topology
-        virtual void initUpdateMesh()
-        {
-            clearOut();
-        }
+        virtual void initUpdateMesh();
 
         //- Update of the patch topology
-        virtual void updateMesh()
-        {
-            clearOut();
-        }
+        virtual void updateMesh();
 
 
 public:
 
     //- Runtime type information
-    TypeName("directMappedPatch");
+    TypeName("directMapped");
 
 
     // Constructors
@@ -271,72 +158,6 @@ public:
 
     // Member functions
 
-        //- What to sample
-        const sampleMode& mode() const
-        {
-            return mode_;
-        }
-
-        //- Patch (only if NEARESTBOUNDARY)
-        const word& samplePatch() const
-        {
-            return samplePatch_;
-        }
-
-        //- Offset vector (from patch faces to destination mesh objects)
-        const vector& offset() const
-        {
-            return offset_;
-        }
-
-        //- Access to communication.
-        const List<labelPair>& schedule() const
-        {
-            if (schedulePtr_.empty())
-            {
-                calcMapping();
-            }
-            return schedulePtr_();
-        }
-
-        //- Cells/faces to sample per processor
-        const labelListList& sendLabels() const
-        {
-            if (debug)
-            {
-                Pout<< "Asking for sendLabels." << endl;
-            }
-
-            if (sendLabelsPtr_.empty())
-            {
-                if (debug)
-                {
-                    Pout<< "Calculating mapping." << endl;
-                    calcMapping();
-                }
-            }
-            return sendLabelsPtr_();
-        }
-
-        //- Patch faces to receive per processor
-        const labelListList& receiveFaceLabels() const
-        {
-            if (debug)
-            {
-                Pout<< "Asking for receiveFaceLabels." << endl;
-            }
-
-            if (receiveFaceLabelsPtr_.empty())
-            {
-                if (debug)
-                {
-                    Pout<< "Calculating mapping." << endl;
-                    calcMapping();
-                }
-            }
-            return receiveFaceLabelsPtr_();
-        }
-
         //- Write the polyPatch data as a dictionary
         virtual void write(Ostream&) const;
 };
diff --git a/src/meshTools/directMapped/directMappedPolyPatch/directMappedWallPolyPatch.C b/src/meshTools/directMapped/directMappedPolyPatch/directMappedWallPolyPatch.C
new file mode 100644
index 0000000000000000000000000000000000000000..daaee3bcb4adf2b275627ede0a7489de6ca1115a
--- /dev/null
+++ b/src/meshTools/directMapped/directMappedPolyPatch/directMappedWallPolyPatch.C
@@ -0,0 +1,163 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  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 "directMappedWallPolyPatch.H"
+#include "addToRunTimeSelectionTable.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+    defineTypeNameAndDebug(directMappedWallPolyPatch, 0);
+
+    addToRunTimeSelectionTable(polyPatch, directMappedWallPolyPatch, word);
+    addToRunTimeSelectionTable
+    (
+        polyPatch,
+        directMappedWallPolyPatch,
+        dictionary
+    );
+}
+
+
+// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
+
+
+// * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * * * * * //
+
+Foam::directMappedWallPolyPatch::directMappedWallPolyPatch
+(
+    const word& name,
+    const label size,
+    const label start,
+    const label index,
+    const polyBoundaryMesh& bm
+)
+:
+    wallPolyPatch(name, size, start, index, bm),
+    directMappedPatchBase(static_cast<const polyPatch&>(*this))
+{}
+
+
+Foam::directMappedWallPolyPatch::directMappedWallPolyPatch
+(
+    const word& name,
+    const dictionary& dict,
+    const label index,
+    const polyBoundaryMesh& bm
+)
+:
+    wallPolyPatch(name, dict, index, bm),
+    directMappedPatchBase(*this, dict)
+{}
+
+
+Foam::directMappedWallPolyPatch::directMappedWallPolyPatch
+(
+    const directMappedWallPolyPatch& pp,
+    const polyBoundaryMesh& bm
+)
+:
+    wallPolyPatch(pp, bm),
+    directMappedPatchBase(*this, pp)
+{}
+
+
+Foam::directMappedWallPolyPatch::directMappedWallPolyPatch
+(
+    const directMappedWallPolyPatch& pp,
+    const polyBoundaryMesh& bm,
+    const label index,
+    const label newSize,
+    const label newStart
+)
+:
+    wallPolyPatch(pp, bm, index, newSize, newStart),
+    directMappedPatchBase(*this, pp)
+{}
+
+
+// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
+
+Foam::directMappedWallPolyPatch::~directMappedWallPolyPatch()
+{
+    directMappedPatchBase::clearOut();
+}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+//- Initialise the calculation of the patch geometry
+void Foam::directMappedWallPolyPatch::initGeometry()
+{
+    wallPolyPatch::initGeometry();
+    directMappedPatchBase::clearOut();
+}
+
+//- Calculate the patch geometry
+void Foam::directMappedWallPolyPatch::calcGeometry()
+{
+    wallPolyPatch::calcGeometry();
+    directMappedPatchBase::clearOut();
+}
+
+//- Initialise the patches for moving points
+void Foam::directMappedWallPolyPatch::initMovePoints(const pointField& p)
+{
+    wallPolyPatch::initMovePoints(p);
+    directMappedPatchBase::clearOut();
+}
+
+//- Correct patches after moving points
+void Foam::directMappedWallPolyPatch::movePoints(const pointField& p)
+{
+    wallPolyPatch::movePoints(p);
+    directMappedPatchBase::clearOut();
+}
+
+//- Initialise the update of the patch topology
+void Foam::directMappedWallPolyPatch::initUpdateMesh()
+{
+    wallPolyPatch::initUpdateMesh();
+    directMappedPatchBase::clearOut();
+}
+
+//- Update of the patch topology
+void Foam::directMappedWallPolyPatch::updateMesh()
+{
+    wallPolyPatch::updateMesh();
+    directMappedPatchBase::clearOut();
+}
+
+
+void Foam::directMappedWallPolyPatch::write(Ostream& os) const
+{
+    wallPolyPatch::write(os);
+    directMappedPatchBase::write(os);
+}
+
+
+// ************************************************************************* //
diff --git a/src/meshTools/directMapped/directMappedPolyPatch/directMappedWallPolyPatch.H b/src/meshTools/directMapped/directMappedPolyPatch/directMappedWallPolyPatch.H
new file mode 100644
index 0000000000000000000000000000000000000000..407d62ddda2c07958a45b0ea642567ceaf4c1078
--- /dev/null
+++ b/src/meshTools/directMapped/directMappedPolyPatch/directMappedWallPolyPatch.H
@@ -0,0 +1,181 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  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::directMappedWallPolyPatch
+
+Description
+    Determines a mapping between patch face centres and mesh cell or face
+    centres and processors they're on.
+
+Note
+    Storage is not optimal. It stores all face centres and cells on all
+    processors to keep the addressing calculation simple.
+
+SourceFiles
+    directMappedWallPolyPatch.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef directMappedWallPolyPatch_H
+#define directMappedWallPolyPatch_H
+
+#include "wallPolyPatch.H"
+#include "directMappedPatchBase.H"
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+class polyMesh;
+
+/*---------------------------------------------------------------------------*\
+                      Class directMappedWallPolyPatch Declaration
+\*---------------------------------------------------------------------------*/
+
+class directMappedWallPolyPatch
+:
+    public wallPolyPatch,
+    public directMappedPatchBase
+{
+
+protected:
+
+        //- Initialise the calculation of the patch geometry
+        virtual void initGeometry();
+
+        //- Calculate the patch geometry
+        virtual void calcGeometry();
+
+        //- Initialise the patches for moving points
+        virtual void initMovePoints(const pointField&);
+
+        //- Correct patches after moving points
+        virtual void movePoints(const pointField&);
+
+        //- Initialise the update of the patch topology
+        virtual void initUpdateMesh();
+
+        //- Update of the patch topology
+        virtual void updateMesh();
+
+
+public:
+
+    //- Runtime type information
+    TypeName("directMappedWall");
+
+
+    // Constructors
+
+        //- Construct from components
+        directMappedWallPolyPatch
+        (
+            const word& name,
+            const label size,
+            const label start,
+            const label index,
+            const polyBoundaryMesh& bm
+        );
+
+        //- Construct from dictionary
+        directMappedWallPolyPatch
+        (
+            const word& name,
+            const dictionary& dict,
+            const label index,
+            const polyBoundaryMesh& bm
+        );
+
+        //- Construct as copy, resetting the boundary mesh
+        directMappedWallPolyPatch
+        (
+            const directMappedWallPolyPatch&,
+            const polyBoundaryMesh&
+        );
+
+        //- Construct given the original patch and resetting the
+        //  face list and boundary mesh information
+        directMappedWallPolyPatch
+        (
+            const directMappedWallPolyPatch& pp,
+            const polyBoundaryMesh& bm,
+            const label index,
+            const label newSize,
+            const label newStart
+        );
+
+        //- Construct and return a clone, resetting the boundary mesh
+        virtual autoPtr<polyPatch> clone(const polyBoundaryMesh& bm) const
+        {
+            return autoPtr<polyPatch>(new directMappedWallPolyPatch(*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
+        {
+            return autoPtr<polyPatch>
+            (
+                new directMappedWallPolyPatch
+                (
+                    *this,
+                    bm,
+                    index,
+                    newSize,
+                    newStart
+                )
+            );
+        }
+
+
+    // Destructor
+
+        ~directMappedWallPolyPatch();
+
+
+    // Member functions
+
+        //- Write the polyPatch data as a dictionary
+        virtual void write(Ostream&) const;
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/meshTools/indexedOctree/indexedOctree.C b/src/meshTools/indexedOctree/indexedOctree.C
index 2131c3aaf6ef936fcf18bbe8f4cc39ffcdde93c5..4f555649996a3deb0ed264dedb43451002ad8479 100644
--- a/src/meshTools/indexedOctree/indexedOctree.C
+++ b/src/meshTools/indexedOctree/indexedOctree.C
@@ -29,6 +29,12 @@ License
 #include "meshTools.H"
 #include "OFstream.H"
 
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+template <class Type>
+Foam::scalar Foam::indexedOctree<Type>::perturbTol_ = 10*SMALL;
+
+
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
 // Does bb intersect a sphere around sample? Or is any corner point of bb
@@ -203,7 +209,7 @@ Foam::indexedOctree<Type>::divide
      || bb.min()[2] >= bb.max()[2]
     )
     {
-        FatalErrorIn("indexedOctree<Type>::divide")
+        FatalErrorIn("indexedOctree<Type>::divide(..)")
             << "Badly formed bounding box:" << bb
             << abort(FatalError);
     }
@@ -674,100 +680,815 @@ void Foam::indexedOctree<Type>::findNearest
 }
 
 
+template <class Type>
+Foam::treeBoundBox Foam::indexedOctree<Type>::subBbox
+(
+    const label parentNodeI,
+    const direction octant
+) const
+{
+    // Get type of node at octant
+    const node& nod = nodes_[parentNodeI];
+    labelBits index = nod.subNodes_[octant];
+
+    if (isNode(index))
+    {
+        // Use stored bb
+        return nodes_[getNode(index)].bb_;
+    }
+    else
+    {
+        // Calculate subBb
+        return nod.bb_.subBbox(octant);
+    }
+}
+
+
+// Takes a bb and a point on/close to the edge of the bb and pushes the point
+// inside by a small fraction. 
+template <class Type>
+Foam::point Foam::indexedOctree<Type>::pushPoint
+(
+    const treeBoundBox& bb,
+    const point& pt,
+    const bool pushInside
+)
+{
+    // Get local length scale.
+    const vector perturbVec = perturbTol_*(bb.span());
+
+    point perturbedPt(pt);
+
+    // Modify all components which are close to any face of the bb to be
+    // well inside/outside them.
+
+    if (pushInside)
+    {
+        for (direction dir = 0; dir < vector::nComponents; dir++)
+        {
+            if (mag(pt[dir]-bb.min()[dir]) < mag(perturbVec[dir]))
+            {
+                // Close to 'left' side. Push well beyond left side.
+                scalar perturbDist = perturbVec[dir] + ROOTVSMALL;
+                perturbedPt[dir] = bb.min()[dir] + perturbDist;
+            }
+            else if (mag(pt[dir]-bb.max()[dir]) < mag(perturbVec[dir]))
+            {
+                // Close to 'right' side. Push well beyond right side.
+                scalar perturbDist = perturbVec[dir] + ROOTVSMALL;
+                perturbedPt[dir] = bb.max()[dir] - perturbDist;
+            }
+        }
+    }
+    else
+    {
+        for (direction dir = 0; dir < vector::nComponents; dir++)
+        {
+            if (mag(pt[dir]-bb.min()[dir]) < mag(perturbVec[dir]))
+            {
+                scalar perturbDist = perturbVec[dir] + ROOTVSMALL;
+                perturbedPt[dir] = bb.min()[dir] - perturbDist;
+            }
+            else if (mag(pt[dir]-bb.max()[dir]) < mag(perturbVec[dir]))
+            {
+                scalar perturbDist = perturbVec[dir] + ROOTVSMALL;
+                perturbedPt[dir] = bb.max()[dir] + perturbDist;
+            }
+        }
+    }
+
+    if (debug)
+    {
+        if (pushInside != bb.contains(perturbedPt))
+        {
+            FatalErrorIn("indexedOctree<Type>::pushPoint(..)")
+                << "pushed point:" << pt
+                << " to:" << perturbedPt
+                << " wanted side:" << pushInside
+                << " obtained side:" << bb.contains(perturbedPt)
+                << " of bb:" << bb
+                << abort(FatalError);
+        }
+    }
+
+    return perturbedPt;
+}
+
+
+// Takes a bb and a point on the edge of the bb and pushes the point
+// outside by a small fraction. 
+template <class Type>
+Foam::point Foam::indexedOctree<Type>::pushPoint
+(
+    const treeBoundBox& bb,
+    const direction faceID,
+    const point& pt,
+    const bool pushInside
+)
+{
+    // Get local length scale.
+    const vector perturbVec = perturbTol_*bb.span();
+
+    point perturbedPt(pt);
+
+    // Modify all components which are close to any face of the bb to be
+    // well outside them.
+
+    if (faceID == 0)
+    {
+        FatalErrorIn("indexedOctree<Type>::pushPoint(..)")
+            << abort(FatalError);
+    }
+
+    if (faceID & treeBoundBox::LEFTBIT)
+    {
+        if (pushInside)
+        {
+            perturbedPt[0] = bb.min()[0] + (perturbVec[0] + ROOTVSMALL);
+        }
+        else
+        {
+            perturbedPt[0] = bb.min()[0] - (perturbVec[0] + ROOTVSMALL);
+        }
+    }
+    else if (faceID & treeBoundBox::RIGHTBIT)
+    {
+        if (pushInside)
+        {
+            perturbedPt[0] = bb.max()[0] - (perturbVec[0] + ROOTVSMALL);
+        }
+        else
+        {
+            perturbedPt[0] = bb.max()[0] + (perturbVec[0] + ROOTVSMALL);
+        }
+    }
+
+    if (faceID & treeBoundBox::BOTTOMBIT)
+    {
+        if (pushInside)
+        {
+            perturbedPt[1] = bb.min()[1] + (perturbVec[1] + ROOTVSMALL);
+        }
+        else
+        {
+            perturbedPt[1] = bb.min()[1] - (perturbVec[1] + ROOTVSMALL);
+        }
+    }
+    else if (faceID & treeBoundBox::TOPBIT)
+    {
+        if (pushInside)
+        {
+            perturbedPt[1] = bb.max()[1] - (perturbVec[1] + ROOTVSMALL);
+        }
+        else
+        {
+            perturbedPt[1] = bb.max()[1] + (perturbVec[1] + ROOTVSMALL);
+        }
+    }
+
+    if (faceID & treeBoundBox::BACKBIT)
+    {
+        if (pushInside)
+        {
+            perturbedPt[2] = bb.min()[2] + (perturbVec[2] + ROOTVSMALL);
+        }
+        else
+        {
+            perturbedPt[2] = bb.min()[2] - (perturbVec[2] + ROOTVSMALL);
+        }
+    }
+    else if (faceID & treeBoundBox::FRONTBIT)
+    {
+        if (pushInside)
+        {
+            perturbedPt[2] = bb.max()[2] - (perturbVec[2] + ROOTVSMALL);
+        }
+        else
+        {
+            perturbedPt[2] = bb.max()[2] + (perturbVec[2] + ROOTVSMALL);
+        }
+    }
+
+    if (debug)
+    {
+        if (pushInside != bb.contains(perturbedPt))
+        {
+            FatalErrorIn("indexedOctree<Type>::pushPoint(..)")
+                << "pushed point:" << pt << " on face:" << faceString(faceID)
+                << " to:" << perturbedPt
+                << " wanted side:" << pushInside
+                << " obtained side:" << bb.contains(perturbedPt)
+                << " of bb:" << bb
+                << abort(FatalError);
+        }
+    }
+
+    return perturbedPt;
+}
+
+
+// Guarantees that if pt is on a face it gets perturbed so it is away
+// from the face edges.
+// If pt is not on a face does nothing.
+template <class Type>
+Foam::point Foam::indexedOctree<Type>::pushPointIntoFace
+(
+    const treeBoundBox& bb,
+    const vector& dir,          // end-start
+    const point& pt
+)
+{
+    if (debug)
+    {
+        if (bb.posBits(pt) != 0)
+        {
+            FatalErrorIn("indexedOctree<Type>::pushPointIntoFace(..)")
+                << " bb:" << bb << endl
+                << "does not contain point " << pt << abort(FatalError);
+        }
+    }
+
+
+    // Handle two cases:
+    // - point exactly on multiple faces. Push away from all but one.
+    // - point on a single face. Push away from edges of face.
+
+    direction ptFaceID = bb.faceBits(pt);
+
+    direction nFaces = 0;
+    FixedList<direction, 3> faceIndices;
+
+    if (ptFaceID & treeBoundBox::LEFTBIT)
+    {
+        faceIndices[nFaces++] = treeBoundBox::LEFT;
+    }
+    else if (ptFaceID & treeBoundBox::RIGHTBIT)
+    {
+        faceIndices[nFaces++] = treeBoundBox::RIGHT;
+    }
+
+    if (ptFaceID & treeBoundBox::BOTTOMBIT)
+    {
+        faceIndices[nFaces++] = treeBoundBox::BOTTOM;
+    }
+    else if (ptFaceID & treeBoundBox::TOPBIT)
+    {
+        faceIndices[nFaces++] = treeBoundBox::TOP;
+    }
+
+    if (ptFaceID & treeBoundBox::BACKBIT)
+    {
+        faceIndices[nFaces++] = treeBoundBox::BACK;
+    }
+    else if (ptFaceID & treeBoundBox::FRONTBIT)
+    {
+        faceIndices[nFaces++] = treeBoundBox::FRONT;
+    }
+
+
+    // Determine the face we want to keep the point on
+
+    direction keepFaceID;
+
+    if (nFaces == 0)
+    {
+        // Return original point
+        return pt;
+    }
+    else if (nFaces == 1)
+    {
+        keepFaceID = faceIndices[0];
+    }
+    else
+    {
+        // Determine best face out of faceIndices[0 .. nFaces-1].
+        // The best face is the one most perpendicular to the ray direction.
+
+        keepFaceID = faceIndices[0];
+        scalar maxInproduct = mag(treeBoundBox::faceNormals[keepFaceID] & dir);
+
+        for (direction i = 1; i < nFaces; i++)
+        {
+            direction face = faceIndices[i];
+            scalar s = mag(treeBoundBox::faceNormals[face] & dir);
+            if (s > maxInproduct)
+            {
+                maxInproduct = s;
+                keepFaceID = face;
+            }
+        }
+    }
+
+
+    // 1. Push point into bb, away from all corners
+
+    point facePoint(pushPoint(bb, pt, true));
+    direction faceID = 0;
+
+    // 2. Snap it back onto the preferred face
+
+    if (keepFaceID == treeBoundBox::LEFT)
+    {
+        facePoint.x() = bb.min().x();
+        faceID = treeBoundBox::LEFTBIT;
+    }
+    else if (keepFaceID == treeBoundBox::RIGHT)
+    {
+        facePoint.x() = bb.max().x();
+        faceID = treeBoundBox::RIGHTBIT;
+    }
+    else if (keepFaceID == treeBoundBox::BOTTOM)
+    {
+        facePoint.y() = bb.min().y();
+        faceID = treeBoundBox::BOTTOMBIT;
+    }
+    else if (keepFaceID == treeBoundBox::TOP)
+    {
+        facePoint.y() = bb.max().y();
+        faceID = treeBoundBox::TOPBIT;
+    }
+    else if (keepFaceID == treeBoundBox::BACK)
+    {
+        facePoint.z() = bb.min().z();
+        faceID = treeBoundBox::BACKBIT;
+    }
+    else if (keepFaceID == treeBoundBox::FRONT)
+    {
+        facePoint.z() = bb.max().z();
+        faceID = treeBoundBox::FRONTBIT;
+    }
+
+
+    if (debug)
+    {
+        if (faceID != bb.faceBits(facePoint))
+        {
+            FatalErrorIn("indexedOctree<Type>::pushPointIntoFace(..)")
+                << "Pushed point from " << pt
+                << " on face:" << ptFaceID << " of bb:" << bb << endl
+                << "onto " << facePoint
+                << " on face:" << faceID
+                << " which is not consistent with geometric face "
+                << bb.faceBits(facePoint)
+                << abort(FatalError);
+        }
+        if (bb.posBits(facePoint) != 0)
+        {
+            FatalErrorIn("indexedOctree<Type>::pushPointIntoFace(..)")
+                << " bb:" << bb << endl
+                << "does not contain perturbed point "
+                << facePoint << abort(FatalError);
+        }
+    }
+
+
+    return facePoint;   
+}
+
+
+//// Takes a bb and a point on the outside of the bb. Checks if on multiple faces
+//// and if so perturbs point so it is only on one face.
+//template <class Type>
+//void Foam::indexedOctree<Type>::checkMultipleFaces
+//(
+//    const treeBoundBox& bb,
+//    const vector& dir,          // end-start
+//    pointIndexHit& faceHitInfo,
+//    direction& faceID
+//)
+//{
+//    // Do the quick elimination of no or one face.
+//    if
+//    (
+//        (faceID == 0)
+//     || (faceID == treeBoundBox::LEFTBIT)
+//     || (faceID == treeBoundBox::RIGHTBIT)
+//     || (faceID == treeBoundBox::BOTTOMBIT)
+//     || (faceID == treeBoundBox::TOPBIT)
+//     || (faceID == treeBoundBox::BACKBIT)
+//     || (faceID == treeBoundBox::FRONTBIT)
+//    )
+//    {
+//        return;
+//    }
+//
+//
+//    // Check the direction of vector w.r.t. faces being intersected.
+//    FixedList<scalar, 6> inproducts(-GREAT);
+//
+//    direction nFaces = 0;
+//
+//    if (faceID & treeBoundBox::LEFTBIT)
+//    {
+//        inproducts[treeBoundBox::LEFT] = mag
+//        (
+//            treeBoundBox::faceNormals[treeBoundBox::LEFT]
+//          & dir
+//        );
+//        nFaces++;
+//    }
+//    if (faceID & treeBoundBox::RIGHTBIT)
+//    {
+//        inproducts[treeBoundBox::RIGHT] = mag
+//        (
+//            treeBoundBox::faceNormals[treeBoundBox::RIGHT]
+//          & dir
+//        );
+//        nFaces++;
+//    }
+//
+//    if (faceID & treeBoundBox::BOTTOMBIT)
+//    {
+//        inproducts[treeBoundBox::BOTTOM] = mag
+//        (
+//            treeBoundBox::faceNormals[treeBoundBox::BOTTOM]
+//          & dir
+//        );
+//        nFaces++;
+//    }
+//    if (faceID & treeBoundBox::TOPBIT)
+//    {
+//        inproducts[treeBoundBox::TOP] = mag
+//        (
+//            treeBoundBox::faceNormals[treeBoundBox::TOP]
+//          & dir
+//        );
+//        nFaces++;
+//    }
+//
+//    if (faceID & treeBoundBox::BACKBIT)
+//    {
+//        inproducts[treeBoundBox::BACK] = mag
+//        (
+//            treeBoundBox::faceNormals[treeBoundBox::BACK]
+//          & dir
+//        );
+//        nFaces++;
+//    }
+//    if (faceID & treeBoundBox::FRONTBIT)
+//    {
+//        inproducts[treeBoundBox::FRONT] = mag
+//        (
+//            treeBoundBox::faceNormals[treeBoundBox::FRONT]
+//          & dir
+//        );
+//        nFaces++;
+//    }
+//
+//    if (nFaces == 0 || nFaces == 1 || nFaces > 3)
+//    {
+//        FatalErrorIn("indexedOctree<Type>::checkMultipleFaces(..)")
+//            << "Problem : nFaces:" << nFaces << abort(FatalError);
+//    }
+//
+//    // Keep point on most perpendicular face; shift it away from the aligned
+//    // ones.
+//    // E.g. line hits top and left face:
+//    //     a
+//    // ----+----+
+//    //     |    |
+//    //     |    |
+//    //     +----+
+//    // Shift point down (away from top):
+//    //     
+//    //    a+----+
+//    // ----|    |
+//    //     |    |
+//    //     +----+
+//
+//    label maxIndex = -1;
+//    scalar maxInproduct = -GREAT;
+//
+//    for (direction i = 0; i < 6; i++)
+//    {
+//        if (inproducts[i] > maxInproduct)
+//        {
+//            maxInproduct = inproducts[i];
+//            maxIndex = i;
+//        }
+//    }
+//
+//    if (maxIndex == -1)
+//    {
+//        FatalErrorIn("indexedOctree<Type>::checkMultipleFaces(..)")
+//            << "Problem maxIndex:" << maxIndex << " inproducts:" << inproducts
+//            << abort(FatalError);
+//    }
+//
+//    const point oldPoint(faceHitInfo.rawPoint());
+//    const direction oldFaceID = faceID;
+//
+//    // 1. Push point into bb, away from all corners
+//
+//    faceHitInfo.rawPoint() = pushPoint(bb, oldFaceID, oldPoint, true);
+//
+//    // 2. Snap it back onto the preferred face
+//
+//    if (maxIndex == treeBoundBox::LEFT)
+//    {
+//        faceHitInfo.rawPoint().x() = bb.min().x();
+//        faceID = treeBoundBox::LEFTBIT;
+//    }
+//    else if (maxIndex == treeBoundBox::RIGHT)
+//    {
+//        faceHitInfo.rawPoint().x() = bb.max().x();
+//        faceID = treeBoundBox::RIGHTBIT;
+//    }
+//    else if (maxIndex == treeBoundBox::BOTTOM)
+//    {
+//        faceHitInfo.rawPoint().y() = bb.min().y();
+//        faceID = treeBoundBox::BOTTOMBIT;
+//    }
+//    else if (maxIndex == treeBoundBox::TOP)
+//    {
+//        faceHitInfo.rawPoint().y() = bb.max().y();
+//        faceID = treeBoundBox::TOPBIT;
+//    }
+//    else if (maxIndex == treeBoundBox::BACK)
+//    {
+//        faceHitInfo.rawPoint().z() = bb.min().z();
+//        faceID = treeBoundBox::BACKBIT;
+//    }
+//    else if (maxIndex == treeBoundBox::FRONT)
+//    {
+//        faceHitInfo.rawPoint().z() = bb.max().z();
+//        faceID = treeBoundBox::FRONTBIT;
+//    }
+//
+//    Pout<< "From ray:" << dir
+//        << " from point:" << oldPoint
+//        << " on faces:" << faceString(oldFaceID)
+//        << " of bb:" << bb
+//        << " with inprods:" << inproducts
+//        << " maxIndex:" << maxIndex << endl
+//        << "perturbed to point:" << faceHitInfo.rawPoint()
+//        << " on face:" << faceString(faceID)
+//        << endl;
+//
+//
+//    if (debug)
+//    {
+//        if (faceID != bb.faceBits(faceHitInfo.rawPoint()))
+//        {
+//            FatalErrorIn("indexedOctree<Type>::checkMultipleFaces(..)")
+//                << "Pushed point from " << oldPoint
+//                << " on face:" << oldFaceID << " of bb:" << bb << endl
+//                << "onto " << faceHitInfo.rawPoint()
+//                << " on face:" << faceID
+//                << " which is not consistent with geometric face "
+//                <<  bb.faceBits(faceHitInfo.rawPoint())
+//                << abort(FatalError);
+//        }
+//    }
+//}
+
+
+// Get parent node and octant. Return false if top of tree reached.
+template <class Type>
+bool Foam::indexedOctree<Type>::walkToParent
+(
+    const label nodeI,
+    const direction octant,
+
+    label& parentNodeI,
+    label& parentOctant
+) const
+{
+    parentNodeI = nodes_[nodeI].parent_;
+
+    if (parentNodeI == -1)
+    {
+        // Reached edge of tree
+        return false;
+    }
+
+    const node& parentNode = nodes_[parentNodeI];
+
+    // Find octant nodeI is in.
+    parentOctant = 255;
+
+    for (direction i = 0; i < parentNode.subNodes_.size(); i++)
+    {
+        labelBits index = parentNode.subNodes_[i];
+
+        if (isNode(index) && getNode(index) == nodeI)
+        {
+            parentOctant = i;
+            break;
+        }
+    }
+
+    if (parentOctant == 255)
+    {
+        FatalErrorIn("walkToParent(..)")
+            << "Problem: no parent found for octant:" << octant
+            << " node:" << nodeI
+            << abort(FatalError);
+    }
+
+    return true;
+}
+
+
 // Walk tree to neighbouring node. Gets current position as
 // node and octant in this node and walks in the direction given by
-// the faceID (one of treeBoundBox::LEFTBIT, RIGHTBIT etc.)
+// the facePointBits (combination of treeBoundBox::LEFTBIT, TOPBIT etc.)
 // Returns false if edge of tree hit.
 template <class Type>
 bool Foam::indexedOctree<Type>::walkToNeighbour
 (
     const point& facePoint,
-    const direction faceID,         // direction to walk in
+    const direction faceID,  // face(s) that facePoint is on
     label& nodeI,
     direction& octant
 ) const
 {
+    label oldNodeI = nodeI;
+    direction oldOctant = octant;
+
     // Find out how to test for octant. Say if we want to go left we need
     // to traverse up the tree until we hit a node where our octant is
     // on the right.
 
+    // Coordinate direction to test
+    const direction X = treeBoundBox::RIGHTHALF;
+    const direction Y = treeBoundBox::TOPHALF;
+    const direction Z = treeBoundBox::FRONTHALF;
+
     direction octantMask = 0;
-    direction valueMask = 0;
+    direction wantedValue = 0;
 
     if ((faceID & treeBoundBox::LEFTBIT) != 0)
     {
-        // We want to go left so check if in right octant.
-        octantMask |= treeBoundBox::RIGHTHALF;
-        valueMask |= treeBoundBox::RIGHTHALF;
+        // We want to go left so check if in right octant (i.e. x-bit is set)
+        octantMask |= X;
+        wantedValue |= X;
     }
     else if ((faceID & treeBoundBox::RIGHTBIT) != 0)
     {
-        octantMask |= treeBoundBox::RIGHTHALF;  // valueMask already 0
+        octantMask |= X;  // wantedValue already 0
     }
 
     if ((faceID & treeBoundBox::BOTTOMBIT) != 0)
     {
-        octantMask |= treeBoundBox::TOPHALF;
-        valueMask |= treeBoundBox::TOPHALF;
+        // Want to go down so check for y-bit set.
+        octantMask |= Y;
+        wantedValue |= Y;
     }
     else if ((faceID & treeBoundBox::TOPBIT) != 0)
     {
-        octantMask |= treeBoundBox::TOPHALF;
+        // Want to go up so check for y-bit not set.
+        octantMask |= Y;
     }
 
     if ((faceID & treeBoundBox::BACKBIT) != 0)
     {
-        octantMask |= treeBoundBox::FRONTHALF;
-        valueMask |= treeBoundBox::FRONTHALF;
+        octantMask |= Z;
+        wantedValue |= Z;
     }
     else if ((faceID & treeBoundBox::FRONTBIT) != 0)
     {
-        octantMask |= treeBoundBox::FRONTHALF;
+        octantMask |= Z;
     }
 
+    // So now we have the coordinate directions in the octant we need to check
+    // and the resulting value.
+
+    /*
+    // +---+---+
+    // |   |   |
+    // |   |   |
+    // |   |   |
+    // +---+-+-+
+    // |   | | |
+    // |  a+-+-+
+    // |   |\| |
+    // +---+-+-+
+    //        \ 
+    //
+    // e.g. ray is at (a) in octant 0(or 4) with faceIDs : LEFTBIT+TOPBIT.
+    // If we would be in octant 1(or 5) we could go to the correct octant
+    // in the same node by just flipping the x and y bits (exoring).
+    // But if we are not in octant 1/5 we have to go up until we are.
+    // In general for leftbit+topbit:
+    // - we have to check for x and y : octantMask  = 011
+    // - the checked bits have to be  : wantedValue = ?01
+    */
+
+    //Pout<< "For point " << facePoint << endl;
+
     // Go up until we have chance to cross to the wanted direction
-    while (valueMask != (octant & octantMask))
+    while (wantedValue != (octant & octantMask))
     {
-        label parentNodeI = nodes_[nodeI].parent_;
+        // Go up to the parent.
 
-        if (parentNodeI == -1)
+        // Remove the directions that are not on the boundary of the parent.
+        // See diagram above
+        if (wantedValue & X)    // && octantMask&X
         {
-            // Reached edge of tree
-            return false;
+            // Looking for right octant.
+            if (octant & X)
+            {
+                // My octant is one of the left ones so punch out the x check
+                octantMask &= ~X;
+                wantedValue &= ~X;
+            }
+        }
+        else
+        {
+            if (!(octant & X))
+            {
+                // My octant is right but I want to go left.
+                octantMask &= ~X;
+                wantedValue &= ~X;
+            }
         }
 
-        const node& parentNode = nodes_[parentNodeI];
-
-        // Find octant nodeI is in.
-        direction parentOctant = 255;
-
-        for (direction i = 0; i < parentNode.subNodes_.size(); i++)
+        if (wantedValue & Y)
         {
-            labelBits index = parentNode.subNodes_[i];
+            if (octant & Y)
+            {
+                octantMask &= ~Y;
+                wantedValue &= ~Y;
+            }
+        }
+        else
+        {
+            if (!(octant & Y))
+            {
+                octantMask &= ~Y;
+                wantedValue &= ~Y;
+            }
+        }
 
-            if (isNode(index) && getNode(index) == nodeI)
+        if (wantedValue & Z)
+        {
+            if (octant & Z)
+            {
+                octantMask &= ~Z;
+                wantedValue &= ~Z;
+            }
+        }
+        else
+        {
+            if (!(octant & Z))
             {
-                parentOctant = i;
-                break;
+                octantMask &= ~Z;
+                wantedValue &= ~Z;
             }
         }
 
-        if (parentOctant == 255)
+
+        label parentNodeI;
+        label parentOctant;
+        walkToParent(nodeI, octant, parentNodeI, parentOctant);
+
+        if (parentNodeI == -1)
         {
-            FatalErrorIn("walkToNeighbour")
-                << abort(FatalError);
+            // Reached edge of tree
+            return false;
         }
+
+        //Pout<< "    walked from node:" << nodeI << " octant:" << octant
+        //    << " bb:" << nodes_[nodeI].bb_.subBbox(octant) << endl
+        //    << "    to:" << parentNodeI << " octant:" << parentOctant
+        //    << " bb:" << nodes_[parentNodeI].bb_.subBbox(parentOctant)
+        //    << endl;
+        //
+        //Pout<< "    octantMask:" << octantMask
+        //    << " wantedValue:" << wantedValue << endl;
+
         nodeI = parentNodeI;
         octant = parentOctant;
     }
 
-    // So now we hit the correct parent node. Switch to the correct octant
+    // So now we hit the correct parent node. Switch to the correct octant.
+    // Is done by jumping to the 'other half' so if e.g. in x direction in
+    // right half we now jump to the left half.
     octant ^= octantMask;
 
+    //Pout<< "    to node:" << nodeI << " octant:" << octant
+    //    << " subBb:" <<subBbox(nodeI, octant) << endl;
+
+
+    if (debug)
+    {
+        const treeBoundBox subBb(subBbox(nodeI, octant));
+
+        if (!subBb.contains(facePoint))
+        {
+            FatalErrorIn("indexedOctree<Type>::walkToNeighbour(..)")
+                << "When searching for " << facePoint
+                << " ended up in node:" << nodeI
+                << " octant:" << octant
+                << " with bb:" << subBb
+                << abort(FatalError);
+        }
+    }
+
+
     // See if we need to travel down. Note that we already go into the
-    // the first level ourselves (instead of having findNode decide) since
-    // the facePoint is now exactly on the mid of the node so there could
-    // be truncation problems.
+    // the first level ourselves (instead of having findNode decide)
     labelBits index = nodes_[nodeI].subNodes_[octant];
 
     if (isNode(index))
@@ -778,49 +1499,82 @@ bool Foam::indexedOctree<Type>::walkToNeighbour
         octant = getOctant(node);
     }
 
+
+    if (debug)
+    {
+        const treeBoundBox subBb(subBbox(nodeI, octant));
+
+        if (nodeI == oldNodeI && octant == oldOctant)
+        {
+            FatalErrorIn("indexedOctree<Type>::walkToNeighbour(..)")
+                << "Did not go to neighbour when searching for " << facePoint
+                << endl
+                << "    starting from face:" << faceString(faceID)
+                << " node:" << nodeI
+                << " octant:" << octant
+                << " bb:" << subBb
+                << abort(FatalError);
+        }
+
+        if (!subBb.contains(facePoint))
+        {
+            FatalErrorIn("indexedOctree<Type>::walkToNeighbour(..)")
+                << "When searching for " << facePoint
+                << " ended up in node:" << nodeI
+                << " octant:" << octant
+                << " bb:" << subBb
+                << abort(FatalError);
+        }
+    }
+
+
     return true;
 }
 
 
-// Return unique number for the face of a bounding box a point is on.
-// (number is single bit but not really nessecary)
-// Return 0 if point not on any face of bb.
 template <class Type>
-Foam::direction Foam::indexedOctree<Type>::getFace
+Foam::word Foam::indexedOctree<Type>::faceString
 (
-    const treeBoundBox& bb,
-    const point& pt
+    const direction faceID
 )
 {
-    direction faceID = 0;
+    word desc;
 
-    if (pt.x() <= bb.min().x())
+    if (faceID == 0)
     {
-        faceID |= treeBoundBox::LEFTBIT;
+        desc = "noFace";
     }
-    if (pt.x() >= bb.max().x())
+    if (faceID & treeBoundBox::LEFTBIT)
     {
-        faceID |= treeBoundBox::RIGHTBIT;
+        if (!desc.empty()) desc += "+";
+        desc += "left";
     }
-
-    if (pt.y() <= bb.min().y())
+    if (faceID & treeBoundBox::RIGHTBIT)
     {
-        faceID |= treeBoundBox::BOTTOMBIT;
+        if (!desc.empty()) desc += "+";
+        desc += "right";
     }
-    if (pt.y() >= bb.max().y())
+    if (faceID & treeBoundBox::BOTTOMBIT)
     {
-        faceID |= treeBoundBox::TOPBIT;
+        if (!desc.empty()) desc += "+";
+        desc += "bottom";
     }
-
-    if (pt.z() <= bb.min().z())
+    if (faceID & treeBoundBox::TOPBIT)
     {
-        faceID |= treeBoundBox::BACKBIT;
+        if (!desc.empty()) desc += "+";
+        desc += "top";
     }
-    if (pt.z() >= bb.max().z())
+    if (faceID & treeBoundBox::BACKBIT)
     {
-        faceID |= treeBoundBox::FRONTBIT;
+        if (!desc.empty()) desc += "+";
+        desc += "back";
     }
-    return faceID;
+    if (faceID & treeBoundBox::FRONTBIT)
+    {
+        if (!desc.empty()) desc += "+";
+        desc += "front";
+    }
+    return desc;
 }
 
 
@@ -829,21 +1583,37 @@ Foam::direction Foam::indexedOctree<Type>::getFace
 //  hitInfo.point = point on shape
 // Else return a miss and the bounding box face hit:
 //  hitInfo.point = coordinate of intersection of ray with bounding box
-//  faceID  = index of bounding box face
+//  hitBits  = posbits of point on bounding box
 template <class Type>
 void Foam::indexedOctree<Type>::traverseNode
 (
     const bool findAny,
+    const point& treeStart,
+    const vector& treeVec,
+
     const point& start,
     const point& end,
-    const vector& dir,
     const label nodeI,
     const direction octant,
 
     pointIndexHit& hitInfo,
-    direction& faceID
+    direction& hitBits
 ) const
 {
+    if (debug)
+    {
+        const treeBoundBox octantBb(subBbox(nodeI, octant));
+
+        if (octantBb.posBits(start) != 0)
+        {
+            FatalErrorIn("indexedOctree<Type>::traverseNode(..)")
+                << "Node:" << nodeI << " octant:" << octant
+                << " bb:" << octantBb << endl
+                << "does not contain point " << start << abort(FatalError);
+        }
+    }
+
+
     const node& nod = nodes_[nodeI];
 
     labelBits index = nod.subNodes_[octant];
@@ -909,49 +1679,72 @@ void Foam::indexedOctree<Type>::traverseNode
     // Nothing intersected in this node
     // Traverse to end of node. Do by ray tracing back from end and finding
     // intersection with bounding box of node.
+    // start point is now considered to be inside bounding box.
+
+    const treeBoundBox octantBb(subBbox(nodeI, octant));
 
     point pt;
+    bool intersected = octantBb.intersects
+    (
+        end,            //treeStart,
+        (start-end),    //treeVec,
 
-    if (isNode(index))
-    {
-        const treeBoundBox& subBb = nodes_[getNode(index)].bb_;
+        end,
+        start,
 
-        if (!subBb.intersects(end, start, pt))
-        {
-            faceID = 0;
+        pt,
+        hitBits
+    );
 
-            FatalErrorIn("indexedOctree<Type>::traverseNode(..)")
-                << "Did not hit side of box " << subBb
-                << " with ray from " << start << " to " << end
-                << abort(FatalError);
-        }
-        else
-        {
-            faceID = getFace(subBb, pt);
-        }
+
+    if (intersected)
+    {
+        // Return miss. Set misspoint to face.
+        hitInfo.setPoint(pt);
     }
     else
     {
-        const treeBoundBox subBb(nod.bb_.subBbox(octant));
+        // Rare case: did not find intersection of ray with octantBb. Can
+        // happen if end is on face/edge of octantBb. Do like
+        // lagrangian and re-track with perturbed vector (slightly pushed out
+        // of bounding box)
 
-        if (!subBb.intersects(end, start, pt))
-        {
-            faceID = 0;
+        point perturbedEnd(pushPoint(octantBb, end, false));
 
-            FatalErrorIn("indexedOctree<Type>::traverseNode(..)")
-                << "Did not hit side of box " << subBb
-                << " with ray from " << start << " to " << end
-                << abort(FatalError);
-        }
-        else
+
+        //if (debug)
         {
-            faceID = getFace(subBb, pt);
+            // Dump octantBb to obj
+            writeOBJ(nodeI, octant);
+            // Dump ray to obj as well
+            {
+                OFstream str("ray.obj");
+                meshTools::writeOBJ(str, start);
+                meshTools::writeOBJ(str, end);
+                str << "l 1 2" << nl;
+            }
+            WarningIn("indexedOctree<Type>::traverseNode(..)")
+                << "Did not intersect ray from endpoint:" << end
+                << " to startpoint:" << start
+                << " with bounding box:" << octantBb << nl
+                << "Re-intersecting with perturbed endpoint:" << perturbedEnd
+                << endl;
         }
-    }
 
+        traverseNode
+        (
+            findAny,
+            treeStart,
+            treeVec,
+            start,
+            perturbedEnd,
+            nodeI,
+            octant,
 
-    // Return miss. Set misspoint to face.
-    hitInfo.setPoint(pt);
+            hitInfo,
+            hitBits
+        );
+    }
 }
 
 
@@ -963,40 +1756,75 @@ Foam::pointIndexHit Foam::indexedOctree<Type>::findLine
     const point& treeStart,
     const point& treeEnd,
     const label startNodeI,
-    const direction startOctant
+    const direction startOctant,
+    const bool verbose
 ) const
 {
-    const vector dir(treeEnd - treeStart);
+    const vector treeVec(treeEnd - treeStart);
 
     // Current node as parent+octant
     label nodeI = startNodeI;
     direction octant = startOctant;
 
+    if (verbose)
+    {
+        Pout<< "findLine : treeStart:" << treeStart
+            << " treeEnd:" << treeEnd << endl
+            << "node:" << nodeI
+            << " octant:" << octant
+            << " bb:" << subBbox(nodeI, octant) << endl;
+    }
+
     // Current position. Initialize to miss
     pointIndexHit hitInfo(false, treeStart, -1);
 
-    // Side of current bounding box current point is on
-    direction faceID = 0;
-
-    while (true)
+    //while (true)
+    label i = 0;
+    for (; i < 100000; i++)
     {
+        if (verbose)
+        {
+            Pout<< "iter:" << i
+                << " at startPoint:" << hitInfo.rawPoint() << endl
+                << "    node:" << nodeI
+                << " octant:" << octant
+                << " bb:" << subBbox(nodeI, octant) << endl;
+        }
+
+
         // Ray-trace to end of current node. Updates point (either on triangle
         // in case of hit or on node bounding box in case of miss)
 
-        point startPoint(hitInfo.rawPoint());
+        const treeBoundBox octantBb(subBbox(nodeI, octant));
+
+        // Make sure point is away from any edges/corners
+        point startPoint
+        (
+            pushPointIntoFace
+            (
+                octantBb,
+                treeVec,
+                hitInfo.rawPoint()
+            )
+        );
+
+        // Faces of current bounding box current point is on
+        direction hitFaceID = 0;
 
         traverseNode
         (
             findAny,
+            treeStart,
+            treeVec,
+
             startPoint,     // Note: pass in copy since hitInfo
                             // also used in return value.
-            treeEnd,
-            dir,
+            treeEnd,        // pass in overall end so is nicely outside bb
             nodeI,
             octant,
 
             hitInfo,
-            faceID
+            hitFaceID
         );
 
         // Did we hit a triangle?
@@ -1005,29 +1833,48 @@ Foam::pointIndexHit Foam::indexedOctree<Type>::findLine
             break;
         }
 
-        if (faceID == 0)
+        if (hitFaceID == 0)
         {
-            // Was never inside the tree. Return miss.
+            // endpoint inside the tree. Return miss.
             break;
         }
 
-        //Pout<< "findLine : treeStart:" << treeStart
-        //    << " treeEnd:" << treeEnd
-        //    << " tracked from " << startPoint << " to edge of nodeBb:"
-        //    << hitInfo.missPoint()
-        //    << " node:" << nodeI << " octant:" << octant
-        //    << " subBb:"
-        //    << nodes_[nodeI].bb_.subBbox(octant)
-        //    << endl;
+
+        if (verbose)
+        {
+            Pout<< "    iter:" << i
+                << " hit face:" << faceString(hitFaceID)
+                << " at:" << hitInfo.rawPoint() << nl
+                << "    node:" << nodeI
+                << " octant:" << octant
+                << " bb:" << subBbox(nodeI, octant) << nl
+                << "    walking to neighbour containing:"
+                <<  pushPoint
+                    (
+                        octantBb,
+                        hitFaceID,
+                        hitInfo.rawPoint(),
+                        false                   // push outside of octantBb
+                    )
+                << endl;
+        }
 
 
         // Nothing hit so we are on face of bounding box (given as node+octant+
-        // faceID). Traverse to neighbouring node.
+        // position bits). Traverse to neighbouring node. Use slightly perturbed
+        // point.
 
         bool ok = walkToNeighbour
         (
-            hitInfo.rawPoint(), // point on face
-            faceID,             // direction to walk in
+            pushPoint
+            (
+                octantBb,
+                hitFaceID,
+                hitInfo.rawPoint(),
+                false                   // push outside of octantBb
+            ),
+            hitFaceID,  // face(s) that hitInfo is on
+
             nodeI,
             octant
         );
@@ -1037,7 +1884,53 @@ Foam::pointIndexHit Foam::indexedOctree<Type>::findLine
             // Hit the edge of the tree. Return miss.
             break;
         }
+
+        if (verbose)
+        {
+            const treeBoundBox octantBb(subBbox(nodeI, octant));
+            Pout<< "    walked for point:" << hitInfo.rawPoint() << endl
+                << "    to neighbour node:" << nodeI
+                << " octant:" << octant
+                << " face:" << faceString(octantBb.faceBits(hitInfo.rawPoint()))
+                << " of octantBb:" << octantBb << endl
+                << endl;
+        }
+    }
+
+    if (i == 100000)
+    {
+        // Probably in loop.
+        if (!verbose)
+        {
+            // Redo intersection but now with verbose flag switched on.
+            return findLine
+            (
+                findAny,
+                treeStart,
+                treeEnd,
+                startNodeI,
+                startOctant,
+                true            //verbose
+            );
+        }
+        if (debug)
+        {
+            FatalErrorIn("indexedOctree<Type>::findLine(..)")
+                << "Got stuck in loop raytracing from:" << treeStart
+                << " to:" << treeEnd << endl
+                << "inside top box:" << subBbox(startNodeI, startOctant)
+                << abort(FatalError);
+        }
+        else
+        {
+            WarningIn("indexedOctree<Type>::findLine(..)")
+                << "Got stuck in loop raytracing from:" << treeStart
+                << " to:" << treeEnd << endl
+                << "inside top box:" << subBbox(startNodeI, startOctant)
+                << endl;
+        }
     }
+
     return hitInfo;
 }
 
@@ -1057,6 +1950,9 @@ Foam::pointIndexHit Foam::indexedOctree<Type>::findLine
     {
         const treeBoundBox& treeBb = nodes_[0].bb_;
 
+        // No effort is made to deal with points which are on edge of tree
+        // bounding box for now.
+
         direction startBit = treeBb.posBits(start);
         direction endBit = treeBb.posBits(end);
 
@@ -1066,6 +1962,9 @@ Foam::pointIndexHit Foam::indexedOctree<Type>::findLine
             return pointIndexHit(false, vector::zero, -1);
         }
 
+
+        // Trim segment to treeBb
+
         point trackStart(start);
         point trackEnd(end);
 
@@ -1087,6 +1986,7 @@ Foam::pointIndexHit Foam::indexedOctree<Type>::findLine
             }
         }
 
+
         // Find lowest level tree node that start is in.
         labelBits index = findNode(0, trackStart);
 
@@ -1234,32 +2134,6 @@ void Foam::indexedOctree<Type>::writeOBJ
 
         str<< "l " << e[0]+pointVertI+1 << ' ' << e[1]+pointVertI+1 << nl;
     }
-
-
-    //// Dump triangles
-    //if (isContent(index))
-    //{
-    //    const labelList& indices = contents_[getContent(index)];
-    //    const triSurface& surf = shapes_.surface();
-    //    const pointField& points = surf.points();
-    //
-    //    forAll(indices, i)
-    //    {
-    //        label shapeI = indices[i];
-    //
-    //        const labelledTri& f = surf[shapeI];
-    //
-    //        meshTools::writeOBJ(str, points[f[0]]);
-    //        vertI++;
-    //        meshTools::writeOBJ(str, points[f[1]]);
-    //        vertI++;
-    //        meshTools::writeOBJ(str, points[f[2]]);
-    //        vertI++;
-    //
-    //        str<< "l " << vertI-2 << ' ' << vertI-1 << ' ' << vertI << ' '
-    //            << vertI-2 << nl;
-    //    }
-    //}
 }
 
 
@@ -1305,6 +2179,14 @@ Foam::indexedOctree<Type>::indexedOctree
     contents_(0),
     nodeTypes_(0)
 {
+    if (debug)
+    {
+        Pout<< "indexedOctree<Type>::indexedOctree:" << nl
+            << "    shapes:" << shapes.size() << nl
+            << "    bb:" << bb << nl
+            << endl;
+    }
+
     if (shapes.size() == 0)
     {
         return;
@@ -1409,7 +2291,6 @@ Foam::indexedOctree<Type>::indexedOctree
     nodes_.transfer(nodes);
     nodes.clear();
 
-
     if (debug)
     {
         label nEntries = 0;
@@ -1418,14 +2299,18 @@ Foam::indexedOctree<Type>::indexedOctree
             nEntries += contents_[i].size();
         }
 
-        Pout<< "indexedOctree<Type>::indexedOctree : finished construction:"
+        Pout<< "indexedOctree<Type>::indexedOctree"
+            << " : finished construction of tree of:" << shapes.typeName
             << nl
+            << "    bb:" << this->bb() << nl
             << "    shapes:" << shapes.size() << nl
             << "    nLevels:" << nLevels << nl
             << "    treeNodes:" << nodes_.size() << nl
             << "    nEntries:" << nEntries << nl
-            << "        per treeLeaf:" << nEntries/contents.size() << nl
-            << "        per shape (duplicity):" << nEntries/shapes.size() << nl
+            << "        per treeLeaf:"
+            << scalar(nEntries)/contents.size() << nl
+            << "        per shape (duplicity):"
+            << scalar(nEntries)/shapes.size() << nl
             << endl;
     }
 }
@@ -1447,6 +2332,13 @@ Foam::indexedOctree<Type>::indexedOctree
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
+template <class Type>
+Foam::scalar& Foam::indexedOctree<Type>::perturbTol()
+{
+    return perturbTol_;
+}
+
+
 template <class Type>
 Foam::pointIndexHit Foam::indexedOctree<Type>::findNearest
 (
@@ -1570,6 +2462,16 @@ Foam::labelBits Foam::indexedOctree<Type>::findNode
 
     const node& nod = nodes_[nodeI];
 
+    if (debug)
+    {
+        if (!nod.bb_.contains(sample))
+        {
+            FatalErrorIn("findNode(..)")
+                << "Cannot find " << sample << " in node " << nodeI
+                << abort(FatalError);
+        }
+    }
+
     direction octant = nod.bb_.subOctant(sample);
 
     labelBits index = nod.subNodes_[octant];
diff --git a/src/meshTools/indexedOctree/indexedOctree.H b/src/meshTools/indexedOctree/indexedOctree.H
index b4aad9a3052f520a6ffd599a921f31645f32e933..6c2bfa3c6e6f1408f6b80dfa6375ab60ba511522 100644
--- a/src/meshTools/indexedOctree/indexedOctree.H
+++ b/src/meshTools/indexedOctree/indexedOctree.H
@@ -128,6 +128,15 @@ public:
 
 private:
 
+    // Static data
+
+        //- Relative peturbation tolerance. Determines when point is
+        //  considered to be close to face/edge of bb of node.
+        //  The tolerance is relative to the bounding box of the smallest
+        //  node.
+        static scalar perturbTol_;
+
+
     // Private data
 
         //- Underlying shapes for geometric queries.
@@ -144,8 +153,9 @@ private:
 
     // Private Member Functions
 
-        //- Like above but now bb is implicitly provided as parent bb + mid
-        //  + octant
+        //- Helper: does bb intersect a sphere around sample? Or is any
+        //  corner point of bb closer than nearestDistSqr to sample.
+        //  (bb is implicitly provided as parent bb + octant)
         static bool overlaps
         (
             const treeBoundBox& parentBb,
@@ -215,6 +225,60 @@ private:
                 point& nearestPoint
             ) const;
 
+            //- Return bbox of octant
+            treeBoundBox subBbox
+            (
+                const label parentNodeI,
+                const direction octant
+            ) const;
+
+            //- Helper: take a point on/close to face of bb and push it
+            //  inside or outside of bb.
+            static point pushPoint
+            (
+                const treeBoundBox&,
+                const point&,
+                const bool pushInside
+            );
+
+            //- Helper: take a point on face of bb and push it
+            //  inside or outside of bb.
+            static point pushPoint
+            (
+                const treeBoundBox&,
+                const direction,
+                const point&,
+                const bool pushInside
+            );
+
+            //- Helper: take point on face(s) of bb and push it away from
+            //  edges of face.
+            static point pushPointIntoFace
+            (
+                const treeBoundBox& bb,
+                const vector& dir,          // end-start
+                const point& pt
+            );
+
+            ////- Push point on multiple faces away from any corner/edge.
+            //static void checkMultipleFaces
+            //(
+            //    const treeBoundBox& bb,
+            //    const vector& dir,          // end-start
+            //    pointIndexHit& faceHitInfo,
+            //    direction& faceID
+            //);
+
+            //- Walk to parent of node+octant.
+            bool walkToParent
+            (
+                const label nodeI,
+                const direction octant,
+
+                label& parentNodeI,
+                label& parentOctant
+            ) const;
+
             //- Walk tree to neighbouring node. Return false if edge of tree
             //  hit.
             bool walkToNeighbour
@@ -225,8 +289,8 @@ private:
                 direction& octant
             ) const;
 
-            //- Categorize point on bounding box.
-            static direction getFace(const treeBoundBox&, const point&);
+            //- Debug: return verbose the bounding box faces
+            static word faceString(const direction faceID);
 
             //- Traverse a node. If intersects a triangle return first
             // intersection point.
@@ -235,9 +299,11 @@ private:
             void traverseNode
             (
                 const bool findAny,
+                const point& treeStart,
+                const vector& treeVec,
+
                 const point& start,
                 const point& end,
-                const vector& dir,
                 const label nodeI,
                 const direction octantI,
 
@@ -252,7 +318,8 @@ private:
                 const point& treeStart,
                 const point& treeEnd,
                 const label startNodeI,
-                const direction startOctantI
+                const direction startOctantI,
+                const bool verbose = false
             ) const;
 
             //- Find any or nearest intersection of line between start and end.
@@ -310,6 +377,10 @@ private:
 
 public:
 
+        //- Get the perturbation tolerance
+        static scalar& perturbTol();
+
+
     // Constructors
 
         //- Construct null
@@ -505,6 +576,7 @@ public:
                 const point& sample
             );
 
+
         // Write
 
             //- Print tree. Either print all indices (printContent = true) or
diff --git a/src/meshTools/indexedOctree/treeDataCell.H b/src/meshTools/indexedOctree/treeDataCell.H
index 4f09188942e52ed86bdeccdbc7e8365013b4e0f9..100dcb62cf7659a852daf95532ec31f0e3bfde4a 100644
--- a/src/meshTools/indexedOctree/treeDataCell.H
+++ b/src/meshTools/indexedOctree/treeDataCell.H
@@ -37,9 +37,7 @@ SourceFiles
 #ifndef treeDataCell_H
 #define treeDataCell_H
 
-#include "treeBoundBox.H"
 #include "treeBoundBoxList.H"
-#include "labelList.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
diff --git a/src/meshTools/indexedOctree/treeDataEdge.C b/src/meshTools/indexedOctree/treeDataEdge.C
index c4bb08f3744ac1f6360660ca037c4a0041debfd8..12f347c16483afff5664c6295b9211123f6c69f2 100644
--- a/src/meshTools/indexedOctree/treeDataEdge.C
+++ b/src/meshTools/indexedOctree/treeDataEdge.C
@@ -22,16 +22,15 @@ License
     along with OpenFOAM; if not, write to the Free Software Foundation,
     Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 
-Description
-
 \*---------------------------------------------------------------------------*/
 
 #include "treeDataEdge.H"
 #include "indexedOctree.H"
-#include "polyMesh.H"
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
+defineTypeNameAndDebug(Foam::treeDataEdge, 0);
+
 
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
diff --git a/src/meshTools/indexedOctree/treeDataEdge.H b/src/meshTools/indexedOctree/treeDataEdge.H
index 916bad870ec358ff4e2b6ff8ab13eab2bb6fb736..5dad366b3b624121c54dad883bc4c4259ef1ddb0 100644
--- a/src/meshTools/indexedOctree/treeDataEdge.H
+++ b/src/meshTools/indexedOctree/treeDataEdge.H
@@ -36,8 +36,6 @@ SourceFiles
 #ifndef treeDataEdge_H
 #define treeDataEdge_H
 
-#include "treeBoundBox.H"
-#include "pointField.H"
 #include "treeBoundBoxList.H"
 #include "linePointRef.H"
 
diff --git a/src/meshTools/indexedOctree/treeDataPoint.C b/src/meshTools/indexedOctree/treeDataPoint.C
index c64fc04ee584282fa9e74747a6f3700d4a1e5eb8..5303156518e93277e21f8b110de84f78456b9dc4 100644
--- a/src/meshTools/indexedOctree/treeDataPoint.C
+++ b/src/meshTools/indexedOctree/treeDataPoint.C
@@ -32,6 +32,11 @@ Description
 #include "polyMesh.H"
 #include "triangleFuncs.H"
 
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+defineTypeNameAndDebug(Foam::treeDataPoint, 0);
+
+
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
 // Construct from components
diff --git a/src/meshTools/indexedOctree/treeDataTriSurface.C b/src/meshTools/indexedOctree/treeDataTriSurface.C
index 06a496ee881c9f71db430c8bd01fbd59416f28f7..ea519291e3a275351622082b35d45413ddab825d 100644
--- a/src/meshTools/indexedOctree/treeDataTriSurface.C
+++ b/src/meshTools/indexedOctree/treeDataTriSurface.C
@@ -22,8 +22,6 @@ License
     along with OpenFOAM; if not, write to the Free Software Foundation,
     Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 
-Description
-
 \*---------------------------------------------------------------------------*/
 
 #include "treeDataTriSurface.H"
@@ -226,7 +224,7 @@ Foam::label Foam::treeDataTriSurface::getVolumeType
 
     if (!pHit.hit())
     {
-        FatalErrorIn("treeDataTriSurface::getVolumeType")
+        FatalErrorIn("treeDataTriSurface::getVolumeType(..)")
             << "treeBb:" << treeBb
             << " sample:" << sample
             << " pHit:" << pHit
@@ -238,7 +236,8 @@ Foam::label Foam::treeDataTriSurface::getVolumeType
         surface_,
         sample,
         pHit.index(),
-        pHit.hitPoint()
+        pHit.hitPoint(),
+        indexedOctree<treeDataTriSurface>::perturbTol()
     );
 
     if (t == triSurfaceTools::UNKNOWN)
@@ -255,12 +254,13 @@ Foam::label Foam::treeDataTriSurface::getVolumeType
     }
     else
     {
-        FatalErrorIn("treeDataTriSurface::getVolumeType")
+        FatalErrorIn("treeDataTriSurface::getVolumeType(..)")
             << "problem" << abort(FatalError);
         return indexedOctree<treeDataTriSurface>::UNKNOWN;
     }
 }
 
+
 // Check if any point on triangle is inside cubeBb.
 bool Foam::treeDataTriSurface::overlaps
 (
@@ -305,6 +305,7 @@ bool Foam::treeDataTriSurface::overlaps
     // Now we have the difficult case: all points are outside but connecting
     // edges might go through cube. Use fast intersection of bounding box.
 
+    //return triangleFuncs::intersectBbExact(p0, p1, p2, cubeBb);
     return triangleFuncs::intersectBb(p0, p1, p2, cubeBb);
 }
 
@@ -445,7 +446,15 @@ bool Foam::treeDataTriSurface::intersects
 
     const vector dir(end - start);
 
-    pointHit inter = tri.intersection(start, dir, intersection::HALF_RAY);
+    // Use relative tolerance (from octree) to determine intersection.
+
+    pointHit inter = tri.intersection
+    (
+        start,
+        dir,
+        intersection::HALF_RAY,
+        indexedOctree<treeDataTriSurface>::perturbTol()
+    );
 
     if (inter.hit() && inter.distance() <= 1)
     {
@@ -459,6 +468,16 @@ bool Foam::treeDataTriSurface::intersects
     {
         return false;
     }
+
+
+    //- Using exact intersections
+    //pointHit info = f.tri(points).intersectionExact(start, end);
+    //
+    //if (info.hit())
+    //{
+    //    intersectionPoint = info.hitPoint();
+    //}
+    //return info.hit();
 }
 
 
diff --git a/src/meshTools/meshSearch/meshSearch.C b/src/meshTools/meshSearch/meshSearch.C
index ef1aa46f67430fc9cbb4b2870c334f51130ca556..2c803a277251bf72faff28f83dbd889d11fbeeef 100644
--- a/src/meshTools/meshSearch/meshSearch.C
+++ b/src/meshTools/meshSearch/meshSearch.C
@@ -27,9 +27,11 @@ License
 #include "meshSearch.H"
 #include "polyMesh.H"
 #include "indexedOctree.H"
-#include "pointIndexHit.H"
 #include "DynamicList.H"
 #include "demandDrivenData.H"
+#include "treeDataCell.H"
+#include "treeDataFace.H"
+#include "treeDataPoint.H"
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
diff --git a/src/meshTools/meshSearch/meshSearch.H b/src/meshTools/meshSearch/meshSearch.H
index 7b99a7159c5e6dfee2d1eff12a7697d72c564b1c..c8d44bdd489b045469538fbcb0179cbc59571b10 100644
--- a/src/meshTools/meshSearch/meshSearch.H
+++ b/src/meshTools/meshSearch/meshSearch.H
@@ -37,9 +37,6 @@ SourceFiles
 #ifndef meshSearch_H
 #define meshSearch_H
 
-#include "treeDataCell.H"
-#include "treeDataFace.H"
-#include "treeDataPoint.H"
 #include "pointIndexHit.H"
 #include "Cloud.H"
 #include "passiveParticle.H"
@@ -51,6 +48,10 @@ namespace Foam
 
 // Forward declaration of classes
 class polyMesh;
+class treeDataCell;
+class treeDataFace;
+class treeDataPoint;
+template<class Type> class indexedOctree;
 
 /*---------------------------------------------------------------------------*\
                            Class meshSearch Declaration
diff --git a/src/meshTools/octree/treeBoundBox.C b/src/meshTools/octree/treeBoundBox.C
index ce62c471924a26b1d138f2d49b0e6c91a42dd5b7..6133bc3106f9c3e8e07edd53b0d3e7a639211bda 100644
--- a/src/meshTools/octree/treeBoundBox.C
+++ b/src/meshTools/octree/treeBoundBox.C
@@ -309,12 +309,14 @@ bool Foam::treeBoundBox::overlaps
 //     This makes sure that posBits tests 'inside'
 bool Foam::treeBoundBox::intersects
 (
+    const point& overallStart,
+    const vector& overallVec,
     const point& start,
     const point& end,
-    point& pt
+    point& pt,
+    direction& ptOnFaces
 ) const
 {
-    const vector vec(end - start);
     const direction endBits = posBits(end);
     pt = start;
 
@@ -325,80 +327,106 @@ bool Foam::treeBoundBox::intersects
         if (ptBits == 0)
         {
             // pt inside bb
+            ptOnFaces = faceBits(pt);
             return true;
         }
 
         if ((ptBits & endBits) != 0)
         {
             // pt and end in same block outside of bb
+            ptOnFaces = faceBits(pt);
             return false;
         }
 
         if (ptBits & LEFTBIT)
         {
             // Intersect with plane V=min, n=-1,0,0
-            if (Foam::mag(vec.x()) > VSMALL)
+            if (Foam::mag(overallVec.x()) > VSMALL)
+            {
+                scalar s = (min().x() - overallStart.x())/overallVec.x();
+                pt.x() = min().x();
+                pt.y() = overallStart.y() + overallVec.y()*s;
+                pt.z() = overallStart.z() + overallVec.z()*s;
+            }
+            else
             {
-                scalar s = (min().x() - pt.x())/vec.x();
+                // Vector not in x-direction. But still intersecting bb planes.
+                // So must be close - just snap to bb.
                 pt.x() = min().x();
-                pt.y() = pt.y() + vec.y()*s;
-                pt.z() = pt.z() + vec.z()*s;
             }
         }
-        if (ptBits & RIGHTBIT)
+        else if (ptBits & RIGHTBIT)
         {
             // Intersect with plane V=max, n=1,0,0
-            if (Foam::mag(vec.x()) > VSMALL)
+            if (Foam::mag(overallVec.x()) > VSMALL)
+            {
+                scalar s = (max().x() - overallStart.x())/overallVec.x();
+                pt.x() = max().x();
+                pt.y() = overallStart.y() + overallVec.y()*s;
+                pt.z() = overallStart.z() + overallVec.z()*s;
+            }
+            else
             {
-                scalar s = (max().x() - pt.x())/vec.x();
                 pt.x() = max().x();
-                pt.y() = pt.y() + vec.y()*s;
-                pt.z() = pt.z() + vec.z()*s;
             }
         }
-
-        if (ptBits & BOTTOMBIT)
+        else if (ptBits & BOTTOMBIT)
         {
             // Intersect with plane V=min, n=0,-1,0
-            if (Foam::mag(vec.y()) > VSMALL)
+            if (Foam::mag(overallVec.y()) > VSMALL)
             {
-                scalar s = (min().y() - pt.y())/vec.y();
-                pt.x() = pt.x() + vec.x()*s;
+                scalar s = (min().y() - overallStart.y())/overallVec.y();
+                pt.x() = overallStart.x() + overallVec.x()*s;
                 pt.y() = min().y();
-                pt.z() = pt.z() + vec.z()*s;
+                pt.z() = overallStart.z() + overallVec.z()*s;
+            }
+            else
+            {
+                pt.x() = min().y();
             }
         }
-        if (ptBits & TOPBIT)
+        else if (ptBits & TOPBIT)
         {
             // Intersect with plane V=max, n=0,1,0
-            if (Foam::mag(vec.y()) > VSMALL)
+            if (Foam::mag(overallVec.y()) > VSMALL)
+            {
+                scalar s = (max().y() - overallStart.y())/overallVec.y();
+                pt.x() = overallStart.x() + overallVec.x()*s;
+                pt.y() = max().y();
+                pt.z() = overallStart.z() + overallVec.z()*s;
+            }
+            else
             {
-                scalar s = (max().y() - pt.y())/vec.y();
-                pt.x() = pt.x() + vec.x()*s;
                 pt.y() = max().y();
-                pt.z() = pt.z() + vec.z()*s;
             }
         }
-
-        if (ptBits & BACKBIT)
+        else if (ptBits & BACKBIT)
         {
             // Intersect with plane V=min, n=0,0,-1
-            if (Foam::mag(vec.z()) > VSMALL)
+            if (Foam::mag(overallVec.z()) > VSMALL)
+            {
+                scalar s = (min().z() - overallStart.z())/overallVec.z();
+                pt.x() = overallStart.x() + overallVec.x()*s;
+                pt.y() = overallStart.y() + overallVec.y()*s;
+                pt.z() = min().z();
+            }
+            else
             {
-                scalar s = (min().z() - pt.z())/vec.z();
-                pt.x() = pt.x() + vec.x()*s;
-                pt.y() = pt.y() + vec.y()*s;
                 pt.z() = min().z();
             }
         }
-        if (ptBits & FRONTBIT)
+        else if (ptBits & FRONTBIT)
         {
             // Intersect with plane V=max, n=0,0,1
-            if (Foam::mag(vec.z()) > VSMALL)
+            if (Foam::mag(overallVec.z()) > VSMALL)
+            {
+                scalar s = (max().z() - overallStart.z())/overallVec.z();
+                pt.x() = overallStart.x() + overallVec.x()*s;
+                pt.y() = overallStart.y() + overallVec.y()*s;
+                pt.z() = max().z();
+            }
+            else
             {
-                scalar s = (max().z() - pt.z())/vec.z();
-                pt.x() = pt.x() + vec.x()*s;
-                pt.y() = pt.y() + vec.y()*s;
                 pt.z() = max().z();
             }
         }
@@ -406,6 +434,18 @@ bool Foam::treeBoundBox::intersects
 }
 
 
+bool Foam::treeBoundBox::intersects
+(
+    const point& start,
+    const point& end,
+    point& pt
+) const
+{
+    direction ptBits;
+    return intersects(start, end-start, start, end, pt, ptBits);
+}
+
+
 // this.bb fully contains bb
 bool Foam::treeBoundBox::contains(const treeBoundBox& bb) const
 {
@@ -452,6 +492,40 @@ bool Foam::treeBoundBox::contains(const vector& dir, const point& pt) const
 }
 
 
+// Code position of pt on bounding box faces
+Foam::direction Foam::treeBoundBox::faceBits(const point& pt) const
+{
+    direction faceBits = 0;
+    if (pt.x() == min().x())
+    {
+        faceBits |= LEFTBIT;
+    }
+    else if (pt.x() == max().x())
+    {
+        faceBits |= RIGHTBIT;
+    }
+
+    if (pt.y() == min().y())
+    {
+        faceBits |= BOTTOMBIT;
+    }
+    else if (pt.y() == max().y())
+    {
+        faceBits |= TOPBIT;
+    }
+
+    if (pt.z() == min().z())
+    {
+        faceBits |= BACKBIT;
+    }
+    else if (pt.z() == max().z())
+    {
+        faceBits |= FRONTBIT;
+    }
+    return faceBits;
+}
+
+
 // Code position of point relative to box
 Foam::direction Foam::treeBoundBox::posBits(const point& pt) const
 {
@@ -461,7 +535,7 @@ Foam::direction Foam::treeBoundBox::posBits(const point& pt) const
     {
         posBits |= LEFTBIT;
     }
-    if (pt.x() > max().x())
+    else if (pt.x() > max().x())
     {
         posBits |= RIGHTBIT;
     }
@@ -470,7 +544,7 @@ Foam::direction Foam::treeBoundBox::posBits(const point& pt) const
     {
         posBits |= BOTTOMBIT;
     }
-    if (pt.y() > max().y())
+    else if (pt.y() > max().y())
     {
         posBits |= TOPBIT;
     }
@@ -479,7 +553,7 @@ Foam::direction Foam::treeBoundBox::posBits(const point& pt) const
     {
         posBits |= BACKBIT;
     }
-    if (pt.z() > max().z())
+    else if (pt.z() > max().z())
     {
         posBits |= FRONTBIT;
     }
diff --git a/src/meshTools/octree/treeBoundBox.H b/src/meshTools/octree/treeBoundBox.H
index 77498b2935212cf1b49a29892a20e270657bdad9..69791e04a85b8ddac668cc924a0f46f48b67a5b4 100644
--- a/src/meshTools/octree/treeBoundBox.H
+++ b/src/meshTools/octree/treeBoundBox.H
@@ -120,12 +120,12 @@ public:
         enum faceBit
         {
             NOFACE    = 0,
-            LEFTBIT   = 0x1 << LEFT,
-            RIGHTBIT  = 0x1 << RIGHT,
-            BOTTOMBIT = 0x1 << BOTTOM,
-            TOPBIT    = 0x1 << TOP,
-            BACKBIT   = 0x1 << BACK,
-            FRONTBIT  = 0x1 << FRONT,
+            LEFTBIT   = 0x1 << LEFT,    //1
+            RIGHTBIT  = 0x1 << RIGHT,   //2
+            BOTTOMBIT = 0x1 << BOTTOM,  //4
+            TOPBIT    = 0x1 << TOP,     //8
+            BACKBIT   = 0x1 << BACK,    //16
+            FRONTBIT  = 0x1 << FRONT,   //32
         };
 
         //- Edges codes.
@@ -265,9 +265,25 @@ public:
             //- Overlaps boundingSphere (centre + sqr(radius))?
             bool overlaps(const point&, const scalar radiusSqr) const;
 
-            //- Intersects segment; set point to intersection position,
+            //- Intersects segment; set point to intersection position and face,
             //  return true if intersection found.
-            // (intPt argument used during calculation even if not intersecting)
+            //  (pt argument used during calculation even if not intersecting).
+            //  Calculates intersections from outside supplied vector
+            //  (overallStart, overallVec). This is so when
+            //  e.g. tracking through lots of consecutive boxes
+            // (typical octree) we're not accumulating truncation errors. Set
+            // to start, (end-start) if not used.
+            bool intersects
+            (
+                const point& overallStart,
+                const vector& overallVec,
+                const point& start,
+                const point& end,
+                point& pt,
+                direction& ptBits
+            ) const;
+
+            //- Like above but does not return faces point is on
             bool intersects
             (
                 const point& start,
@@ -285,6 +301,9 @@ public:
             //  dir would cause it to go inside.
             bool contains(const vector& dir, const point&) const;
 
+            //- Code position of pt on bounding box faces
+            direction faceBits(const point& pt) const;
+
             //- Position of point relative to bounding box
             direction posBits(const point&) const;
 
diff --git a/src/meshTools/searchableSurface/searchableCylinder.C b/src/meshTools/searchableSurface/searchableCylinder.C
index e2b8426f1fec5448dc51fbc9347b0893e6e9eb60..fcaa42194aab42ce1f06f9e199f215548b92c627 100644
--- a/src/meshTools/searchableSurface/searchableCylinder.C
+++ b/src/meshTools/searchableSurface/searchableCylinder.C
@@ -105,6 +105,13 @@ Foam::pointIndexHit Foam::searchableCylinder::findNearest
 }
 
 
+Foam::scalar Foam::searchableCylinder::radius2(const point& pt) const
+{
+    const vector x = (pt-point1_) ^ unitDir_;
+    return x&x;
+}
+
+
 // From http://www.gamedev.net/community/forums/topic.asp?topic_id=467789 -
 // intersection of cylinder with ray
 void Foam::searchableCylinder::findLineAll
@@ -118,13 +125,91 @@ void Foam::searchableCylinder::findLineAll
     near.setMiss();
     far.setMiss();
 
-    // Line as P = start + t*V
-    const vector V(end-start);
+    vector point1Start(start-point1_);
+    vector point2Start(start-point2_);
+    vector point1End(end-point1_);
+
+    // Quick rejection of complete vector outside endcaps
+    scalar s1 = point1Start&unitDir_;
+    scalar s2 = point1End&unitDir_;
+
+    if ((s1 < 0 && s2 < 0) || (s1 > magDir_ && s2 > magDir_))
+    {
+        return;
+    }
+
+    // Line as P = start+t*V  where V is unit vector and t=[0..mag(end-start)]
+    vector V(end-start);
+    scalar magV = mag(V);
+    if (magV < ROOTVSMALL)
+    {
+        return;
+    }
+    V /= magV;
+
+
+    // We now get the nearest intersections to start. This can either be
+    // the intersection with the end plane or with the cylinder side.
+
+    // Get the two points (expressed in t) on the end planes. This is to
+    // clip any cylinder intersection against.
+    scalar tPoint1;
+    scalar tPoint2;
+
+    // Maintain the two intersections with the endcaps
+    scalar tNear = VGREAT;
+    scalar tFar = VGREAT;
+
+    {
+        scalar s = (V&unitDir_);
+        if (mag(s) > VSMALL)
+        {
+            tPoint1 = -s1/s;
+            tPoint2 = -(point2Start&unitDir_)/s;
+            if (tPoint2 < tPoint1)
+            {
+                Swap(tPoint1, tPoint2);
+            }
+            if (tPoint1 > magV || tPoint2 < 0)
+            {
+                return;
+            }
+
+            // See if the points on the endcaps are actually inside the cylinder
+            if (tPoint1 >= 0 && tPoint1 <= magV)
+            {
+                if (radius2(start+tPoint1*V) <= sqr(radius_))
+                {
+                    tNear = tPoint1;
+                }
+            }
+            if (tPoint2 >= 0 && tPoint2 <= magV)
+            {
+                if (radius2(start+tPoint2*V) <= sqr(radius_))
+                {
+                    // Check if already have a near hit from point1
+                    if (tNear <= 1)
+                    {
+                        tFar = tPoint2;
+                    }
+                    else
+                    {
+                        tNear = tPoint2;
+                    }
+                }
+            }
+        }
+        else
+        {
+            // Vector perpendicular to cylinder. Check for outside already done
+            // above so just set tpoint to allow all.
+            tPoint1 = -VGREAT;
+            tPoint2 = VGREAT;
+        }
+    }
 
-//Pout<< "point1:" << point1_ << " point2:" << point2_
-//    << " start:" << start << " end:" << end << endl;
 
-    const vector x = (start-point1_) ^ unitDir_;
+    const vector x = point1Start ^ unitDir_;
     const vector y = V ^ unitDir_;
     const scalar d = sqr(radius_);
 
@@ -135,11 +220,12 @@ void Foam::searchableCylinder::findLineAll
 
     const scalar disc = b*b-4*a*c;
 
-//Pout<< "a:" << a << " b:" << b << " c:" << c << " disc:" << disc
-//    << endl;
+    scalar t1 = -VGREAT;
+    scalar t2 = VGREAT;
 
     if (disc < 0)
     {
+        // Fully outside
         return;
     }
     else if (disc < ROOTVSMALL)
@@ -147,12 +233,40 @@ void Foam::searchableCylinder::findLineAll
         // Single solution
         if (mag(a) > ROOTVSMALL)
         {
-            scalar t = -b/(2*a);
-            if (t >= 0 && t <= 1)
+            t1 = -b/(2*a);
+
+            //Pout<< "single solution t:" << t1
+            //    << " for start:" << start << " end:" << end
+            //    << " c:" << c << endl;
+
+            if (t1 >= 0 && t1 <= magV && t1 >= tPoint1 && t1 <= tPoint2)
+            {
+                // valid. Insert sorted.
+                if (t1 < tNear)
+                {
+                    tFar = tNear;
+                    tNear = t1;
+                }
+                else if (t1 < tFar)
+                {
+                    tFar = t1;
+                }
+            }
+            else
             {
-                near.setPoint(start + t*V);
-                near.setHit();
-                near.setIndex(0);
+                return;
+            }
+        }
+        else
+        {
+            // Aligned with axis. Check if outside radius
+            //Pout<< "small discriminant:" << disc
+            //    << " for start:" << start << " end:" << end
+            //    << " magV:" << magV
+            //    << " c:" << c << endl;
+            if (c > 0)
+            {
+                return;
             }
         }
     }
@@ -162,41 +276,79 @@ void Foam::searchableCylinder::findLineAll
         {
             scalar sqrtDisc = sqrt(disc);
 
-            scalar t1 = (-b + sqrtDisc)/2*a;
-            scalar t2 = (-b - sqrtDisc)/2*a;
+            t1 = (-b - sqrtDisc)/(2*a);
+            t2 = (-b + sqrtDisc)/(2*a);
+            if (t2 < t1)
+            {
+                Swap(t1, t2);
+            }
 
-            if (t1 < t2)
+            if (t1 >= 0 && t1 <= magV && t1 >= tPoint1 && t1 <= tPoint2)
             {
-                if (t1 >= 0 && t1 <= 1)
+                // valid. Insert sorted.
+                if (t1 < tNear)
                 {
-                    near.setPoint(start + t1*V);
-                    near.setHit();
-                    near.setIndex(0);
+                    tFar = tNear;
+                    tNear = t1;
                 }
-                if (t2 >= 0 && t2 <= 1)
+                else if (t1 < tFar)
                 {
-                    far.setPoint(start + t2*V);
-                    far.setHit();
-                    far.setIndex(0);
+                    tFar = t1;
                 }
             }
-            else
+            if (t2 >= 0 && t2 <= magV && t2 >= tPoint1 && t2 <= tPoint2)
             {
-                if (t2 >= 0 && t2 <= 1)
+                // valid. Insert sorted.
+                if (t2 < tNear)
                 {
-                    near.setPoint(start + t2*V);
-                    near.setHit();
-                    near.setIndex(0);
+                    tFar = tNear;
+                    tNear = t2;
                 }
-                if (t1 >= 0 && t1 <= 1)
+                else if (t2 < tFar)
                 {
-                    far.setPoint(start + t1*V);
-                    far.setHit();
-                    far.setIndex(0);
+                    tFar = t2;
                 }
             }
+            //Pout<< "two solutions t1:" << t1 << " t2:" << t2
+            //    << " for start:" << start << " end:" << end
+            //    << " magV:" << magV
+            //    << " c:" << c << endl;
+        }
+        else
+        {
+            // Aligned with axis. Check if outside radius
+            //Pout<< "large discriminant:" << disc
+            //    << " small a:" << a
+            //    << " for start:" << start << " end:" << end
+            //    << " magV:" << magV
+            //    << " c:" << c << endl;
+            if (c > 0)
+            {
+                return;
+            }
+        }
+    }
+
+    // Check tNear, tFar
+    if (tNear >= 0 && tNear <= magV)
+    {
+        near.setPoint(start+tNear*V);
+        near.setHit();
+        near.setIndex(0);
+
+        if (tFar <= magV)
+        {
+            far.setPoint(start+tFar*V);
+            far.setHit();
+            far.setIndex(0);
         }
     }
+    else if (tFar >= 0 && tFar <= magV)
+    {
+        near.setPoint(start+tFar*V);
+        near.setHit();
+        near.setIndex(0);
+    }
 }
 
 
@@ -216,13 +368,7 @@ Foam::searchableCylinder::searchableCylinder
     magDir_(mag(point2_-point1_)),
     unitDir_((point2_-point1_)/magDir_),
     radius_(radius)
-{
-    Pout<< "point1_:" << point1_ << endl;
-    Pout<< "point2_:" << point2_ << endl;
-    Pout<< "magDir_:" << magDir_ << endl;
-    Pout<< "unitDir_:" << unitDir_ << endl;
-    Pout<< "radius_:" << radius_ << endl;
-}
+{}
 
 
 Foam::searchableCylinder::searchableCylinder
@@ -237,13 +383,7 @@ Foam::searchableCylinder::searchableCylinder
     magDir_(mag(point2_-point1_)),
     unitDir_((point2_-point1_)/magDir_),
     radius_(readScalar(dict.lookup("radius")))
-{
-    Pout<< "point1_:" << point1_ << endl;
-    Pout<< "point2_:" << point2_ << endl;
-    Pout<< "magDir_:" << magDir_ << endl;
-    Pout<< "unitDir_:" << unitDir_ << endl;
-    Pout<< "radius_:" << radius_ << endl;
-}
+{}
 
 
 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
@@ -290,11 +430,10 @@ void Foam::searchableCylinder::findLine
 {
     info.setSize(start.size());
 
-    pointIndexHit b;
-
     forAll(start, i)
     {
         // Pick nearest intersection. If none intersected take second one.
+        pointIndexHit b;
         findLineAll(start[i], end[i], info[i], b);
         if (!info[i].hit() && b.hit())
         {
@@ -313,11 +452,10 @@ void Foam::searchableCylinder::findLineAny
 {
     info.setSize(start.size());
 
-    pointIndexHit b;
-
     forAll(start, i)
     {
         // Discard far intersection
+        pointIndexHit b;
         findLineAll(start[i], end[i], info[i], b);
         if (!info[i].hit() && b.hit())
         {
diff --git a/src/meshTools/searchableSurface/searchableCylinder.H b/src/meshTools/searchableSurface/searchableCylinder.H
index 55ee0354ddd0665e6e37ec85320aca072fe29a25..cae0f058db2863db95ff479381d207c8ad9e57cf 100644
--- a/src/meshTools/searchableSurface/searchableCylinder.H
+++ b/src/meshTools/searchableSurface/searchableCylinder.H
@@ -86,6 +86,8 @@ private:
             const scalar nearestDistSqr
         ) const;
 
+        scalar radius2(const point& pt) const;
+
         //- Find intersection with cylinder
         void findLineAll
         (
diff --git a/src/meshTools/searchableSurface/triSurfaceMesh.C b/src/meshTools/searchableSurface/triSurfaceMesh.C
index 877f2643414d78b9fc986fa2d765b56aac04b816..950cd13285334a4849f187b61f678f0dc21b309d 100644
--- a/src/meshTools/searchableSurface/triSurfaceMesh.C
+++ b/src/meshTools/searchableSurface/triSurfaceMesh.C
@@ -237,6 +237,7 @@ Foam::triSurfaceMesh::triSurfaceMesh(const IOobject& io, const triSurface& s)
         )
     ),
     triSurface(s),
+    tolerance_(indexedOctree<treeDataTriSurface>::perturbTol()),
     surfaceClosed_(-1)
 {}
 
@@ -279,6 +280,7 @@ Foam::triSurfaceMesh::triSurfaceMesh(const IOobject& io)
             searchableSurface::objectPath()
         )
     ),
+    tolerance_(indexedOctree<treeDataTriSurface>::perturbTol()),
     surfaceClosed_(-1)
 {}
 
@@ -324,6 +326,7 @@ Foam::triSurfaceMesh::triSurfaceMesh
             searchableSurface::objectPath()
         )
     ),
+    tolerance_(indexedOctree<treeDataTriSurface>::perturbTol()),
     surfaceClosed_(-1)
 {
     scalar scaleFactor = 0;
@@ -332,8 +335,18 @@ Foam::triSurfaceMesh::triSurfaceMesh
     // eg, CAD geometries are often done in millimeters
     if (dict.readIfPresent("scale", scaleFactor) && scaleFactor > 0)
     {
+        Info<< searchableSurface::name() << " : using scale " << scaleFactor
+            << endl;
         triSurface::scalePoints(scaleFactor);
     }
+
+
+    // Have optional non-standard search tolerance for gappy surfaces.
+    if (dict.readIfPresent("tolerance", tolerance_) && tolerance_ > 0)
+    {
+        Info<< searchableSurface::name() << " : using intersection tolerance "
+            << tolerance_ << endl;
+    }
 }
 
 
@@ -380,6 +393,9 @@ const Foam::indexedOctree<Foam::treeDataTriSurface>&
         bb.min() -= point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL);
         bb.max() += point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL);
 
+        scalar oldTol = indexedOctree<treeDataTriSurface>::perturbTol();
+        indexedOctree<treeDataTriSurface>::perturbTol() = tolerance_;
+
         tree_.reset
         (
             new indexedOctree<treeDataTriSurface>
@@ -391,6 +407,8 @@ const Foam::indexedOctree<Foam::treeDataTriSurface>&
                 3.0     // duplicity
             )
         );
+
+        indexedOctree<treeDataTriSurface>::perturbTol() = oldTol;
     }
 
     return tree_();
@@ -491,6 +509,9 @@ void Foam::triSurfaceMesh::findNearest
 
     info.setSize(samples.size());
 
+    scalar oldTol = indexedOctree<treeDataTriSurface>::perturbTol();
+    indexedOctree<treeDataTriSurface>::perturbTol() = tolerance_;
+
     forAll(samples, i)
     {
         static_cast<pointIndexHit&>(info[i]) = octree.findNearest
@@ -499,6 +520,8 @@ void Foam::triSurfaceMesh::findNearest
             nearestDistSqr[i]
         );
     }
+
+    indexedOctree<treeDataTriSurface>::perturbTol() = oldTol;
 }
 
 
@@ -513,6 +536,9 @@ void Foam::triSurfaceMesh::findLine
 
     info.setSize(start.size());
 
+    scalar oldTol = indexedOctree<treeDataTriSurface>::perturbTol();
+    indexedOctree<treeDataTriSurface>::perturbTol() = tolerance_;
+
     forAll(start, i)
     {
         static_cast<pointIndexHit&>(info[i]) = octree.findLine
@@ -521,6 +547,8 @@ void Foam::triSurfaceMesh::findLine
             end[i]
         );
     }
+
+    indexedOctree<treeDataTriSurface>::perturbTol() = oldTol;
 }
 
 
@@ -535,6 +563,9 @@ void Foam::triSurfaceMesh::findLineAny
 
     info.setSize(start.size());
 
+    scalar oldTol = indexedOctree<treeDataTriSurface>::perturbTol();
+    indexedOctree<treeDataTriSurface>::perturbTol() = tolerance_;
+
     forAll(start, i)
     {
         static_cast<pointIndexHit&>(info[i]) = octree.findLineAny
@@ -543,6 +574,8 @@ void Foam::triSurfaceMesh::findLineAny
             end[i]
         );
     }
+
+    indexedOctree<treeDataTriSurface>::perturbTol() = oldTol;
 }
 
 
@@ -557,6 +590,9 @@ void Foam::triSurfaceMesh::findLineAll
 
     info.setSize(start.size());
 
+    scalar oldTol = indexedOctree<treeDataTriSurface>::perturbTol();
+    indexedOctree<treeDataTriSurface>::perturbTol() = tolerance_;
+
     // Work array
     DynamicList<pointIndexHit, 1, 1> hits;
 
@@ -570,7 +606,7 @@ void Foam::triSurfaceMesh::findLineAll
     const scalarField magSqrDirVec(magSqr(dirVec));
     const vectorField smallVec
     (
-        Foam::sqrt(SMALL)*dirVec
+        indexedOctree<treeDataTriSurface>::perturbTol()*dirVec
       + vector(ROOTVSMALL,ROOTVSMALL,ROOTVSMALL)
     );
 
@@ -613,6 +649,8 @@ void Foam::triSurfaceMesh::findLineAll
             info[pointI].clear();
         }
     }
+
+    indexedOctree<treeDataTriSurface>::perturbTol() = oldTol;
 }
 
 
@@ -649,7 +687,13 @@ void Foam::triSurfaceMesh::getNormal
     {
         if (info[i].hit())
         {
-            normal[i] = faceNormals()[info[i].index()];
+            label triI = info[i].index();
+            //- Cached:
+            //normal[i] = faceNormals()[triI];
+
+            //- Uncached
+            normal[i] = triSurface::operator[](triI).normal(points());
+            normal[i] /= mag(normal[i]) + VSMALL;
         }
         else
         {
@@ -691,6 +735,9 @@ void Foam::triSurfaceMesh::getVolumeType
 {
     volType.setSize(points.size());
 
+    scalar oldTol = indexedOctree<treeDataTriSurface>::perturbTol();
+    indexedOctree<treeDataTriSurface>::perturbTol() = tolerance_;
+
     forAll(points, pointI)
     {
         const point& pt = points[pointI];
@@ -699,6 +746,8 @@ void Foam::triSurfaceMesh::getVolumeType
         // - cheat conversion since same values
         volType[pointI] = static_cast<volumeType>(tree().getVolumeType(pt));
     }
+
+    indexedOctree<treeDataTriSurface>::perturbTol() = oldTol;
 }
 
 
diff --git a/src/meshTools/searchableSurface/triSurfaceMesh.H b/src/meshTools/searchableSurface/triSurfaceMesh.H
index b2ec61c14a943e4c6d4268306d5dfc4ee9157359..4ae415fafa441090bc9589b1b582aec298281d2b 100644
--- a/src/meshTools/searchableSurface/triSurfaceMesh.H
+++ b/src/meshTools/searchableSurface/triSurfaceMesh.H
@@ -28,6 +28,11 @@ Class
 Description
     IOoject and searching on triSurface
 
+    Note: when constructing from dictionary has optional parameters:
+        - scale     : scaling factor.
+        - tolerance : relative tolerance for doing intersections
+                      (see triangle::intersection)
+
 SourceFiles
     triSurfaceMesh.C
 
@@ -63,6 +68,9 @@ private:
 
     // Private member data
 
+        //- Optional tolerance to use in searches
+        scalar tolerance_;
+
         //- Search tree (triangles)
         mutable autoPtr<indexedOctree<treeDataTriSurface> > tree_;
 
diff --git a/src/meshTools/triSurface/orientedSurface/orientedSurface.C b/src/meshTools/triSurface/orientedSurface/orientedSurface.C
index 10e1fa8f2f930e9457352190159ea80584ef3623..f4c165d83f40ee11ee1dffcc2a997f28282f9eba 100644
--- a/src/meshTools/triSurface/orientedSurface/orientedSurface.C
+++ b/src/meshTools/triSurface/orientedSurface/orientedSurface.C
@@ -121,8 +121,8 @@ Foam::labelList Foam::orientedSurface::edgeToFace
             label face0 = eFaces[0];
             label face1 = eFaces[1];
 
-            const labelledTri& f0 = s[face0];
-            const labelledTri& f1 = s[face1];
+            const labelledTri& f0 = s.localFaces()[face0];
+            const labelledTri& f1 = s.localFaces()[face1];
 
             if (flip[face0] == UNVISITED)
             {
@@ -238,7 +238,8 @@ void Foam::orientedSurface::propagateOrientation
         s,
         samplePoint,
         nearestFaceI,
-        nearestPt
+        nearestPt,
+        10*SMALL
     );
 
     if (side == triSurfaceTools::UNKNOWN)
@@ -348,7 +349,10 @@ Foam::orientedSurface::orientedSurface
 :
     triSurface(surf)
 {
-    point outsidePoint = 2 * treeBoundBox(localPoints()).span();
+    // BoundBox calculation without localPoints
+    treeBoundBox bb(surf.points(), surf.meshPoints());
+
+    point outsidePoint = bb.max() + bb.span();
 
     orient(*this, outsidePoint, orientOutside);
 }
diff --git a/src/meshTools/triSurface/triSurfaceTools/triSurfaceTools.C b/src/meshTools/triSurface/triSurfaceTools/triSurfaceTools.C
index 08138f450be02188245c335841a6a3f638ae1974..b89afdab63b372cb73ad5839afec77febf4d14d0 100644
--- a/src/meshTools/triSurface/triSurfaceTools/triSurfaceTools.C
+++ b/src/meshTools/triSurface/triSurfaceTools/triSurfaceTools.C
@@ -2203,7 +2203,8 @@ Foam::triSurfaceTools::sideType Foam::triSurfaceTools::surfaceSide
     const triSurface& surf,
     const point& sample,
     const label nearestFaceI,   // nearest face
-    const point& nearestPoint   // nearest point on nearest face
+    const point& nearestPoint,  // nearest point on nearest face
+    const scalar tol
 )
 {
     const labelledTri& f = surf[nearestFaceI];
@@ -2217,7 +2218,7 @@ Foam::triSurfaceTools::sideType Foam::triSurfaceTools::surfaceSide
         points[f[0]],
         points[f[1]],
         points[f[2]]
-    ).classify(nearestPoint, 1E-6, nearType, nearLabel);
+    ).classify(nearestPoint, tol, nearType, nearLabel);
 
     if (nearType == triPointRef::NONE)
     {
diff --git a/src/meshTools/triSurface/triSurfaceTools/triSurfaceTools.H b/src/meshTools/triSurface/triSurfaceTools/triSurfaceTools.H
index 8ddac22a2994296ec86010bac901d3abe02d05d7..b88d460b77bbc934438df741bc351375eab62ce4 100644
--- a/src/meshTools/triSurface/triSurfaceTools/triSurfaceTools.H
+++ b/src/meshTools/triSurface/triSurfaceTools/triSurfaceTools.H
@@ -454,13 +454,14 @@ public:
 
         //- Given nearest point (to sample) on surface determines which side
         //  sample is. Uses either face normal, edge normal or point normal
-        //  (non-trivial). Feed in output of e.g. triangle::classify.
+        //  (non-trivial). Uses triangle::classify.
         static sideType surfaceSide
         (
             const triSurface& surf,
             const point& sample,
             const label nearestFaceI,   // nearest face
-            const point& nearestPt      // nearest point on nearest face
+            const point& nearestPt,     // nearest point on nearest face
+            const scalar tol            // tolerance for nearness test.
         );
 
     // Triangulation of faces
diff --git a/src/meshTools/triSurface/triangleFuncs/triangleFuncs.C b/src/meshTools/triSurface/triangleFuncs/triangleFuncs.C
index be83b6326cc52d558ce6130ffac5d77c3388bc9c..1bef529b0325f6242c8ce98574eafe9b4b4c398b 100644
--- a/src/meshTools/triSurface/triangleFuncs/triangleFuncs.C
+++ b/src/meshTools/triSurface/triangleFuncs/triangleFuncs.C
@@ -22,8 +22,6 @@ License
     along with OpenFOAM; if not, write to the Free Software Foundation,
     Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 
-Description
-
 \*---------------------------------------------------------------------------*/
 
 #include "triangleFuncs.H"
@@ -31,8 +29,6 @@ Description
 #include "treeBoundBox.H"
 #include "SortableList.H"
 #include "boolList.H"
-#include "scalar.H"
-
 
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
@@ -170,7 +166,6 @@ bool Foam::triangleFuncs::intersectAxesBundle
 }
 
 
-
 // Intersect triangle with bounding box. Return true if
 // any of the faces of bb intersect triangle.
 // Note: so returns false if triangle inside bb.
@@ -262,6 +257,272 @@ bool Foam::triangleFuncs::intersectBb
 }
 
 
+//// Intersect triangle with bounding box. Return true if
+//// any of the faces of bb intersect triangle.
+//// Note: so returns false if triangle inside bb.
+//bool Foam::triangleFuncs::intersectBbExact
+//(
+//    const point& p0,
+//    const point& p1,
+//    const point& p2,
+//    const treeBoundBox& cubeBb
+//)
+//{
+//    const point& min = cubeBb.min();
+//    const point& max = cubeBb.max();
+//
+//    const point& cube0 = min;
+//    const point  cube1(min.x(), min.y(), max.z());
+//    const point  cube2(max.x(), min.y(), max.z());
+//    const point  cube3(max.x(), min.y(), min.z());
+//
+//    const point  cube4(min.x(), max.y(), min.z());
+//    const point  cube5(min.x(), max.y(), max.z());
+//    const point& cube6 = max;
+//    const point  cube7(max.x(), max.y(), min.z());
+//
+//    // Test intersection of triangle with twelve edges of box.
+//    {
+//        triPointRef tri(p0, p1, p2);
+//        if (tri.intersectionExact(cube0, cube1).hit())
+//        {
+//            return true;
+//        }
+//        if (tri.intersectionExact(cube1, cube2).hit())
+//        {
+//            return true;
+//        }
+//        if (tri.intersectionExact(cube2, cube3).hit())
+//        {
+//            return true;
+//        }
+//        if (tri.intersectionExact(cube3, cube0).hit())
+//        {   
+//            return true;
+//        }
+//
+//        if (tri.intersectionExact(cube4, cube5).hit())
+//        {
+//            return true;
+//        }
+//        if (tri.intersectionExact(cube5, cube6).hit())
+//        {
+//            return true;
+//        }
+//        if (tri.intersectionExact(cube6, cube7).hit())
+//        {
+//            return true;
+//        }
+//        if (tri.intersectionExact(cube7, cube4).hit())
+//        {
+//            return true;
+//        }
+//
+//        if (tri.intersectionExact(cube0, cube4).hit())
+//        {
+//            return true;
+//        }
+//        if (tri.intersectionExact(cube1, cube5).hit())
+//        {
+//            return true;
+//        }
+//        if (tri.intersectionExact(cube2, cube6).hit())
+//        {
+//            return true;
+//        }
+//        if (tri.intersectionExact(cube3, cube7).hit())
+//        {
+//            return true;
+//        }
+//    }
+//    // Test intersection of triangle edges with bounding box
+//    {
+//        triPointRef tri(cube0, cube1, cube2);
+//        if (tri.intersectionExact(p0, p1).hit())
+//        {
+//            return true;
+//        }
+//        if (tri.intersectionExact(p1, p2).hit())
+//        {
+//            return true;
+//        }
+//        if (tri.intersectionExact(p2, p0).hit())
+//        {
+//            return true;
+//        }
+//    }
+//    {
+//        triPointRef tri(cube2, cube3, cube0);
+//        if (tri.intersectionExact(p0, p1).hit())
+//        {
+//            return true;
+//        }
+//        if (tri.intersectionExact(p1, p2).hit())
+//        {
+//            return true;
+//        }
+//        if (tri.intersectionExact(p2, p0).hit())
+//        {
+//            return true;
+//        }
+//    }
+//    {
+//        triPointRef tri(cube4, cube5, cube6);
+//        if (tri.intersectionExact(p0, p1).hit())
+//        {
+//            return true;
+//        }
+//        if (tri.intersectionExact(p1, p2).hit())
+//        {
+//            return true;
+//        }
+//        if (tri.intersectionExact(p2, p0).hit())
+//        {
+//            return true;
+//        }
+//    }
+//    {
+//        triPointRef tri(cube6, cube7, cube4);
+//        if (tri.intersectionExact(p0, p1).hit())
+//        {
+//            return true;
+//        }
+//        if (tri.intersectionExact(p1, p2).hit())
+//        {
+//            return true;
+//        }
+//        if (tri.intersectionExact(p2, p0).hit())
+//        {
+//            return true;
+//        }
+//    }
+//
+//
+//    {
+//        triPointRef tri(cube4, cube5, cube1);
+//        if (tri.intersectionExact(p0, p1).hit())
+//        {
+//            return true;
+//        }
+//        if (tri.intersectionExact(p1, p2).hit())
+//        {
+//            return true;
+//        }
+//        if (tri.intersectionExact(p2, p0).hit())
+//        {
+//            return true;
+//        }
+//    }
+//    {
+//        triPointRef tri(cube1, cube0, cube4);
+//        if (tri.intersectionExact(p0, p1).hit())
+//        {
+//            return true;
+//        }
+//        if (tri.intersectionExact(p1, p2).hit())
+//        {
+//            return true;
+//        }
+//        if (tri.intersectionExact(p2, p0).hit())
+//        {
+//            return true;
+//        }
+//    }
+//    {
+//        triPointRef tri(cube7, cube6, cube2);
+//        if (tri.intersectionExact(p0, p1).hit())
+//        {
+//            return true;
+//        }
+//        if (tri.intersectionExact(p1, p2).hit())
+//        {
+//            return true;
+//        }
+//        if (tri.intersectionExact(p2, p0).hit())
+//        {
+//            return true;
+//        }
+//    }
+//    {
+//        triPointRef tri(cube2, cube3, cube7);
+//        if (tri.intersectionExact(p0, p1).hit())
+//        {
+//            return true;
+//        }
+//        if (tri.intersectionExact(p1, p2).hit())
+//        {
+//            return true;
+//        }
+//        if (tri.intersectionExact(p2, p0).hit())
+//        {
+//            return true;
+//        }
+//    }
+//
+//    {
+//        triPointRef tri(cube0, cube4, cube7);
+//        if (tri.intersectionExact(p0, p1).hit())
+//        {
+//            return true;
+//        }
+//        if (tri.intersectionExact(p1, p2).hit())
+//        {
+//            return true;
+//        }
+//        if (tri.intersectionExact(p2, p0).hit())
+//        {
+//            return true;
+//        }
+//    }
+//    {
+//        triPointRef tri(cube7, cube3, cube0);
+//        if (tri.intersectionExact(p0, p1).hit())
+//        {
+//            return true;
+//        }
+//        if (tri.intersectionExact(p1, p2).hit())
+//        {
+//            return true;
+//        }
+//        if (tri.intersectionExact(p2, p0).hit())
+//        {
+//            return true;
+//        }
+//    }
+//    {
+//        triPointRef tri(cube1, cube5, cube6);
+//        if (tri.intersectionExact(p0, p1).hit())
+//        {
+//            return true;
+//        }
+//        if (tri.intersectionExact(p1, p2).hit())
+//        {
+//            return true;
+//        }
+//        if (tri.intersectionExact(p2, p0).hit())
+//        {
+//            return true;
+//        }
+//    }
+//    {
+//        triPointRef tri(cube6, cube2, cube1);
+//        if (tri.intersectionExact(p0, p1).hit())
+//        {
+//            return true;
+//        }
+//        if (tri.intersectionExact(p1, p2).hit())
+//        {
+//            return true;
+//        }
+//        if (tri.intersectionExact(p2, p0).hit())
+//        {
+//            return true;
+//        }
+//    }
+//    return false;
+//}
+
+
 bool Foam::triangleFuncs::intersect
 (
     const point& va0,
@@ -470,145 +731,4 @@ bool Foam::triangleFuncs::intersect
 }
 
 
-bool Foam::triangleFuncs::classify
-(
-    const point& baseVertex,
-    const vector& E0,
-    const vector& E1,
-    const vector& n,
-    const point& pInter,
-    const scalar tol,
-    label& nearType,
-    label& nearLabel
-)
-{
-    // Get largest component of normal
-    scalar magX = Foam::mag(n.x());
-    scalar magY = Foam::mag(n.y());
-    scalar magZ = Foam::mag(n.z());
-
-    label i0 = -1;
-    if ((magX >= magY) && (magX >= magZ))
-    {
-        i0 = 0;
-    }
-    else if ((magY >= magX) && (magY >= magZ))
-    {
-        i0 = 1;
-    }
-    else
-    {
-        i0 = 2;
-    }
-
-    // Get other components
-    label i1 = (i0 + 1) % 3;
-    label i2 = (i1 + 1) % 3;
-
-    scalar u1 = E0[i1];
-    scalar v1 = E0[i2];
-
-    scalar u2 = E1[i1];
-    scalar v2 = E1[i2];
-
-    scalar det = v2*u1 - u2*v1;
-
-    scalar u0 = pInter[i1] - baseVertex[i1];
-    scalar v0 = pInter[i2] - baseVertex[i2];
-
-    scalar alpha = 0;
-    scalar beta = 0;
-
-    bool hit = false;
-    
-    if (Foam::mag(u1) < ROOTVSMALL)
-    {
-        beta = u0/u2;
-
-        alpha = (v0 - beta*v2)/v1;
-
-        hit = ((alpha >= 0) && ((alpha + beta) <= 1));
-    }
-    else
-    {
-        beta = (v0*u1 - u0*v1)/det;
-
-        alpha = (u0 - beta*u2)/u1;
-
-        hit = ((alpha >= 0) && ((alpha + beta) <= 1));
-    }
-
-    //
-    // Now alpha, beta are the coordinates in the triangle local coordinate
-    // system E0, E1
-    //
-
-    nearType = NONE;
-    nearLabel = -1;
-
-    if (mag(alpha+beta-1) < tol)
-    {
-        // On edge between vert 1-2 (=edge 1)
-
-        if (mag(alpha) < tol)
-        {
-            nearType = POINT;
-            nearLabel = 2;
-        }
-        else if (mag(beta) < tol)
-        {
-            nearType = POINT;
-            nearLabel = 1;
-        }
-        else if ((alpha >= 0) && (alpha <= 1) && (beta >= 0) && (beta <= 1))
-        {
-            nearType = EDGE;
-            nearLabel = 1;
-        }
-    }
-    else if (mag(alpha) < tol)
-    {
-        // On edge between vert 2-0 (=edge 2)
-
-        if (mag(beta) < tol)
-        {
-            nearType = POINT;
-            nearLabel = 0;
-        }
-        else if (mag(beta-1) < tol)
-        {
-            nearType = POINT;
-            nearLabel = 2;
-        }
-        else if ((beta >= 0) && (beta <= 1))
-        {
-            nearType = EDGE;
-            nearLabel = 2;
-        }
-    }
-    else if (mag(beta) < tol)
-    {
-        // On edge between vert 0-1 (= edge 0)
-
-        if (mag(alpha) < tol)
-        {
-            nearType = POINT;
-            nearLabel = 0;
-        }
-        else if (mag(alpha-1) < tol)
-        {
-            nearType = POINT;
-            nearLabel = 1;
-        }
-        else if ((alpha >= 0) && (alpha <= 1))
-        {
-            nearType = EDGE;
-            nearLabel = 0;
-        }
-    }
-
-    return hit;
-}
-
-
 // ************************************************************************* //
diff --git a/src/meshTools/triSurface/triangleFuncs/triangleFuncs.H b/src/meshTools/triSurface/triangleFuncs/triangleFuncs.H
index 1180e10195399aa79640a86e7a5c9eeecce3939d..0aa2a4c1c406bdb76ce407d559deb2fe4314bccc 100644
--- a/src/meshTools/triSurface/triangleFuncs/triangleFuncs.H
+++ b/src/meshTools/triSurface/triangleFuncs/triangleFuncs.H
@@ -147,25 +147,6 @@ public:
         point& pInter0,
         point& pInter1
     );
-
-
-    //- Classify point on triangle plane w.r.t. triangle edges.
-    //  - inside/outside (returned)
-    //  - near point (0, 1, 2)
-    //  - near edge (0, 1, 2). Note: edges are counted from starting vertex
-    //    so e.g. edge 2 is from f[2] to f[0]
-    static bool classify
-    (
-        const point& baseVertex,
-        const vector& E0,
-        const vector& E1,
-        const vector& n,
-        const point& pInter,
-        const scalar tol,
-        label& nearType,
-        label& nearLabel
-    );
-
 };
 
 
diff --git a/src/triSurface/triSurface/triSurface.C b/src/triSurface/triSurface/triSurface.C
index 9b63d3de86259314aad1db4227c38f16476c11ec..b17aa88bb58ca26d7d6fad3cc2a223a68863428d 100644
--- a/src/triSurface/triSurface/triSurface.C
+++ b/src/triSurface/triSurface/triSurface.C
@@ -347,127 +347,6 @@ void Foam::triSurface::checkEdges(const bool verbose)
 }
 
 
-// Check normals and orientation
-Foam::boolList Foam::triSurface::checkOrientation(const bool verbose)
-{
-    const edgeList& es = edges();
-    const labelListList& faceEs = faceEdges();
-
-    // Check edge normals, face normals, point normals.
-    forAll(faceEs, facei)
-    {
-        const labelList& edgeLabels = faceEs[facei];
-
-        if (edgeLabels.size() != 3)
-        {
-            FatalErrorIn("triSurface::checkOrientation(bool)")
-                << "triangle " << (*this)[facei]
-                << " does not have 3 edges. Edges:" << edgeLabels
-                << exit(FatalError);
-        }
-
-        bool valid = true;
-        forAll(edgeLabels, i)
-        {
-            if (edgeLabels[i] < 0 || edgeLabels[i] >= nEdges())
-            {
-                WarningIn
-                (
-                    "triSurface::checkOrientation(bool)"
-                )   << "edge number " << edgeLabels[i] << " on face " << facei
-                    << " out-of-range\n"
-                    << "This usually means that the input surface has "
-                    << "edges with more than 2 triangles connected.\n"
-                    << endl;
-                valid = false;
-            }
-        }
-        if (! valid)
-        {
-            continue;
-        }
-
-
-        //
-        //- Compute normal from triangle points.
-        //
-
-        const labelledTri& tri = (*this)[facei];
-        const point pa(points()[tri[0]]);
-        const point pb(points()[tri[1]]);
-        const point pc(points()[tri[2]]);
-
-        const vector pointNormal((pc - pb) ^ (pa - pb));
-        if ((pointNormal & faceNormals()[facei]) < 0)
-        {
-            FatalErrorIn("triSurface::checkOrientation(bool)")
-                << "Normal calculated from points not consistent with"
-                " faceNormal" << endl
-                << "triangle:" << tri << endl
-                << "points:" << pa << ' ' << pb << ' ' << pc << endl
-                << "pointNormal:" << pointNormal << endl
-                << "faceNormal:" << faceNormals()[facei]
-                << exit(FatalError);
-        }
-    }
-
-
-    const labelListList& eFaces = edgeFaces();
-
-    // Storage for holding status of edge. True if normal flips across this
-    // edge
-    boolList borderEdge(nEdges(), false);
-
-    forAll(es, edgeI)
-    {
-        const edge& e = es[edgeI];
-        const labelList& neighbours = eFaces[edgeI];
-
-        if (neighbours.size() == 2)
-        {
-            const labelledTri& faceA = (*this)[neighbours[0]];
-            const labelledTri& faceB = (*this)[neighbours[1]];
-
-            // The edge cannot be going in the same direction if both faces
-            // are oriented counterclockwise.
-            // Thus the next face point *must* different between the faces.
-            if
-            (
-                faceA[faceA.fcIndex(findIndex(faceA, e.start()))]
-             == faceB[faceB.fcIndex(findIndex(faceB, e.start()))]
-            )
-            {
-                borderEdge[edgeI] = true;
-                if (verbose)
-                {
-                    WarningIn("PrimitivePatchExtra::checkOrientation(bool)")
-                        << "face orientation incorrect." << nl
-                        << "edge[" << edgeI << "] " << e
-                        << " between faces " << neighbours << ":" << nl
-                        << "face[" << neighbours[0] << "] " << faceA << nl
-                        << "face[" << neighbours[1] << "] " << faceB << endl;
-                }
-            }
-        }
-        else if (neighbours.size() != 1)
-        {
-            if (verbose)
-            {
-                WarningIn("triSurface::checkOrientation(bool)")
-                    << "Wrong number of edge neighbours." << endl
-                    << "edge[" << edgeI << "] " << e
-                    << "with points:" << localPoints()[e.start()]
-                    << ' ' << localPoints()[e.end()]
-                    << " has neighbours:" << neighbours << endl;
-            }
-            borderEdge[edgeI] = true;
-        }
-    }
-
-    return borderEdge;
-}
-
-
 // Read triangles, points from Istream
 bool Foam::triSurface::read(Istream& is)
 {
diff --git a/src/triSurface/triSurface/triSurface.H b/src/triSurface/triSurface/triSurface.H
index e6fb6239afec2313987fcd7ec582774740e29a02..9ee5b5ca4d9ee85e2bf1b392feba92928f7aa2ff 100644
--- a/src/triSurface/triSurface/triSurface.H
+++ b/src/triSurface/triSurface/triSurface.H
@@ -326,17 +326,12 @@ public:
             //- Scale points. A non-positive factor is ignored
             virtual void scalePoints(const scalar&);
 
-            //- Check/fix duplicate/degenerate triangles
+            //- Check/remove duplicate/degenerate triangles
             void checkTriangles(const bool verbose);
 
-            //- Check triply (or more) connected edges. Return list of faces
-            //  sharing these edges.
+            //- Check triply (or more) connected edges.
             void checkEdges(const bool verbose);
 
-            //- Check orientation (normals) and normals of neighbouring
-            //  triangles
-            boolList checkOrientation(const bool verbose);
-
             //- Remove non-valid triangles
             void cleanup(const bool verbose);
 
diff --git a/src/turbulenceModels/compressible/RAS/LRR/LRR.C b/src/turbulenceModels/compressible/RAS/LRR/LRR.C
index 6521d8130c401d89f9b526f6497294210b00eb3e..a6588ba17c00bca4df37048b09deef3133bf46b3 100644
--- a/src/turbulenceModels/compressible/RAS/LRR/LRR.C
+++ b/src/turbulenceModels/compressible/RAS/LRR/LRR.C
@@ -337,7 +337,7 @@ void LRR::correct()
     RASModel::correct();
 
     volSymmTensorField P = -twoSymm(R_ & fvc::grad(U_));
-    volScalarField G("G", 0.5*mag(tr(P)));
+    volScalarField G("RASModel::G", 0.5*mag(tr(P)));
 
     // Update espsilon and G at the wall
     epsilon_.boundaryField().updateCoeffs();
diff --git a/src/turbulenceModels/compressible/RAS/LaunderGibsonRSTM/LaunderGibsonRSTM.C b/src/turbulenceModels/compressible/RAS/LaunderGibsonRSTM/LaunderGibsonRSTM.C
index 4a9987131f24f15042be7ef406404fceb7fc31a8..e677d86a50fde3c5659523d82e103c981c8399a9 100644
--- a/src/turbulenceModels/compressible/RAS/LaunderGibsonRSTM/LaunderGibsonRSTM.C
+++ b/src/turbulenceModels/compressible/RAS/LaunderGibsonRSTM/LaunderGibsonRSTM.C
@@ -367,7 +367,7 @@ void LaunderGibsonRSTM::correct()
     }
 
     volSymmTensorField P = -twoSymm(R_ & fvc::grad(U_));
-    volScalarField G("G", 0.5*mag(tr(P)));
+    volScalarField G("RASModel::G", 0.5*mag(tr(P)));
 
     // Update espsilon and G at the wall
     epsilon_.boundaryField().updateCoeffs();
diff --git a/src/turbulenceModels/compressible/RAS/RNGkEpsilon/RNGkEpsilon.C b/src/turbulenceModels/compressible/RAS/RNGkEpsilon/RNGkEpsilon.C
index 3d294ebcebb8764ad1c055faf3e41120e3fae85e..9e50de343fbd104c457cbc95440c1566ef14883a 100644
--- a/src/turbulenceModels/compressible/RAS/RNGkEpsilon/RNGkEpsilon.C
+++ b/src/turbulenceModels/compressible/RAS/RNGkEpsilon/RNGkEpsilon.C
@@ -300,7 +300,7 @@ void RNGkEpsilon::correct()
     volScalarField S2 = (tgradU() && dev(twoSymm(tgradU())));
     tgradU.clear();
 
-    volScalarField G("G", mut_*S2);
+    volScalarField G("RASModel::G", mut_*S2);
 
     volScalarField eta = sqrt(mag(S2))*k_/epsilon_;
     volScalarField eta3 = eta*sqr(eta);
diff --git a/src/turbulenceModels/compressible/RAS/backwardsCompatibilityWallFunctions/backwardsCompatibilityWallFunctions.C b/src/turbulenceModels/compressible/RAS/backwardsCompatibilityWallFunctions/backwardsCompatibilityWallFunctions.C
index c86f2f43ebd8d8fe37894d04543c825b2266313a..657dfbb48e629f38f435eb7cbd6d19f5fe48432b 100644
--- a/src/turbulenceModels/compressible/RAS/backwardsCompatibilityWallFunctions/backwardsCompatibilityWallFunctions.C
+++ b/src/turbulenceModels/compressible/RAS/backwardsCompatibilityWallFunctions/backwardsCompatibilityWallFunctions.C
@@ -64,8 +64,8 @@ tmp<volScalarField> autoCreateAlphat
     }
     else
     {
-        Info<< "--> Upgrading " << fieldName << " to employ run-time "
-            << "selectable wall functions" << endl;
+        Info<< "--> Creating " << fieldName
+            << " to employ run-time selectable wall functions" << endl;
 
         const fvBoundaryMesh& bm = mesh.boundary();
 
@@ -104,7 +104,7 @@ tmp<volScalarField> autoCreateAlphat
             )
         );
 
-        Info<< "    Writing updated " << fieldName << endl;
+        Info<< "    Writing new " << fieldName << endl;
         alphat().write();
 
         return alphat;
@@ -134,8 +134,8 @@ tmp<volScalarField> autoCreateMut
     }
     else
     {
-        Info<< "--> Upgrading " << fieldName << " to employ run-time "
-            << "selectable wall functions" << endl;
+        Info<< "--> Creating " << fieldName
+            << " to employ run-time selectable wall functions" << endl;
 
         const fvBoundaryMesh& bm = mesh.boundary();
 
@@ -174,7 +174,7 @@ tmp<volScalarField> autoCreateMut
             )
         );
 
-        Info<< "    Writing updated " << fieldName << endl;
+        Info<< "    Writing new " << fieldName << endl;
         mut().write();
 
         return mut;
diff --git a/src/turbulenceModels/compressible/RAS/backwardsCompatibilityWallFunctions/backwardsCompatibilityWallFunctionsTemplates.C b/src/turbulenceModels/compressible/RAS/backwardsCompatibilityWallFunctions/backwardsCompatibilityWallFunctionsTemplates.C
index 98c750c71acc40564ea78ce2b0c8b92683280b70..91f739abfb9d6d6624bf3e0a7413dffd58a55eaa 100644
--- a/src/turbulenceModels/compressible/RAS/backwardsCompatibilityWallFunctions/backwardsCompatibilityWallFunctionsTemplates.C
+++ b/src/turbulenceModels/compressible/RAS/backwardsCompatibilityWallFunctions/backwardsCompatibilityWallFunctionsTemplates.C
@@ -26,6 +26,7 @@ License
 
 #include "backwardsCompatibilityWallFunctions.H"
 #include "Time.H"
+#include "OSspecific.H"
 
 #include "wallPolyPatch.H"
 
@@ -77,27 +78,35 @@ autoCreateWallFunctionField
     }
     else
     {
-        Info<< "--> Upgrading " << fieldName << " to employ run-time "
-            << "selectable wall functions" << endl;
+        Info<< "--> Upgrading " << fieldName
+            << " to employ run-time selectable wall functions" << endl;
+
+        // Read existing field
+        IOobject ioObj
+        (
+            fieldName,
+            mesh.time().timeName(),
+            mesh,
+            IOobject::MUST_READ,
+            IOobject::NO_WRITE,
+            false
+        );
 
-        // Read existing epsilon field
         tmp<fieldType> fieldOrig
         (
             new fieldType
             (
-                IOobject
-                (
-                    fieldName,
-                    mesh.time().timeName(),
-                    mesh,
-                    IOobject::MUST_READ,
-                    IOobject::NO_WRITE,
-                    false
-                ),
+                ioObj,
                 mesh
             )
         );
 
+        // rename file
+        Info<< "    Backup original " << fieldName << " to "
+            << fieldName << ".old" << endl;
+        mv(ioObj.objectPath(), ioObj.objectPath() + ".old");
+
+
         PtrList<fvPatchField<Type> > newPatchFields(mesh.boundary().size());
 
         forAll(newPatchFields, patchI)
@@ -145,11 +154,6 @@ autoCreateWallFunctionField
             )
         );
 
-        Info<< "    Writing backup of original " << fieldName << " to "
-            << fieldName << ".old" << endl;
-        fieldOrig().rename(fieldName + ".old");
-        fieldOrig().write();
-
         Info<< "    Writing updated " << fieldName << endl;
         fieldNew().write();
 
diff --git a/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/turbulentHeatFluxTemperature/turbulentHeatFluxTemperatureFvPatchScalarField.H b/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/turbulentHeatFluxTemperature/turbulentHeatFluxTemperatureFvPatchScalarField.H
index 4640acc7db1a4c6fc9446e4751dea16fc6b04bbb..f7581102df9f8d328715b7b295548f2e8d051326 100644
--- a/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/turbulentHeatFluxTemperature/turbulentHeatFluxTemperatureFvPatchScalarField.H
+++ b/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/turbulentHeatFluxTemperature/turbulentHeatFluxTemperatureFvPatchScalarField.H
@@ -66,7 +66,7 @@ class turbulentHeatFluxTemperatureFvPatchScalarField
 public:
 
     //- Runtime type information
-    TypeName("turbulentHeatFluxTemperature");
+    TypeName("compressible::turbulentHeatFluxTemperature");
 
 
     // Constructors
diff --git a/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/turbulentMixingLengthDissipationRateInlet/turbulentMixingLengthDissipationRateInletFvPatchScalarField.H b/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/turbulentMixingLengthDissipationRateInlet/turbulentMixingLengthDissipationRateInletFvPatchScalarField.H
index dcadbdd8b954ee2efcf025bd4926c87d4edc9bc1..1eb669f06b370bff6d9fdcb581beff706899fb42 100644
--- a/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/turbulentMixingLengthDissipationRateInlet/turbulentMixingLengthDissipationRateInletFvPatchScalarField.H
+++ b/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/turbulentMixingLengthDissipationRateInlet/turbulentMixingLengthDissipationRateInletFvPatchScalarField.H
@@ -72,7 +72,7 @@ class turbulentMixingLengthDissipationRateInletFvPatchScalarField
 public:
 
     //- Runtime type information
-    TypeName("turbulentMixingLengthDissipationRateInlet");
+    TypeName("compressible::turbulentMixingLengthDissipationRateInlet");
 
 
     // Constructors
diff --git a/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/turbulentMixingLengthFrequencyInlet/turbulentMixingLengthFrequencyInletFvPatchScalarField.H b/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/turbulentMixingLengthFrequencyInlet/turbulentMixingLengthFrequencyInletFvPatchScalarField.H
index 90d374a33639eab4a5061647632c17e61684affc..45d8d2663c91fb2368d297ba489ecd49c97e2fa9 100644
--- a/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/turbulentMixingLengthFrequencyInlet/turbulentMixingLengthFrequencyInletFvPatchScalarField.H
+++ b/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/turbulentMixingLengthFrequencyInlet/turbulentMixingLengthFrequencyInletFvPatchScalarField.H
@@ -76,7 +76,7 @@ class turbulentMixingLengthFrequencyInletFvPatchScalarField
 public:
 
     //- Runtime type information
-    TypeName("turbulentMixingLengthFrequencyInlet");
+    TypeName("compressible::turbulentMixingLengthFrequencyInlet");
 
 
     // Constructors
diff --git a/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/wallFunctions/alphatWallFunctions/alphatWallFunction/alphatWallFunctionFvPatchScalarField.H b/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/wallFunctions/alphatWallFunctions/alphatWallFunction/alphatWallFunctionFvPatchScalarField.H
index da71e80a2ff15dee2a7edb451153111d4f497b0b..c49a0bc4826377334289fbbfc681906f0abd8ff7 100644
--- a/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/wallFunctions/alphatWallFunctions/alphatWallFunction/alphatWallFunctionFvPatchScalarField.H
+++ b/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/wallFunctions/alphatWallFunctions/alphatWallFunction/alphatWallFunctionFvPatchScalarField.H
@@ -66,7 +66,7 @@ class alphatWallFunctionFvPatchScalarField
 public:
 
     //- Runtime type information
-    TypeName("alphatWallFunction");
+    TypeName("compressible::alphatWallFunction");
 
 
     // Constructors
diff --git a/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/wallFunctions/epsilonWallFunctions/epsilonWallFunction/epsilonWallFunctionFvPatchScalarField.C b/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/wallFunctions/epsilonWallFunctions/epsilonWallFunction/epsilonWallFunctionFvPatchScalarField.C
index 387f54df338b67e36b947ddb9dd634c883c76a88..d7b7547e0ad896e5b342758fcafc72cebc458c02 100644
--- a/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/wallFunctions/epsilonWallFunctions/epsilonWallFunction/epsilonWallFunctionFvPatchScalarField.C
+++ b/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/wallFunctions/epsilonWallFunctions/epsilonWallFunction/epsilonWallFunctionFvPatchScalarField.C
@@ -67,7 +67,7 @@ epsilonWallFunctionFvPatchScalarField::epsilonWallFunctionFvPatchScalarField
     fixedInternalValueFvPatchField<scalar>(p, iF),
     UName_("U"),
     kName_("k"),
-    GName_("G"),
+    GName_("RASModel::G"),
     rhoName_("rho"),
     muName_("mu"),
     mutName_("mut")
@@ -106,7 +106,7 @@ epsilonWallFunctionFvPatchScalarField::epsilonWallFunctionFvPatchScalarField
     fixedInternalValueFvPatchField<scalar>(p, iF, dict),
     UName_(dict.lookupOrDefault<word>("U", "U")),
     kName_(dict.lookupOrDefault<word>("k", "k")),
-    GName_(dict.lookupOrDefault<word>("G", "G")),
+    GName_(dict.lookupOrDefault<word>("G", "RASModel::G")),
     rhoName_(dict.lookupOrDefault<word>("rho", "rho")),
     muName_(dict.lookupOrDefault<word>("mu", "mu")),
     mutName_(dict.lookupOrDefault<word>("mut", "mut"))
@@ -229,7 +229,7 @@ void epsilonWallFunctionFvPatchScalarField::write(Ostream& os) const
     fixedInternalValueFvPatchField<scalar>::write(os);
     writeEntryIfDifferent<word>(os, "U", "U", UName_);
     writeEntryIfDifferent<word>(os, "k", "k", kName_);
-    writeEntryIfDifferent<word>(os, "G", "G", GName_);
+    writeEntryIfDifferent<word>(os, "G", "RASModel::G", GName_);
     writeEntryIfDifferent<word>(os, "rho", "rho", rhoName_);
     writeEntryIfDifferent<word>(os, "mu", "mu", muName_);
     writeEntryIfDifferent<word>(os, "mut", "mut", mutName_);
diff --git a/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/wallFunctions/epsilonWallFunctions/epsilonWallFunction/epsilonWallFunctionFvPatchScalarField.H b/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/wallFunctions/epsilonWallFunctions/epsilonWallFunction/epsilonWallFunctionFvPatchScalarField.H
index 42bdeea6818c8716c2c9fc8e9d8d5a1c5aad2efe..506e9f8c2d693d34fac20302774dfeb31d6c3104 100644
--- a/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/wallFunctions/epsilonWallFunctions/epsilonWallFunction/epsilonWallFunctionFvPatchScalarField.H
+++ b/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/wallFunctions/epsilonWallFunctions/epsilonWallFunction/epsilonWallFunctionFvPatchScalarField.H
@@ -87,7 +87,7 @@ class epsilonWallFunctionFvPatchScalarField
 public:
 
     //- Runtime type information
-    TypeName("epsilonWallFunction");
+    TypeName("compressible::epsilonWallFunction");
 
 
     // Constructors
diff --git a/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/wallFunctions/kQRWallFunctions/kQRWallFunction/kQRWallFunctionFvPatchField.H b/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/wallFunctions/kQRWallFunctions/kQRWallFunction/kQRWallFunctionFvPatchField.H
index 05ed2fbcb81d08f9d21ca1ba104f4649c7057c43..a4a9ddbc30894b2679503131475386d3e4526e39 100644
--- a/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/wallFunctions/kQRWallFunctions/kQRWallFunction/kQRWallFunctionFvPatchField.H
+++ b/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/wallFunctions/kQRWallFunctions/kQRWallFunction/kQRWallFunctionFvPatchField.H
@@ -67,7 +67,7 @@ class kQRWallFunctionFvPatchField
 public:
 
     //- Runtime type information
-    TypeName("kQRWallFunction");
+    TypeName("compressible::kQRWallFunction");
 
 
     // Constructors
diff --git a/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/wallFunctions/omegaWallFunctions/omegaWallFunction/omegaWallFunctionFvPatchScalarField.C b/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/wallFunctions/omegaWallFunctions/omegaWallFunction/omegaWallFunctionFvPatchScalarField.C
index eacf26b1d42a2b81e4bafb52bb11d039dee35f4a..897a8c1162ca26c06eed190859fbdc98da331b81 100644
--- a/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/wallFunctions/omegaWallFunctions/omegaWallFunction/omegaWallFunctionFvPatchScalarField.C
+++ b/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/wallFunctions/omegaWallFunctions/omegaWallFunction/omegaWallFunctionFvPatchScalarField.C
@@ -68,7 +68,7 @@ omegaWallFunctionFvPatchScalarField::omegaWallFunctionFvPatchScalarField
     UName_("U"),
     rhoName_("rho"),
     kName_("k"),
-    GName_("G"),
+    GName_("RASModel::G"),
     muName_("mu"),
     mutName_("mut")
 {
@@ -107,7 +107,7 @@ omegaWallFunctionFvPatchScalarField::omegaWallFunctionFvPatchScalarField
     UName_(dict.lookupOrDefault<word>("U", "U")),
     rhoName_(dict.lookupOrDefault<word>("rho", "rho")),
     kName_(dict.lookupOrDefault<word>("k", "k")),
-    GName_(dict.lookupOrDefault<word>("G", "G")),
+    GName_(dict.lookupOrDefault<word>("G", "RASModel::G")),
     muName_(dict.lookupOrDefault<word>("mu", "mu")),
     mutName_(dict.lookupOrDefault<word>("mut", "mut"))
 {
@@ -221,7 +221,7 @@ void omegaWallFunctionFvPatchScalarField::write(Ostream& os) const
     writeEntryIfDifferent<word>(os, "U", "U", UName_);
     writeEntryIfDifferent<word>(os, "rho", "rho", rhoName_);
     writeEntryIfDifferent<word>(os, "k", "k", kName_);
-    writeEntryIfDifferent<word>(os, "G", "G", GName_);
+    writeEntryIfDifferent<word>(os, "G", "RASModel::G", GName_);
     writeEntryIfDifferent<word>(os, "mu", "mu", muName_);
     writeEntryIfDifferent<word>(os, "mut", "mut", mutName_);
     writeEntry("value", os);
diff --git a/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/wallFunctions/omegaWallFunctions/omegaWallFunction/omegaWallFunctionFvPatchScalarField.H b/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/wallFunctions/omegaWallFunctions/omegaWallFunction/omegaWallFunctionFvPatchScalarField.H
index 6dfe7a772ba574110e3cba1a183fe5d99bd2bc60..675d3a16fbafda9e911c232a9dce8f836d2b8fdb 100644
--- a/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/wallFunctions/omegaWallFunctions/omegaWallFunction/omegaWallFunctionFvPatchScalarField.H
+++ b/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/wallFunctions/omegaWallFunctions/omegaWallFunction/omegaWallFunctionFvPatchScalarField.H
@@ -85,7 +85,7 @@ class omegaWallFunctionFvPatchScalarField
 public:
 
     //- Runtime type information
-    TypeName("omegaWallFunction");
+    TypeName("compressible::omegaWallFunction");
 
 
     // Constructors
diff --git a/src/turbulenceModels/compressible/RAS/kEpsilon/kEpsilon.C b/src/turbulenceModels/compressible/RAS/kEpsilon/kEpsilon.C
index 609ee8300d3dac50ae7dcdf45fe411f9bd28397d..3e076722a2297e9045a5e59fd7a7319cb9e47f6f 100644
--- a/src/turbulenceModels/compressible/RAS/kEpsilon/kEpsilon.C
+++ b/src/turbulenceModels/compressible/RAS/kEpsilon/kEpsilon.C
@@ -278,7 +278,7 @@ void kEpsilon::correct()
     }
 
     tmp<volTensorField> tgradU = fvc::grad(U_);
-    volScalarField G("G", mut_*(tgradU() && dev(twoSymm(tgradU()))));
+    volScalarField G("RASModel::G", mut_*(tgradU() && dev(twoSymm(tgradU()))));
     tgradU.clear();
 
     // Update espsilon and G at the wall
diff --git a/src/turbulenceModels/compressible/RAS/kOmegaSST/kOmegaSST.C b/src/turbulenceModels/compressible/RAS/kOmegaSST/kOmegaSST.C
index 52cfaf2df838c5dd72ed4b5d678d80ccb32be7da..e8a7e06895caa1a987cbe756940b1aeb66a5a124 100644
--- a/src/turbulenceModels/compressible/RAS/kOmegaSST/kOmegaSST.C
+++ b/src/turbulenceModels/compressible/RAS/kOmegaSST/kOmegaSST.C
@@ -381,7 +381,7 @@ void kOmegaSST::correct()
     tmp<volTensorField> tgradU = fvc::grad(U_);
     volScalarField S2 = magSqr(symm(tgradU()));
     volScalarField GbyMu = (tgradU() && dev(twoSymm(tgradU())));
-    volScalarField G("G", mut_*GbyMu);
+    volScalarField G("RASModel::G", mut_*GbyMu);
     tgradU.clear();
 
     // Update omega and G at the wall
diff --git a/src/turbulenceModels/compressible/RAS/realizableKE/realizableKE.C b/src/turbulenceModels/compressible/RAS/realizableKE/realizableKE.C
index d55321fdb44372e9c5c820eab7a8bd3264ee606c..c08516aa2714f73f02f3314f016e8924cde25fec 100644
--- a/src/turbulenceModels/compressible/RAS/realizableKE/realizableKE.C
+++ b/src/turbulenceModels/compressible/RAS/realizableKE/realizableKE.C
@@ -317,7 +317,7 @@ void realizableKE::correct()
     volScalarField eta = magS*k_/epsilon_;
     volScalarField C1 = max(eta/(scalar(5) + eta), scalar(0.43));
 
-    volScalarField G("G", mut_*(gradU && dev(twoSymm(gradU))));
+    volScalarField G("RASModel::G", mut_*(gradU && dev(twoSymm(gradU))));
 
     // Update espsilon and G at the wall
     epsilon_.boundaryField().updateCoeffs();
diff --git a/src/turbulenceModels/incompressible/RAS/LRR/LRR.C b/src/turbulenceModels/incompressible/RAS/LRR/LRR.C
index f720a0312d932dc4a06dfbc94e3909feef52df99..0c361c97ff1cb453d8b2ee0f554efd26d7d88511 100644
--- a/src/turbulenceModels/incompressible/RAS/LRR/LRR.C
+++ b/src/turbulenceModels/incompressible/RAS/LRR/LRR.C
@@ -297,7 +297,7 @@ void LRR::correct()
     }
 
     volSymmTensorField P = -twoSymm(R_ & fvc::grad(U_));
-    volScalarField G("G", 0.5*mag(tr(P)));
+    volScalarField G("RASModel::G", 0.5*mag(tr(P)));
 
     // Update espsilon and G at the wall
     epsilon_.boundaryField().updateCoeffs();
diff --git a/src/turbulenceModels/incompressible/RAS/LaunderGibsonRSTM/LaunderGibsonRSTM.C b/src/turbulenceModels/incompressible/RAS/LaunderGibsonRSTM/LaunderGibsonRSTM.C
index 6f130f2a31256f2c2bc4ef475e6dff780df0c3d0..60f32bf14f07b2dd0dc2c9a594ed33d8057bdfa8 100644
--- a/src/turbulenceModels/incompressible/RAS/LaunderGibsonRSTM/LaunderGibsonRSTM.C
+++ b/src/turbulenceModels/incompressible/RAS/LaunderGibsonRSTM/LaunderGibsonRSTM.C
@@ -329,7 +329,7 @@ void LaunderGibsonRSTM::correct()
     }
 
     volSymmTensorField P = -twoSymm(R_ & fvc::grad(U_));
-    volScalarField G("G", 0.5*mag(tr(P)));
+    volScalarField G("RASModel::G", 0.5*mag(tr(P)));
 
     // Update espsilon and G at the wall
     epsilon_.boundaryField().updateCoeffs();
diff --git a/src/turbulenceModels/incompressible/RAS/LienCubicKE/LienCubicKE.C b/src/turbulenceModels/incompressible/RAS/LienCubicKE/LienCubicKE.C
index bb442dc24093a7ba99294c64083849cfd891f59b..41e6a851b7b8b58bdfc3fdf3e02afe339bc844c1 100644
--- a/src/turbulenceModels/incompressible/RAS/LienCubicKE/LienCubicKE.C
+++ b/src/turbulenceModels/incompressible/RAS/LienCubicKE/LienCubicKE.C
@@ -328,7 +328,7 @@ void LienCubicKE::correct()
 
     volScalarField G
     (
-        "G",
+        "RASModel::G",
         Cmu_*sqr(k_)/epsilon_*S2 - (nonlinearStress_ && gradU_)
     );
 
diff --git a/src/turbulenceModels/incompressible/RAS/RNGkEpsilon/RNGkEpsilon.C b/src/turbulenceModels/incompressible/RAS/RNGkEpsilon/RNGkEpsilon.C
index 6285fb17bf29cf9b8bd8e6af47e78cb77d995c83..533aca878af81e60dc0206b12b097c8e9265807f 100644
--- a/src/turbulenceModels/incompressible/RAS/RNGkEpsilon/RNGkEpsilon.C
+++ b/src/turbulenceModels/incompressible/RAS/RNGkEpsilon/RNGkEpsilon.C
@@ -249,7 +249,7 @@ void RNGkEpsilon::correct()
 
     volScalarField S2 = 2*magSqr(symm(fvc::grad(U_)));
 
-    volScalarField G("G", nut_*S2);
+    volScalarField G("RASModel::G", nut_*S2);
 
     volScalarField eta = sqrt(S2)*k_/epsilon_;
     volScalarField R =
diff --git a/src/turbulenceModels/incompressible/RAS/backwardsCompatibilityWallFunctions/backwardsCompatibilityWallFunctions.C b/src/turbulenceModels/incompressible/RAS/backwardsCompatibilityWallFunctions/backwardsCompatibilityWallFunctions.C
index 949c33472636b63641a0ce01807d380bd9eb2879..f7b144a03b4bdce4890b2d06eaeb83a278a3b402 100644
--- a/src/turbulenceModels/incompressible/RAS/backwardsCompatibilityWallFunctions/backwardsCompatibilityWallFunctions.C
+++ b/src/turbulenceModels/incompressible/RAS/backwardsCompatibilityWallFunctions/backwardsCompatibilityWallFunctions.C
@@ -63,8 +63,8 @@ tmp<volScalarField> autoCreateNut
     }
     else
     {
-        Info<< "--> Upgrading " << fieldName << " to employ run-time "
-            << "selectable wall functions" << endl;
+        Info<< "--> Creating " << fieldName
+            << " to employ run-time selectable wall functions" << endl;
 
         const fvBoundaryMesh& bm = mesh.boundary();
 
@@ -103,7 +103,7 @@ tmp<volScalarField> autoCreateNut
             )
         );
 
-        Info<< "    Writing updated " << fieldName << endl;
+        Info<< "    Writing new " << fieldName << endl;
         nut().write();
 
         return nut;
diff --git a/src/turbulenceModels/incompressible/RAS/backwardsCompatibilityWallFunctions/backwardsCompatibilityWallFunctionsTemplates.C b/src/turbulenceModels/incompressible/RAS/backwardsCompatibilityWallFunctions/backwardsCompatibilityWallFunctionsTemplates.C
index 563f529d619b43adf41b9ee49338b5b851a2781c..10247d493eae3d934035a20af26b8ea493a30b19 100644
--- a/src/turbulenceModels/incompressible/RAS/backwardsCompatibilityWallFunctions/backwardsCompatibilityWallFunctionsTemplates.C
+++ b/src/turbulenceModels/incompressible/RAS/backwardsCompatibilityWallFunctions/backwardsCompatibilityWallFunctionsTemplates.C
@@ -26,6 +26,7 @@ License
 
 #include "backwardsCompatibilityWallFunctions.H"
 #include "Time.H"
+#include "OSspecific.H"
 
 #include "wallPolyPatch.H"
 
@@ -77,27 +78,35 @@ autoCreateWallFunctionField
     }
     else
     {
-        Info<< "--> Upgrading " << fieldName << " to employ run-time "
-            << "selectable wall functions" << endl;
+        Info<< "--> Upgrading " << fieldName
+            << " to employ run-time selectable wall functions" << endl;
+
+        // Read existing field
+        IOobject ioObj
+        (
+            fieldName,
+            mesh.time().timeName(),
+            mesh,
+            IOobject::MUST_READ,
+            IOobject::NO_WRITE,
+            false
+        );
 
-        // Read existing epsilon field
         tmp<fieldType> fieldOrig
         (
             new fieldType
             (
-                IOobject
-                (
-                    fieldName,
-                    mesh.time().timeName(),
-                    mesh,
-                    IOobject::MUST_READ,
-                    IOobject::NO_WRITE,
-                    false
-                ),
+                ioObj,
                 mesh
             )
         );
 
+        // rename file
+        Info<< "    Backup original " << fieldName << " to "
+            << fieldName << ".old" << endl;
+        mv(ioObj.objectPath(), ioObj.objectPath() + ".old");
+
+
         PtrList<fvPatchField<Type> > newPatchFields(mesh.boundary().size());
 
         forAll(newPatchFields, patchI)
@@ -145,11 +154,6 @@ autoCreateWallFunctionField
             )
         );
 
-        Info<< "    Writing backup of original " << fieldName << " to "
-            << fieldName << ".old" << endl;
-        fieldOrig().rename(fieldName + ".old");
-        fieldOrig().write();
-
         Info<< "    Writing updated " << fieldName << endl;
         fieldNew().write();
 
diff --git a/src/turbulenceModels/incompressible/RAS/derivedFvPatchFields/wallFunctions/epsilonWallFunctions/epsilonWallFunction/epsilonWallFunctionFvPatchScalarField.C b/src/turbulenceModels/incompressible/RAS/derivedFvPatchFields/wallFunctions/epsilonWallFunctions/epsilonWallFunction/epsilonWallFunctionFvPatchScalarField.C
index ae8a57c303d3c686212acb5c8f5175c677c9bad2..371d912c8ab00c955c5c214a7ae711bbdf19ddae 100644
--- a/src/turbulenceModels/incompressible/RAS/derivedFvPatchFields/wallFunctions/epsilonWallFunctions/epsilonWallFunction/epsilonWallFunctionFvPatchScalarField.C
+++ b/src/turbulenceModels/incompressible/RAS/derivedFvPatchFields/wallFunctions/epsilonWallFunctions/epsilonWallFunction/epsilonWallFunctionFvPatchScalarField.C
@@ -67,7 +67,7 @@ epsilonWallFunctionFvPatchScalarField::epsilonWallFunctionFvPatchScalarField
     fixedInternalValueFvPatchField<scalar>(p, iF),
     UName_("U"),
     kName_("k"),
-    GName_("G"),
+    GName_("RASModel::G"),
     nuName_("nu"),
     nutName_("nut")
 {
@@ -104,7 +104,7 @@ epsilonWallFunctionFvPatchScalarField::epsilonWallFunctionFvPatchScalarField
     fixedInternalValueFvPatchField<scalar>(p, iF, dict),
     UName_(dict.lookupOrDefault<word>("U", "U")),
     kName_(dict.lookupOrDefault<word>("k", "k")),
-    GName_(dict.lookupOrDefault<word>("G", "G")),
+    GName_(dict.lookupOrDefault<word>("G", "RASModel::G")),
     nuName_(dict.lookupOrDefault<word>("nu", "nu")),
     nutName_(dict.lookupOrDefault<word>("nut", "nut"))
 {
@@ -219,7 +219,7 @@ void epsilonWallFunctionFvPatchScalarField::write(Ostream& os) const
     fixedInternalValueFvPatchField<scalar>::write(os);
     writeEntryIfDifferent<word>(os, "U", "U", UName_);
     writeEntryIfDifferent<word>(os, "k", "k", kName_);
-    writeEntryIfDifferent<word>(os, "G", "G", GName_);
+    writeEntryIfDifferent<word>(os, "G", "RASModel::G", GName_);
     writeEntryIfDifferent<word>(os, "nu", "nu", nuName_);
     writeEntryIfDifferent<word>(os, "nut", "nut", nutName_);
     writeEntry("value", os);
diff --git a/src/turbulenceModels/incompressible/RAS/derivedFvPatchFields/wallFunctions/omegaWallFunctions/omegaWallFunction/omegaWallFunctionFvPatchScalarField.C b/src/turbulenceModels/incompressible/RAS/derivedFvPatchFields/wallFunctions/omegaWallFunctions/omegaWallFunction/omegaWallFunctionFvPatchScalarField.C
index f6a3b6a191fdeeef6fb8de8d729259989d129183..d4351bf243cc22d3358840d6e48181400f741caf 100644
--- a/src/turbulenceModels/incompressible/RAS/derivedFvPatchFields/wallFunctions/omegaWallFunctions/omegaWallFunction/omegaWallFunctionFvPatchScalarField.C
+++ b/src/turbulenceModels/incompressible/RAS/derivedFvPatchFields/wallFunctions/omegaWallFunctions/omegaWallFunction/omegaWallFunctionFvPatchScalarField.C
@@ -67,7 +67,7 @@ omegaWallFunctionFvPatchScalarField::omegaWallFunctionFvPatchScalarField
     fixedInternalValueFvPatchField<scalar>(p, iF),
     UName_("U"),
     kName_("k"),
-    GName_("G"),
+    GName_("RASModel::G"),
     nuName_("nu"),
     nutName_("nut")
 {
@@ -104,7 +104,7 @@ omegaWallFunctionFvPatchScalarField::omegaWallFunctionFvPatchScalarField
     fixedInternalValueFvPatchField<scalar>(p, iF, dict),
     UName_(dict.lookupOrDefault<word>("U", "U")),
     kName_(dict.lookupOrDefault<word>("k", "k")),
-    GName_(dict.lookupOrDefault<word>("G", "G")),
+    GName_(dict.lookupOrDefault<word>("G", "RASModel::G")),
     nuName_(dict.lookupOrDefault<word>("nu", "nu")),
     nutName_(dict.lookupOrDefault<word>("nut", "nut"))
 {
@@ -210,7 +210,7 @@ void omegaWallFunctionFvPatchScalarField::write(Ostream& os) const
     fixedInternalValueFvPatchField<scalar>::write(os);
     writeEntryIfDifferent<word>(os, "U", "U", UName_);
     writeEntryIfDifferent<word>(os, "k", "k", kName_);
-    writeEntryIfDifferent<word>(os, "G", "G", GName_);
+    writeEntryIfDifferent<word>(os, "G", "RASModel::G", GName_);
     writeEntryIfDifferent<word>(os, "nu", "nu", nuName_);
     writeEntryIfDifferent<word>(os, "nut", "nut", nutName_);
     writeEntry("value", os);
diff --git a/src/turbulenceModels/incompressible/RAS/kEpsilon/kEpsilon.C b/src/turbulenceModels/incompressible/RAS/kEpsilon/kEpsilon.C
index a5953a4cb7df244fcd042a1b21f31187bfd61b27..1f65b2d2ba8386073a30c8e82274e626b582a709 100644
--- a/src/turbulenceModels/incompressible/RAS/kEpsilon/kEpsilon.C
+++ b/src/turbulenceModels/incompressible/RAS/kEpsilon/kEpsilon.C
@@ -129,7 +129,7 @@ kEpsilon::kEpsilon
         autoCreateNut("nut", mesh_)
     )
 {
-    nut_ == Cmu_*sqr(k_)/(epsilon_ + epsilonSmall_);
+    nut_ = Cmu_*sqr(k_)/(epsilon_ + epsilonSmall_);
     nut_.correctBoundaryConditions();
 
     printCoeffs();
@@ -216,7 +216,7 @@ void kEpsilon::correct()
         return;
     }
 
-    volScalarField G("G", nut_*2*magSqr(symm(fvc::grad(U_))));
+    volScalarField G("RASModel::G", nut_*2*magSqr(symm(fvc::grad(U_))));
 
     // Update espsilon and G at the wall
     epsilon_.boundaryField().updateCoeffs();
@@ -259,7 +259,7 @@ void kEpsilon::correct()
 
 
     // Re-calculate viscosity
-    nut_ == Cmu_*sqr(k_)/epsilon_;
+    nut_ = Cmu_*sqr(k_)/epsilon_;
     nut_.correctBoundaryConditions();
 }
 
diff --git a/src/turbulenceModels/incompressible/RAS/kOmega/kOmega.C b/src/turbulenceModels/incompressible/RAS/kOmega/kOmega.C
index a45ff8c33b1594741ab0d0c61fefd967fe5655b1..d29291885a61ad8de82ee3486bea86e7e8646e5d 100644
--- a/src/turbulenceModels/incompressible/RAS/kOmega/kOmega.C
+++ b/src/turbulenceModels/incompressible/RAS/kOmega/kOmega.C
@@ -225,7 +225,7 @@ void kOmega::correct()
         return;
     }
 
-    volScalarField G("G", nut_*2*magSqr(symm(fvc::grad(U_))));
+    volScalarField G("RASModel::G", nut_*2*magSqr(symm(fvc::grad(U_))));
 
     // Update omega and G at the wall
     omega_.boundaryField().updateCoeffs();
diff --git a/src/turbulenceModels/incompressible/RAS/kOmegaSST/kOmegaSST.C b/src/turbulenceModels/incompressible/RAS/kOmegaSST/kOmegaSST.C
index 6a737fce49fb5b4c1cb41f39818d314fa5ed4ad7..2ae7d8be6a970ca7ec78bce42832d50dc29af79f 100644
--- a/src/turbulenceModels/incompressible/RAS/kOmegaSST/kOmegaSST.C
+++ b/src/turbulenceModels/incompressible/RAS/kOmegaSST/kOmegaSST.C
@@ -343,7 +343,7 @@ void kOmegaSST::correct()
     }
 
     volScalarField S2 = magSqr(symm(fvc::grad(U_)));
-    volScalarField G("G", nut_*2*S2);
+    volScalarField G("RASModel::G", nut_*2*S2);
 
     // Update omega and G at the wall
     omega_.boundaryField().updateCoeffs();
diff --git a/src/turbulenceModels/incompressible/RAS/realizableKE/realizableKE.C b/src/turbulenceModels/incompressible/RAS/realizableKE/realizableKE.C
index 2f70b0ed2a7303ce422b878b8b5c29a877152142..d92a765ee2191751fd6415952a9f12884b936488 100644
--- a/src/turbulenceModels/incompressible/RAS/realizableKE/realizableKE.C
+++ b/src/turbulenceModels/incompressible/RAS/realizableKE/realizableKE.C
@@ -277,7 +277,7 @@ void realizableKE::correct()
     volScalarField eta = magS*k_/epsilon_;
     volScalarField C1 = max(eta/(scalar(5) + eta), scalar(0.43));
 
-    volScalarField G("G", nut_*S2);
+    volScalarField G("RASModel::G", nut_*S2);
 
     // Update espsilon and G at the wall
     epsilon_.boundaryField().updateCoeffs();
diff --git a/tutorials/compressible/rhoPisoFoam/ras/cavity/constant/polyMesh/boundary b/tutorials/compressible/rhoPisoFoam/ras/cavity/constant/polyMesh/boundary
index 52f27af65188a35fc12861a6314b2cbe72d660d5..61feadd97403fbf58a57c925fc262f3de46ec95a 100644
--- a/tutorials/compressible/rhoPisoFoam/ras/cavity/constant/polyMesh/boundary
+++ b/tutorials/compressible/rhoPisoFoam/ras/cavity/constant/polyMesh/boundary
@@ -1,8 +1,8 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  1.5                                   |
-|   \\  /    A nd           | Web:      http://www.OpenFOAM.org               |
+|  \\    /   O peration     | Version:  dev                                   |
+|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
 FoamFile
@@ -10,32 +10,31 @@ FoamFile
     version     2.0;
     format      ascii;
     class       polyBoundaryMesh;
+    location    "constant/polyMesh";
     object      boundary;
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 3
 (
-movingWall
-{
-    type wall;
-    nFaces 20;
-    startFace 760;
-}
-
-fixedWalls
-{
-    type wall;
-    nFaces 60;
-    startFace 780;
-}
-
-frontAndBack
-{
-    type empty;
-    nFaces 800;
-    startFace 840;
-}
+    movingWall
+    {
+        type            wall;
+        nFaces          20;
+        startFace       760;
+    }
+    fixedWalls
+    {
+        type            wall;
+        nFaces          60;
+        startFace       780;
+    }
+    frontAndBack
+    {
+        type            empty;
+        nFaces          800;
+        startFace       840;
+    }
 )
 
 // ************************************************************************* //
diff --git a/tutorials/heatTransfer/buoyantPisoFoam/hotRoom/0/epsilon b/tutorials/heatTransfer/buoyantPisoFoam/hotRoom/0/epsilon
index 471f122da8e2a81955aac14f408a0fec3c7c19f7..23851291dc60d3b0df3be887acfbeb0bb5067ef8 100644
--- a/tutorials/heatTransfer/buoyantPisoFoam/hotRoom/0/epsilon
+++ b/tutorials/heatTransfer/buoyantPisoFoam/hotRoom/0/epsilon
@@ -15,7 +15,7 @@ FoamFile
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-dimensions      [ 0 2 -3 0 0 0 0 ];
+dimensions      [0 2 -3 0 0 0 0];
 
 internalField   uniform 0.01;
 
@@ -23,20 +23,18 @@ boundaryField
 {
     floor
     {
-        type            epsilonWallFunction;
-        value           uniform 0;
+        type            compressible::epsilonWallFunction;
+        value           uniform 0.01;
     }
-
     ceiling
     {
-        type            epsilonWallFunction;
-        value           uniform 0;
+        type            compressible::epsilonWallFunction;
+        value           uniform 0.01;
     }
-
     fixedWalls
     {
-        type            epsilonWallFunction;
-        value           uniform 0;
+        type            compressible::epsilonWallFunction;
+        value           uniform 0.01;
     }
 }
 
diff --git a/tutorials/heatTransfer/buoyantPisoFoam/hotRoom/0/k b/tutorials/heatTransfer/buoyantPisoFoam/hotRoom/0/k
index e0c92b9c4f9463d1f90ff2ef32188125d092c301..4ec7f08960c175a6d955e2c1d3cfb98453524647 100644
--- a/tutorials/heatTransfer/buoyantPisoFoam/hotRoom/0/k
+++ b/tutorials/heatTransfer/buoyantPisoFoam/hotRoom/0/k
@@ -15,7 +15,7 @@ FoamFile
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-dimensions      [ 0 2 -2 0 0 0 0 ];
+dimensions      [0 2 -2 0 0 0 0];
 
 internalField   uniform 0.1;
 
@@ -23,20 +23,18 @@ boundaryField
 {
     floor
     {
-        type            kQRWallFunction;
-        value           uniform 0;
+        type            compressible::kQRWallFunction;
+        value           uniform 0.1;
     }
-
     ceiling
     {
-        type            kQRWallFunction;
-        value           uniform 0;
+        type            compressible::kQRWallFunction;
+        value           uniform 0.1;
     }
-
     fixedWalls
     {
-        type            kQRWallFunction;
-        value           uniform 0;
+        type            compressible::kQRWallFunction;
+        value           uniform 0.1;
     }
 }
 
diff --git a/tutorials/heatTransfer/buoyantPisoFoam/hotRoom/0/mut b/tutorials/heatTransfer/buoyantPisoFoam/hotRoom/0/mut
deleted file mode 100644
index f78d7659f90151e17c9011c88f9c96806ca7bcaf..0000000000000000000000000000000000000000
--- a/tutorials/heatTransfer/buoyantPisoFoam/hotRoom/0/mut
+++ /dev/null
@@ -1,44 +0,0 @@
-/*--------------------------------*- C++ -*----------------------------------*\
-| =========                 |                                                 |
-| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  dev                                   |
-|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
-|    \\/     M anipulation  |                                                 |
-\*---------------------------------------------------------------------------*/
-FoamFile
-{
-    version     2.0;
-    format      ascii;
-    class       volScalarField;
-    location    "0";
-    object      mut;
-}
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-dimensions      [ 1 -1 -1 0 0 0 0 ];
-
-internalField   uniform 0;
-
-boundaryField
-{
-    floor
-    {
-        type            mutWallFunction;
-        value           uniform 0;
-    }
-
-    ceiling
-    {
-        type            mutWallFunction;
-        value           uniform 0;
-    }
-
-    fixedWalls
-    {
-        type            mutWallFunction;
-        value           uniform 0;
-    }
-}
-
-
-// ************************************************************************* //
diff --git a/tutorials/heatTransfer/buoyantPisoFoam/hotRoom/constant/polyMesh/boundary b/tutorials/heatTransfer/buoyantPisoFoam/hotRoom/constant/polyMesh/boundary
index 713344455a1a29c3cccb21bfcfb43f423eaa5cf3..0d4d0e498dae524c835cc1addc9707eb5af47fb3 100644
--- a/tutorials/heatTransfer/buoyantPisoFoam/hotRoom/constant/polyMesh/boundary
+++ b/tutorials/heatTransfer/buoyantPisoFoam/hotRoom/constant/polyMesh/boundary
@@ -1,8 +1,8 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  1.5                                   |
-|   \\  /    A nd           | Web:      http://www.OpenFOAM.org               |
+|  \\    /   O peration     | Version:  dev                                   |
+|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
 FoamFile
@@ -10,6 +10,7 @@ FoamFile
     version     2.0;
     format      ascii;
     class       polyBoundaryMesh;
+    location    "constant/polyMesh";
     object      boundary;
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
diff --git a/tutorials/heatTransfer/buoyantPisoFoam/hotRoom/system/controlDict b/tutorials/heatTransfer/buoyantPisoFoam/hotRoom/system/controlDict
index f413425423be7e5cce874661512daa4f490ec0fb..cb2e7470f67597540554a58b19942872bab68d34 100644
--- a/tutorials/heatTransfer/buoyantPisoFoam/hotRoom/system/controlDict
+++ b/tutorials/heatTransfer/buoyantPisoFoam/hotRoom/system/controlDict
@@ -43,5 +43,8 @@ timePrecision   6;
 
 runTimeModifiable yes;
 
+adjustTimeStep  no;
+
+maxCo           0.5;
 
 // ************************************************************************* //
diff --git a/tutorials/heatTransfer/buoyantPisoFoam/hotRoom/system/fvSchemes b/tutorials/heatTransfer/buoyantPisoFoam/hotRoom/system/fvSchemes
index 1006ba6d1fa7c94161a12979af2b5fd49da985f5..583bf08e11cb06903ecea9b68ba94a197d2ebed3 100644
--- a/tutorials/heatTransfer/buoyantPisoFoam/hotRoom/system/fvSchemes
+++ b/tutorials/heatTransfer/buoyantPisoFoam/hotRoom/system/fvSchemes
@@ -33,6 +33,7 @@ divSchemes
     div(phi,k)      Gauss upwind;
     div(phi,epsilon) Gauss upwind;
     div(phi,R)      Gauss upwind;
+    div(phiU,p)     Gauss linear;
     div(R)          Gauss linear;
     div((muEff*dev2(grad(U).T()))) Gauss linear;
 }
diff --git a/tutorials/heatTransfer/buoyantSimpleFoam/hotRoom/0/epsilon b/tutorials/heatTransfer/buoyantSimpleFoam/hotRoom/0/epsilon
index fcda1ad91f0555e9302263cb3bc42b7e70960b7a..23851291dc60d3b0df3be887acfbeb0bb5067ef8 100644
--- a/tutorials/heatTransfer/buoyantSimpleFoam/hotRoom/0/epsilon
+++ b/tutorials/heatTransfer/buoyantSimpleFoam/hotRoom/0/epsilon
@@ -1,8 +1,8 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  1.5                                   |
-|   \\  /    A nd           | Web:      http://www.OpenFOAM.org               |
+|  \\    /   O peration     | Version:  dev                                   |
+|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
 FoamFile
@@ -23,17 +23,17 @@ boundaryField
 {
     floor
     {
-        type            epsilonWallFunction;
+        type            compressible::epsilonWallFunction;
         value           uniform 0.01;
     }
     ceiling
     {
-        type            epsilonWallFunction;
+        type            compressible::epsilonWallFunction;
         value           uniform 0.01;
     }
     fixedWalls
     {
-        type            epsilonWallFunction;
+        type            compressible::epsilonWallFunction;
         value           uniform 0.01;
     }
 }
diff --git a/tutorials/heatTransfer/buoyantSimpleFoam/hotRoom/0/k b/tutorials/heatTransfer/buoyantSimpleFoam/hotRoom/0/k
index 93cd1e0334ff778d059a5d6c43fef6b118f39d18..4ec7f08960c175a6d955e2c1d3cfb98453524647 100644
--- a/tutorials/heatTransfer/buoyantSimpleFoam/hotRoom/0/k
+++ b/tutorials/heatTransfer/buoyantSimpleFoam/hotRoom/0/k
@@ -1,8 +1,8 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  1.5                                   |
-|   \\  /    A nd           | Web:      http://www.OpenFOAM.org               |
+|  \\    /   O peration     | Version:  dev                                   |
+|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
 FoamFile
@@ -23,17 +23,17 @@ boundaryField
 {
     floor
     {
-        type            kQRWallFunction;
+        type            compressible::kQRWallFunction;
         value           uniform 0.1;
     }
     ceiling
     {
-        type            kQRWallFunction;
+        type            compressible::kQRWallFunction;
         value           uniform 0.1;
     }
     fixedWalls
     {
-        type            kQRWallFunction;
+        type            compressible::kQRWallFunction;
         value           uniform 0.1;
     }
 }
diff --git a/tutorials/heatTransfer/buoyantSimpleFoam/hotRoom/0/mut b/tutorials/heatTransfer/buoyantSimpleFoam/hotRoom/0/mut
deleted file mode 100644
index fca37fcb40bdec040dd0e57f6fecaebe4c58562c..0000000000000000000000000000000000000000
--- a/tutorials/heatTransfer/buoyantSimpleFoam/hotRoom/0/mut
+++ /dev/null
@@ -1,42 +0,0 @@
-/*--------------------------------*- 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       volScalarField;
-    location    "0";
-    object      mut;
-}
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-dimensions      [1 -1 -1 0 0 0 0];
-
-internalField   uniform 0;
-
-boundaryField
-{
-    floor
-    {
-        type            mutWallFunction;
-        value           uniform 0;
-    }
-    ceiling
-    {
-        type            mutWallFunction;
-        value           uniform 0;
-    }
-    fixedWalls
-    {
-        type            mutWallFunction;
-        value           uniform 0;
-    }
-}
-
-
-// ************************************************************************* //
diff --git a/tutorials/heatTransfer/buoyantSimpleFoam/hotRoom/Allrun b/tutorials/heatTransfer/buoyantSimpleFoam/hotRoom/Allrun
index 0b8cae611d1d464cf8e766070789a9444e0cb4af..6a98e5715d655d25f6569da8915ed83d6d3cbbb1 100755
--- a/tutorials/heatTransfer/buoyantSimpleFoam/hotRoom/Allrun
+++ b/tutorials/heatTransfer/buoyantSimpleFoam/hotRoom/Allrun
@@ -4,7 +4,7 @@
 
 application="buoyantSimpleFoam"
 
-compileApplication ../../buoyantFoam/hotRoom/setHotRoom
+compileApplication ../../buoyantPisoFoam/hotRoom/setHotRoom
 runApplication blockMesh
 runApplication setHotRoom
 runApplication $application
diff --git a/tutorials/heatTransfer/buoyantSimpleFoam/hotRoom/constant/polyMesh/boundary b/tutorials/heatTransfer/buoyantSimpleFoam/hotRoom/constant/polyMesh/boundary
index d0eb52935f2b14b9b94f41a477063f46188ccf5f..0d4d0e498dae524c835cc1addc9707eb5af47fb3 100644
--- a/tutorials/heatTransfer/buoyantSimpleFoam/hotRoom/constant/polyMesh/boundary
+++ b/tutorials/heatTransfer/buoyantSimpleFoam/hotRoom/constant/polyMesh/boundary
@@ -1,8 +1,8 @@
 /*--------------------------------*- C++ -*----------------------------------*\
 | =========                 |                                                 |
 | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  1.5                                   |
-|   \\  /    A nd           | Web:      http://www.OpenFOAM.org               |
+|  \\    /   O peration     | Version:  dev                                   |
+|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
 |    \\/     M anipulation  |                                                 |
 \*---------------------------------------------------------------------------*/
 FoamFile
diff --git a/tutorials/heatTransfer/buoyantSimpleRadiationFoam/hotRadiationRoom/0/mut b/tutorials/heatTransfer/buoyantSimpleRadiationFoam/hotRadiationRoom/0/mut
deleted file mode 100644
index c609cbf3d2c865212d20992980a9b59a349b9c68..0000000000000000000000000000000000000000
--- a/tutorials/heatTransfer/buoyantSimpleRadiationFoam/hotRadiationRoom/0/mut
+++ /dev/null
@@ -1,50 +0,0 @@
-/*--------------------------------*- C++ -*----------------------------------*\
-| =========                 |                                                 |
-| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  dev                                   |
-|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
-|    \\/     M anipulation  |                                                 |
-\*---------------------------------------------------------------------------*/
-FoamFile
-{
-    version     2.0;
-    format      ascii;
-    class       volScalarField;
-    location    "0";
-    object      mut;
-}
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-dimensions      [ 1 -1 -1 0 0 0 0 ];
-
-internalField   uniform 0;
-
-boundaryField
-{
-    box
-    {
-        type            mutWallFunction;
-        value           uniform 0;
-    }
-
-    floor
-    {
-        type            mutWallFunction;
-        value           uniform 0;
-    }
-
-    ceiling
-    {
-        type            mutWallFunction;
-        value           uniform 0;
-    }
-
-    fixedWalls
-    {
-        type            mutWallFunction;
-        value           uniform 0;
-    }
-}
-
-
-// ************************************************************************* //
diff --git a/tutorials/heatTransfer/chtMultiRegionFoam/multiRegionHeater/0/alphat b/tutorials/heatTransfer/chtMultiRegionFoam/multiRegionHeater/0/alphat
index 3a5286b6dbfcffb06d6a45c99fe29429f6cba062..c90550f0b844a0a1a91c867c22d704ee1f4f5c81 100644
--- a/tutorials/heatTransfer/chtMultiRegionFoam/multiRegionHeater/0/alphat
+++ b/tutorials/heatTransfer/chtMultiRegionFoam/multiRegionHeater/0/alphat
@@ -21,6 +21,11 @@ internalField   uniform 0;
 
 boundaryField
 {
+    minY
+    {
+        type            alphatWallFunction;
+        value           uniform 0;
+    }
     maxY
     {
         type            alphatWallFunction;
diff --git a/tutorials/heatTransfer/chtMultiRegionFoam/multiRegionHeater/0/epsilon b/tutorials/heatTransfer/chtMultiRegionFoam/multiRegionHeater/0/epsilon
index bb298dd95dd506ba55c7acde5da6e7a1b8f41bcb..c72b3362c06b88dfd24cd8b3a9be926742fc5057 100644
--- a/tutorials/heatTransfer/chtMultiRegionFoam/multiRegionHeater/0/epsilon
+++ b/tutorials/heatTransfer/chtMultiRegionFoam/multiRegionHeater/0/epsilon
@@ -21,6 +21,11 @@ internalField   uniform 0.01;
 
 boundaryField
 {
+    minY
+    {
+        type            epsilonWallFunction;
+        value           uniform 0.01;
+    }
     maxY
     {
         type            epsilonWallFunction;
diff --git a/tutorials/heatTransfer/chtMultiRegionFoam/multiRegionHeater/0/k b/tutorials/heatTransfer/chtMultiRegionFoam/multiRegionHeater/0/k
index e4db2c837d0bd8d76ad06e085cf27900d8308e9e..49df1e0d2bbc086f04854475877bdd9fe4b596ee 100644
--- a/tutorials/heatTransfer/chtMultiRegionFoam/multiRegionHeater/0/k
+++ b/tutorials/heatTransfer/chtMultiRegionFoam/multiRegionHeater/0/k
@@ -21,6 +21,11 @@ internalField   uniform 0.1;
 
 boundaryField
 {
+    minY
+    {
+        type            kQRWallFunction;
+        value           uniform 0.1;
+    }
     maxY
     {
         type            kQRWallFunction;
diff --git a/tutorials/heatTransfer/chtMultiRegionFoam/multiRegionHeater/0/mut b/tutorials/heatTransfer/chtMultiRegionFoam/multiRegionHeater/0/mut
deleted file mode 100644
index ece854fd06176af32e1d06503c0c3461c1a3b77c..0000000000000000000000000000000000000000
--- a/tutorials/heatTransfer/chtMultiRegionFoam/multiRegionHeater/0/mut
+++ /dev/null
@@ -1,67 +0,0 @@
-/*--------------------------------*- C++ -*----------------------------------*\
-| =========                 |                                                 |
-| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
-|  \\    /   O peration     | Version:  dev                                   |
-|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
-|    \\/     M anipulation  |                                                 |
-\*---------------------------------------------------------------------------*/
-FoamFile
-{
-    version     2.0;
-    format      ascii;
-    class       volScalarField;
-    location    "0.001";
-    object      mut;
-}
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-dimensions      [1 -1 -1 0 0 0 0];
-
-internalField   uniform 0;
-
-boundaryField
-{
-    maxY
-    {
-        type            mutWallFunction;
-        value           uniform 0;
-    }
-    minX
-    {
-        type            calculated;
-        value           uniform 0;
-    }
-    maxX
-    {
-        type            calculated;
-        value           uniform 0;
-    }
-    minZ
-    {
-        type            mutWallFunction;
-        value           uniform 0;
-    }
-    maxZ
-    {
-        type            mutWallFunction;
-        value           uniform 0;
-    }
-    topAir_to_leftSolid
-    {
-        type            calculated;
-        value           uniform 0;
-    }
-    topAir_to_heater
-    {
-        type            calculated;
-        value           uniform 0;
-    }
-    topAir_to_rightSolid
-    {
-        type            calculated;
-        value           uniform 0;
-    }
-}
-
-
-// ************************************************************************* //
diff --git a/tutorials/heatTransfer/chtMultiRegionFoam/multiRegionHeater/system/bottomAir/fvSolution b/tutorials/heatTransfer/chtMultiRegionFoam/multiRegionHeater/system/bottomAir/fvSolution
index b4f773aaa4b412012acf405c551618a62bdbf9d6..84839fe0ac905869edce0e444073487c84f3c61e 100644
--- a/tutorials/heatTransfer/chtMultiRegionFoam/multiRegionHeater/system/bottomAir/fvSolution
+++ b/tutorials/heatTransfer/chtMultiRegionFoam/multiRegionHeater/system/bottomAir/fvSolution
@@ -16,26 +16,30 @@ FoamFile
 
 solvers
 {
-    rho PCG
+    rho
     {
-        preconditioner   DIC;
-        tolerance        1e-6;
-        relTol           0;
+        solver          PCG
+        preconditioner  DIC;
+        tolerance       1e-6;
+        relTol          0;
     };
-//    pd PCG
+//    pd
 //    {
+//        solver           PCG
 //        preconditioner   DIC;
 //        tolerance        1e-6;
 //        relTol           0.1;
 //    };
-//    pdFinal PCG
+//    pdFinal
 //    {
+//        solver           PCG;
 //        preconditioner   DIC;
 //        tolerance        1e-08;
 //        relTol           0;
 //    };
-    pd GAMG
+    pd
     {
+        solver           GAMG;
         tolerance        1e-6;
         relTol           0.1;
 
@@ -46,8 +50,9 @@ solvers
         agglomerator     faceAreaPair;
         mergeLevels      1;
     };
-    pdFinal GAMG
+    pdFinal
     {
+        solver           GAMG;
         tolerance        1e-6;
         relTol           0;
 
@@ -58,32 +63,37 @@ solvers
         agglomerator     faceAreaPair;
         mergeLevels      1;
     };
-    U PBiCG
+    U
     {
+        solver           PBiCG;
         preconditioner   DILU;
         tolerance        1e-08;
         relTol           0;
     };
-    h PBiCG
+    h
     {
+        solver           PBiCG;
         preconditioner   DILU;
         tolerance        1e-06;
         relTol           0;
     };
-    k PBiCG
+    k
     {
+        solver           PBiCG;
         preconditioner   DILU;
         tolerance        1e-06;
         relTol           0;
     };
-    epsilon PBiCG
+    epsilon
     {
+        solver           PBiCG;
         preconditioner   DILU;
         tolerance        1e-06;
         relTol           0;
     };
-    R PBiCG
+    R
     {
+        solver           PBiCG;
         preconditioner   DILU;
         tolerance        1e-06;
         relTol           0;
diff --git a/tutorials/heatTransfer/chtMultiRegionFoam/multiRegionHeater/system/fvSchemes b/tutorials/heatTransfer/chtMultiRegionFoam/multiRegionHeater/system/fvSchemes
index e8078b2b209d98dacf01c6263cf26202d00cd1e8..4c5f890224ae9fc5c14ce322600ab186c3d05c72 100644
--- a/tutorials/heatTransfer/chtMultiRegionFoam/multiRegionHeater/system/fvSchemes
+++ b/tutorials/heatTransfer/chtMultiRegionFoam/multiRegionHeater/system/fvSchemes
@@ -14,5 +14,33 @@ FoamFile
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
+ddtSchemes
+{
+}
+
+gradSchemes
+{
+}
+
+divSchemes
+{
+}
+
+laplacianSchemes
+{
+}
+
+interpolationSchemes
+{
+}
+
+snGradSchemes
+{
+}
+
+fluxRequired
+{
+}
+
 
 // ************************************************************************* //
diff --git a/tutorials/heatTransfer/chtMultiRegionFoam/multiRegionHeater/system/heater/fvSolution b/tutorials/heatTransfer/chtMultiRegionFoam/multiRegionHeater/system/heater/fvSolution
index e1bc5f8416d0c16cb569690f3e11f6f376062c35..d1c768d4d4444eb6e1937e1840ddde4a19096376 100644
--- a/tutorials/heatTransfer/chtMultiRegionFoam/multiRegionHeater/system/heater/fvSolution
+++ b/tutorials/heatTransfer/chtMultiRegionFoam/multiRegionHeater/system/heater/fvSolution
@@ -16,8 +16,9 @@ FoamFile
 
 solvers
 {
-    T PCG
+    T
     {
+        solver           PCG;
         preconditioner   DIC;
         tolerance        1E-06;
         relTol           0;
diff --git a/tutorials/incompressible/pisoFoam/les/pitzDailyDirectMapped/constant/polyMesh/boundary b/tutorials/incompressible/pisoFoam/les/pitzDailyDirectMapped/constant/polyMesh/boundary
index 0b56bb9f5e8be426cd22b962d4b254728ac55ab7..4530c7b820cd84a5d66dfda299ca4ac6620a2c8b 100644
--- a/tutorials/incompressible/pisoFoam/les/pitzDailyDirectMapped/constant/polyMesh/boundary
+++ b/tutorials/incompressible/pisoFoam/les/pitzDailyDirectMapped/constant/polyMesh/boundary
@@ -20,7 +20,7 @@ FoamFile
 (
 inlet
 {
-    type            directMappedPatch;
+    type            directMapped;
     nFaces          30;
     startFace       27238;
     sampleMode      nearestCell;
diff --git a/tutorials/incompressible/pisoFoam/les/pitzDailyDirectMapped/system/changeDictionaryDict b/tutorials/incompressible/pisoFoam/les/pitzDailyDirectMapped/system/changeDictionaryDict
index 9490b8433231b6579abeff8ee805e39857951c3b..5a186d193ec03ee6ba5eda0a643e7ec85c3e4163 100644
--- a/tutorials/incompressible/pisoFoam/les/pitzDailyDirectMapped/system/changeDictionaryDict
+++ b/tutorials/incompressible/pisoFoam/les/pitzDailyDirectMapped/system/changeDictionaryDict
@@ -23,6 +23,7 @@ dictionaryReplacement
         {
             type            directMappedPatch;
             offset          ( 0.0495 0 0 );
+            sampleRegion    region0;
             sampleMode      nearestCell;
             samplePatch     none;
         }
diff --git a/tutorials/mesh/snappyHexMesh/iglooWithFridges/constant/triSurface/fridgeA.eMesh b/tutorials/mesh/snappyHexMesh/iglooWithFridges/constant/triSurface/fridgeA.eMesh
new file mode 100644
index 0000000000000000000000000000000000000000..ff7aab4b8f14cabed8622a7ddcb1e4ec2b635b2f
--- /dev/null
+++ b/tutorials/mesh/snappyHexMesh/iglooWithFridges/constant/triSurface/fridgeA.eMesh
@@ -0,0 +1,58 @@
+/*---------------------------------------------------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  1.3.1                                 |
+|   \\  /    A nd           | Web:      http://www.openfoam.org               |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+
+FoamFile
+{
+    version 2.0;
+    format ascii;
+
+    root "..";
+    case "cavity";
+    instance ""constant"";
+    local "polyMesh";
+
+    class featureEdgeMesh;
+    object points;
+}
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+// Points
+(
+(1.99 1.99 0.01)     //0
+(3.01 1.99 0.01)     //1
+(3.01 3.01 0.01)     //2
+(1.99 3.01 0.01)     //3
+
+(1.99 1.99 2.01)     //4
+(3.01 1.99 2.01)     //5
+(3.01 3.01 2.01)     //6
+(1.99 3.01 2.01)     //7
+)
+
+// Edges
+(
+(0 1)
+(1 2)
+(2 3)
+(3 0)
+
+(4 5)
+(5 6)
+(6 7)
+(7 4)
+
+(0 4)
+(1 5)
+(2 6)
+(3 7)
+)
+
+
+
+// ************************************************************************* //
diff --git a/tutorials/mesh/snappyHexMesh/iglooWithFridges/system/snappyHexMeshDict b/tutorials/mesh/snappyHexMesh/iglooWithFridges/system/snappyHexMeshDict
index 19ef2afec1d08e169d49fd7907cc518d0eccd94b..be30045c6d4d77a2bf014349a0e4890ff5d963bd 100644
--- a/tutorials/mesh/snappyHexMesh/iglooWithFridges/system/snappyHexMeshDict
+++ b/tutorials/mesh/snappyHexMesh/iglooWithFridges/system/snappyHexMeshDict
@@ -143,10 +143,10 @@ castellatedMeshControls
     // This is a featureEdgeMesh, read from constant/triSurface for now.
     features
     (
-//        {
-//            file "fridgeA.eMesh";
-//            level 3;
-//        }
+        {
+            file "fridgeA.eMesh";
+            level 3;
+        }
     );
 
 
@@ -308,6 +308,10 @@ addLayersControls
 
     // Create buffer region for new layer terminations
     nBufferCellsNoExtrude 0;
+
+
+    // Overall max number of layer addition iterations
+    nLayerIter 50;
 }
 
 
diff --git a/tutorials/mesh/snappyHexMesh/motorBike/system/snappyHexMeshDict b/tutorials/mesh/snappyHexMesh/motorBike/system/snappyHexMeshDict
index 3f0ff0417e6b92047878cb285aa71452c8fd3c74..0d84177d8b422d750ef38dbf1536c4ba8383c6dc 100644
--- a/tutorials/mesh/snappyHexMesh/motorBike/system/snappyHexMeshDict
+++ b/tutorials/mesh/snappyHexMesh/motorBike/system/snappyHexMeshDict
@@ -160,7 +160,7 @@ snapControls
     //- Relative distance for points to be attracted by surface feature point
     //  or edge. True distance is this factor times local
     //  maximum edge length.
-    tolerance       4;
+    tolerance 4.0;
 
     //- Number of mesh displacement relaxation iterations.
     nSolveIter      30;
@@ -182,344 +182,14 @@ addLayersControls
             nSurfaceLayers  1;
         }
 
-        motorBike_frt-fairing:001%1
-        {
-            nSurfaceLayers  1;
-        }
-
-        motorBike_windshield:002%2
-        {
-            nSurfaceLayers  1;
-        }
-
-        motorBike_rr-wh-rim:005%5
-        {
-            nSurfaceLayers  1;
-        }
-
-        motorBike_rr-wh-rim:010%10
-        {
-            nSurfaceLayers  1;
-        }
-
-        motorBike_fr-wh-rim:011%11
-        {
-            nSurfaceLayers  1;
-        }
-
-        motorBike_fr-wh-brake-disk:012%12
-        {
-            nSurfaceLayers  1;
-        }
-
-        motorBike_frame:016-shadow%13
-        {
-            nSurfaceLayers  1;
-        }
-
-        motorBike_rear-susp:014%14
-        {
-            nSurfaceLayers  1;
-        }
-
-        motorBike_rear-susp:014-shadow%15
-        {
-            nSurfaceLayers  1;
-        }
-
-        motorBike_frame:016%16
-        {
-            nSurfaceLayers  1;
-        }
-
-        motorBike_rr-wh-rim:005-shadow%17
-        {
-            nSurfaceLayers  1;
-        }
-
-        motorBike_rr-wh-chain-hub:022%22
-        {
-            nSurfaceLayers  1;
-        }
-
-        motorBike_rearseat%24
-        {
-            nSurfaceLayers  1;
-        }
-
-        motorBike_frt-fairing%25
-        {
-            nSurfaceLayers  1;
-        }
-
-        motorBike_windshield%26
-        {
-            nSurfaceLayers  1;
-        }
-
-        motorBike_headlights%27
-        {
-            nSurfaceLayers  1;
-        }
-
-        motorBike_driversseat%28
-        {
-            nSurfaceLayers  1;
-        }
-
-        motorBike_rear-body%29
-        {
-            nSurfaceLayers  1;
-        }
-
-        motorBike_fuel-tank%30
-        {
-            nSurfaceLayers  1;
-        }
-
-        motorBike_exhaust%31
-        {
-            nSurfaceLayers  1;
-        }
-
-        motorBike_rr-wh-rim%32
-        {
-            nSurfaceLayers  1;
-        }
-
-        motorBike_fr-mud-guard%33
-        {
-            nSurfaceLayers  1;
-        }
-
-        motorBike_fr-wh-rim%34
-        {
-            nSurfaceLayers  1;
-        }
-
-        motorBike_fr-wh-brake-disk%35
-        {
-            nSurfaceLayers  1;
-        }
-
-        motorBike_fr-brake-caliper%36
-        {
-            nSurfaceLayers  1;
-        }
-
-        motorBike_fr-wh-tyre%37
-        {
-            nSurfaceLayers  1;
-        }
-
-        motorBike_hbars%38
-        {
-            nSurfaceLayers  1;
-        }
-
-        motorBike_fr-forks%39
-        {
-            nSurfaceLayers  1;
-        }
-
-        motorBike_chain%40
-        {
-            nSurfaceLayers  1;
-        }
-
-        motorBike_rr-wh-tyre%41
-        {
-            nSurfaceLayers  1;
-        }
-
-        motorBike_square-dial%42
-        {
-            nSurfaceLayers  1;
-        }
-
-        motorBike_round-dial%43
-        {
-            nSurfaceLayers  1;
-        }
-
-        motorBike_dial-holder%44
-        {
-            nSurfaceLayers  1;
-        }
-
-        motorBike_rear-susp%45
-        {
-            nSurfaceLayers  1;
-        }
-
-        motorBike_rear-brake-lights%46
-        {
-            nSurfaceLayers  1;
-        }
-
-        motorBike_rear-light-bracket%47
-        {
-            nSurfaceLayers  1;
-        }
-
-        motorBike_frame%48
-        {
-            nSurfaceLayers  1;
-        }
-
-        motorBike_rear-mud-guard%49
-        {
-            nSurfaceLayers  1;
-        }
-
-        motorBike_rear-susp-spring-damp%50
-        {
-            nSurfaceLayers  1;
-        }
-
-        motorBike_fairing-inner-plate%51
-        {
-            nSurfaceLayers  1;
-        }
-
-        motorBike_clutch-housing%52
-        {
-            nSurfaceLayers  1;
-        }
-
-        motorBike_radiator%53
-        {
-            nSurfaceLayers  1;
-        }
-
-        motorBike_water-pipe%54
-        {
-            nSurfaceLayers  1;
-        }
-
-        motorBike_water-pump%55
-        {
-            nSurfaceLayers  1;
-        }
-
-        motorBike_engine%56
-        {
-            nSurfaceLayers  1;
-        }
-
-        motorBike_rear-shock-link%57
-        {
-            nSurfaceLayers  1;
-        }
-
-        motorBike_rear-brake-fluid-pot-bracket%58
-        {
-            nSurfaceLayers  1;
-        }
-
-        motorBike_rear-brake-fluid-pot%59
-        {
-            nSurfaceLayers  1;
-        }
-
-        motorBike_footpeg%60
-        {
-            nSurfaceLayers  1;
-        }
-
-        motorBike_rr-wh-chain-hub%61
-        {
-            nSurfaceLayers  1;
-        }
-
-        motorBike_rear-brake-caliper%62
-        {
-            nSurfaceLayers  1;
-        }
-
-        motorBike_rider-helmet%65
-        {
-            nSurfaceLayers  1;
-        }
-
-        motorBike_rider-visor%66
-        {
-            nSurfaceLayers  1;
-        }
-
-        motorBike_rider-boots%67
-        {
-            nSurfaceLayers  1;
-        }
-
-        motorBike_rider-gloves%68
-        {
-            nSurfaceLayers  1;
-        }
-
-        motorBike_rider-body%69
-        {
-            nSurfaceLayers  1;
-        }
-
-        motorBike_frame:0%70
-        {
-            nSurfaceLayers  1;
-        }
-
-        motorBike_frt-fairing:001-shadow%74
-        {
-            nSurfaceLayers  1;
-        }
-
-        motorBike_windshield-shadow%75
-        {
-            nSurfaceLayers  1;
-        }
-
-        motorBike_fr-mud-guard-shadow%81
-        {
-            nSurfaceLayers  1;
-        }
-
-        motorBike_fr-wh-brake-disk-shadow%83
-        {
-            nSurfaceLayers  1;
-        }
-
-        motorBike_rear-mud-guard-shadow%84
-        {
-            nSurfaceLayers  1;
-        }
-
-        motorBike_rear-susp-spring-damp-shadow%85
-        {
-            nSurfaceLayers  1;
-        }
-
-        motorBike_radiator-shadow%86
-        {
-            nSurfaceLayers  1;
-        }
-
-        motorBike_rear-shock-link-shadow%87
-        {
-            nSurfaceLayers  1;
-        }
-
-        motorBike_rear-brake-fluid-pot-bracket-shadow%88
-        {
-            nSurfaceLayers  1;
-        }
-
-        motorBike_rr-wh-chain-hub-shadow%89
+        "motorBike_.*"
         {
             nSurfaceLayers  1;
         }
     }
 
     // Expansion factor for layer mesh
-    expansionRatio  1;
+    expansionRatio 1.0;
 
     //- Wanted thickness of final added cell layer. If multiple layers
     //  is the
@@ -569,6 +239,10 @@ addLayersControls
 
     // Create buffer region for new layer terminations
     nBufferCellsNoExtrude 0;
+
+
+    // Overall max number of layer addition iterations
+    nLayerIter 50;
 }
 
 
diff --git a/wmake/rules/General/bison b/wmake/rules/General/bison
index 4c63c1f56577dad50619076214228f7797cef2fc..fe2e00a0977f6e4c06f1d1e8169e5a69e011a89d 100644
--- a/wmake/rules/General/bison
+++ b/wmake/rules/General/bison
@@ -1,8 +1,8 @@
 .SUFFIXES: .y .Y
 
-ytoo = bison -v $(YYPREFIX) -d $$SOURCE ; mv $$SOURCE_DIR/*.tab.c $*.c ; mv $$SOURCE_DIR/*.tab.h $*.h ; $(cc) $(cFLAGS) -c $*.c -o $@ 
+ytoo = bison -v -d -y $$SOURCE ; mv y.tab.c $*.c ; mv y.tab.h $*.h ; $(cc) $(cFLAGS) -c $*.c -o $@ 
 
-Ytoo = bison -v $(YYPREFIX) -d $$SOURCE ; mv $$SOURCE_DIR/*.tab.c $*.C ; mv $$SOURCE_DIR/*.tab.h $*.H ; $(CC) $(c++FLAGS) -c $*.C -o $@ 
+Ytoo = bison -v -d -y $$SOURCE ; mv y.tab.c $*.C ; mv y.tab.h $*.H ; $(CC) $(c++FLAGS) -c $*.C -o $@ 
 
 .y.dep:
 	$(MAKE_DEP)
diff --git a/wmake/rules/General/flex b/wmake/rules/General/flex
index c33195546a337046c2002d98114516a199963fe7..06defbb03d3d42e9f803ab3d8cce3184228258ce 100644
--- a/wmake/rules/General/flex
+++ b/wmake/rules/General/flex
@@ -1,6 +1,6 @@
 .SUFFIXES: .l
 
-ltoo = flex $$SOURCE ; mv lex.yy.c $*.C ; $(CC) $(c++FLAGS) -c $*.C -o $@ 
+ltoo = flex $$SOURCE ; mv lex.yy.c $*.c ; $(cc) $(cFLAGS) -c $*.c -o $@ 
 
 .l.dep:
 	$(MAKE_DEP)
diff --git a/wmake/rules/General/standard b/wmake/rules/General/standard
index 8e5e436d32aa2754691dbb1ad89418083daceb95..7752bef0846ab9f047864dfa74bb99d0870d09c2 100644
--- a/wmake/rules/General/standard
+++ b/wmake/rules/General/standard
@@ -5,6 +5,7 @@ include $(GENERAL_RULES)/sourceToDep
 include $(GENERAL_RULES)/java
 include $(GENERAL_RULES)/flex
 include $(GENERAL_RULES)/flex++
-include $(GENERAL_RULES)/byacc
-include $(GENERAL_RULES)/btyacc++
+#include $(GENERAL_RULES)/byacc
+#include $(GENERAL_RULES)/btyacc++
+include $(GENERAL_RULES)/bison
 include $(GENERAL_RULES)/moc