diff --git a/applications/solvers/compressible/rhoPimpleFoam/createFields.H b/applications/solvers/compressible/rhoPimpleFoam/createFields.H
index d1ade4b457277fa1a0c35dfa3dd135c7b6b9917c..070f651a999296d7214d5f86e7fec2e021df2b58 100644
--- a/applications/solvers/compressible/rhoPimpleFoam/createFields.H
+++ b/applications/solvers/compressible/rhoPimpleFoam/createFields.H
@@ -39,15 +39,8 @@
 
     #include "compressibleCreatePhi.H"
 
-    dimensionedScalar rhoMax
-    (
-        mesh.solutionDict().subDict("PIMPLE").lookup("rhoMax")
-    );
-
-    dimensionedScalar rhoMin
-    (
-        mesh.solutionDict().subDict("PIMPLE").lookup("rhoMin")
-    );
+    dimensionedScalar rhoMax(pimple.dict().lookup("rhoMax"));
+    dimensionedScalar rhoMin(pimple.dict().lookup("rhoMin"));
 
     Info<< "Creating turbulence model\n" << endl;
     autoPtr<compressible::turbulenceModel> turbulence
diff --git a/applications/solvers/compressible/rhoPimpleFoam/rhoPimpleFoam.C b/applications/solvers/compressible/rhoPimpleFoam/rhoPimpleFoam.C
index 94f3f54de4577b0cce4c749b831133b5ec42c398..0336ceb74d708531aa00f5a6520bb3bb2197f08e 100644
--- a/applications/solvers/compressible/rhoPimpleFoam/rhoPimpleFoam.C
+++ b/applications/solvers/compressible/rhoPimpleFoam/rhoPimpleFoam.C
@@ -46,10 +46,13 @@ int main(int argc, char *argv[])
     #include "setRootCase.H"
     #include "createTime.H"
     #include "createMesh.H"
+
+    pimpleControl pimple(mesh);
+
     #include "createFields.H"
     #include "initContinuityErrs.H"
 
-    pimpleControl pimple(mesh);
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
     Info<< "\nStarting time loop\n" << endl;
 
diff --git a/applications/solvers/compressible/rhoPimpleFoam/rhoPorousMRFPimpleFoam/rhoPorousMRFPimpleFoam.C b/applications/solvers/compressible/rhoPimpleFoam/rhoPorousMRFPimpleFoam/rhoPorousMRFPimpleFoam.C
index 5bfbc84d5602851615dbc7626b2e969bb11a3638..8de8a412c350931914bad79d0434dcb051d63a43 100644
--- a/applications/solvers/compressible/rhoPimpleFoam/rhoPorousMRFPimpleFoam/rhoPorousMRFPimpleFoam.C
+++ b/applications/solvers/compressible/rhoPimpleFoam/rhoPorousMRFPimpleFoam/rhoPorousMRFPimpleFoam.C
@@ -48,12 +48,13 @@ int main(int argc, char *argv[])
     #include "setRootCase.H"
     #include "createTime.H"
     #include "createMesh.H"
+
+    pimpleControl pimple(mesh);
+
     #include "createFields.H"
     #include "createZones.H"
     #include "initContinuityErrs.H"
 
-    pimpleControl pimple(mesh);
-
     // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
     Info<< "\nStarting time loop\n" << endl;
diff --git a/applications/solvers/compressible/rhoSimpleFoam/createFields.H b/applications/solvers/compressible/rhoSimpleFoam/createFields.H
index aa3de6d6fbfd9c462d57057451c9f723cede8221..27bfb8313317147b91ca84655b61e7086cf19975 100644
--- a/applications/solvers/compressible/rhoSimpleFoam/createFields.H
+++ b/applications/solvers/compressible/rhoSimpleFoam/createFields.H
@@ -42,17 +42,10 @@
 
     label pRefCell = 0;
     scalar pRefValue = 0.0;
-    setRefCell(p, mesh.solutionDict().subDict("SIMPLE"), pRefCell, pRefValue);
+    setRefCell(p, simple.dict(), pRefCell, pRefValue);
 
-    dimensionedScalar rhoMax
-    (
-        mesh.solutionDict().subDict("SIMPLE").lookup("rhoMax")
-    );
-
-    dimensionedScalar rhoMin
-    (
-        mesh.solutionDict().subDict("SIMPLE").lookup("rhoMin")
-    );
+    dimensionedScalar rhoMax(simple.dict().lookup("rhoMax"));
+    dimensionedScalar rhoMin(simple.dict().lookup("rhoMin"));
 
     Info<< "Creating turbulence model\n" << endl;
     autoPtr<compressible::RASModel> turbulence
diff --git a/applications/solvers/compressible/rhoSimpleFoam/rhoPorousMRFSimpleFoam/createZones.H b/applications/solvers/compressible/rhoSimpleFoam/rhoPorousMRFSimpleFoam/createZones.H
index 78a96429f6da7e213139d7c33c387ae137bd6642..0ed5afa2745897eea93992ba7cad5c8e6a5c6fc2 100644
--- a/applications/solvers/compressible/rhoSimpleFoam/rhoPorousMRFSimpleFoam/createZones.H
+++ b/applications/solvers/compressible/rhoSimpleFoam/rhoPorousMRFSimpleFoam/createZones.H
@@ -9,13 +9,7 @@
     if (pZones.size())
     {
         // nUCorrectors for pressureImplicitPorosity
-        if (mesh.solutionDict().subDict("SIMPLE").found("nUCorrectors"))
-        {
-            nUCorr = readInt
-            (
-                mesh.solutionDict().subDict("SIMPLE").lookup("nUCorrectors")
-            );
-        }
+        simple.dict().readIfPresent("nUCorrectors", nUCorr);
 
         if (nUCorr > 0)
         {
diff --git a/applications/solvers/compressible/rhoSimpleFoam/rhoPorousMRFSimpleFoam/rhoPorousMRFSimpleFoam.C b/applications/solvers/compressible/rhoSimpleFoam/rhoPorousMRFSimpleFoam/rhoPorousMRFSimpleFoam.C
index 5273f50eaa2ee32c0836f503faf0e9620093cc23..1cb421e5f41f9c306b3808b078994737cc903e68 100644
--- a/applications/solvers/compressible/rhoSimpleFoam/rhoPorousMRFSimpleFoam/rhoPorousMRFSimpleFoam.C
+++ b/applications/solvers/compressible/rhoSimpleFoam/rhoPorousMRFSimpleFoam/rhoPorousMRFSimpleFoam.C
@@ -45,12 +45,13 @@ int main(int argc, char *argv[])
     #include "setRootCase.H"
     #include "createTime.H"
     #include "createMesh.H"
+
+    simpleControl simple(mesh);
+
     #include "createFields.H"
     #include "createZones.H"
     #include "initContinuityErrs.H"
 
-    simpleControl simple(mesh);
-
     // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
     Info<< "\nStarting time loop\n" << endl;
diff --git a/applications/solvers/compressible/rhoSimpleFoam/rhoSimpleFoam.C b/applications/solvers/compressible/rhoSimpleFoam/rhoSimpleFoam.C
index 454da314411c1cfd8e9fcff8a99df841a5214f21..e87a35fab27c22ecf7562a0dd4d204dd14b1f4ad 100644
--- a/applications/solvers/compressible/rhoSimpleFoam/rhoSimpleFoam.C
+++ b/applications/solvers/compressible/rhoSimpleFoam/rhoSimpleFoam.C
@@ -42,11 +42,12 @@ int main(int argc, char *argv[])
     #include "setRootCase.H"
     #include "createTime.H"
     #include "createMesh.H"
-    #include "createFields.H"
-    #include "initContinuityErrs.H"
 
     simpleControl simple(mesh);
 
+    #include "createFields.H"
+    #include "initContinuityErrs.H"
+
     // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
     Info<< "\nStarting time loop\n" << endl;
diff --git a/applications/solvers/compressible/rhoSimplecFoam/createFields.H b/applications/solvers/compressible/rhoSimplecFoam/createFields.H
index fab7b70048f6e147427cd3ba75ea545b88cd2e8f..46a382864e72740185c60ca49560ff95f2a2bfdb 100644
--- a/applications/solvers/compressible/rhoSimplecFoam/createFields.H
+++ b/applications/solvers/compressible/rhoSimplecFoam/createFields.H
@@ -41,17 +41,10 @@
 
     label pRefCell = 0;
     scalar pRefValue = 0.0;
-    setRefCell(p, mesh.solutionDict().subDict("SIMPLE"), pRefCell, pRefValue);
+    setRefCell(p, simple.dict(), pRefCell, pRefValue);
 
-    dimensionedScalar rhoMax
-    (
-        mesh.solutionDict().subDict("SIMPLE").lookup("rhoMax")
-    );
-
-    dimensionedScalar rhoMin
-    (
-        mesh.solutionDict().subDict("SIMPLE").lookup("rhoMin")
-    );
+    dimensionedScalar rhoMax(simple.dict().lookup("rhoMax"));
+    dimensionedScalar rhoMin(simple.dict().lookup("rhoMin"));
 
     Info<< "Creating turbulence model\n" << endl;
     autoPtr<compressible::RASModel> turbulence
diff --git a/applications/solvers/compressible/rhoSimplecFoam/rhoSimplecFoam.C b/applications/solvers/compressible/rhoSimplecFoam/rhoSimplecFoam.C
index 278e689bc27c2ee64eb69ceeb12094c01dd1b532..937358e0f5a83619655efca3ded9aece15e90838 100644
--- a/applications/solvers/compressible/rhoSimplecFoam/rhoSimplecFoam.C
+++ b/applications/solvers/compressible/rhoSimplecFoam/rhoSimplecFoam.C
@@ -44,11 +44,12 @@ int main(int argc, char *argv[])
     #include "setRootCase.H"
     #include "createTime.H"
     #include "createMesh.H"
-    #include "createFields.H"
-    #include "initContinuityErrs.H"
 
     simpleControl simple(mesh);
 
+    #include "createFields.H"
+    #include "initContinuityErrs.H"
+
     // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
     Info<< "\nStarting time loop\n" << endl;
diff --git a/applications/solvers/heatTransfer/chtMultiRegionFoam/Make/options b/applications/solvers/heatTransfer/chtMultiRegionFoam/Make/options
index 2fcfff41267da303f74240ace88b730e728f87c0..c896f86d1654b9687670bc9339d4bb3d8c323deb 100644
--- a/applications/solvers/heatTransfer/chtMultiRegionFoam/Make/options
+++ b/applications/solvers/heatTransfer/chtMultiRegionFoam/Make/options
@@ -8,7 +8,9 @@ EXE_INC = \
     -I$(LIB_SRC)/thermophysicalModels/specie/lnInclude \
     -I$(LIB_SRC)/thermophysicalModels/basicSolidThermo/lnInclude \
     -I$(LIB_SRC)/turbulenceModels/compressible/turbulenceModel/lnInclude \
-    -I$(LIB_SRC)/thermophysicalModels/radiationModels/lnInclude
+    -I$(LIB_SRC)/thermophysicalModels/radiationModels/lnInclude \
+    -I$(LIB_SRC)/parallel/decompose/decompose/lnInclude \
+    -I$(LIB_SRC)/parallel/reconstruct/reconstruct/lnInclude
 
 EXE_LIBS = \
     -lbasicThermophysicalModels \
@@ -19,4 +21,6 @@ EXE_LIBS = \
     -lcompressibleLESModels \
     -lmeshTools \
     -lfiniteVolume \
-    -lradiationModels
+    -lradiationModels \
+    -ldecompose \
+    -lreconstruct
diff --git a/applications/solvers/heatTransfer/chtMultiRegionFoam/allhEqn.H b/applications/solvers/heatTransfer/chtMultiRegionFoam/allhEqn.H
new file mode 100644
index 0000000000000000000000000000000000000000..cfe2e84a0f77533303ec5bc569d42c18709fcab1
--- /dev/null
+++ b/applications/solvers/heatTransfer/chtMultiRegionFoam/allhEqn.H
@@ -0,0 +1,84 @@
+
+// Get mapped alpha (surfaceScalarField)
+tmp<surfaceScalarField> tallAlpha = procToAllMapper().reconstructFvSurfaceField
+    (
+        IOobject
+        (
+            "alpha",
+            allMesh().time().timeName(),
+            allMesh(),
+            IOobject::NO_READ,
+            IOobject::NO_WRITE
+        ),
+        procAlpha
+    );
+
+// Get alpha from harmonic interpolation of vol quantities
+// (Note: really only needed at internal faces originating patches
+//  inbetween regions)
+tmp<surfaceScalarField> allHarmonicAlpha
+(
+    harmonic(allMesh()).interpolate(allVolAlpha())
+);
+
+// Loop over all fluid and solid regions to transfer
+// allHarmonicAlpha to allAlpha
+surfaceScalarField& allAlpha = tallAlpha();
+forAll(boundaryProcAddressing, procI)
+{
+    forAll(boundaryProcAddressing[procI], patchI)
+    {
+        if (boundaryProcAddressing[procI][patchI] == -1)
+        {
+            // Interface patch
+            const labelList::subList cp =
+                procMeshes[procI].boundary()[patchI].patchSlice
+                (
+                    faceProcAddressing[procI]
+                );
+
+            forAll(cp, faceI)
+            {
+                label curF = mag(cp[faceI])-1;
+                if (curF < allMesh().nInternalFaces())
+                {
+                    allAlpha[curF] = allHarmonicAlpha()[curF];
+                }
+            }
+        }
+    }
+}
+
+
+tmp<surfaceScalarField> allPhi
+(
+    procToAllMapper().reconstructFvSurfaceField
+    (
+        IOobject
+        (
+            "phi",
+            allMesh().time().timeName(),
+            allMesh(),
+            IOobject::NO_READ,
+            IOobject::NO_WRITE
+        ),
+        procPhi
+    )
+);
+
+// So we have nNonOrthCorr
+//#include "readSolidMultiRegionPIMPLEControls.H"
+//for (int nonOrth=0; nonOrth<=nNonOrthCorr; nonOrth++)
+{
+    fvScalarMatrix hEqn
+    (
+        fvm::ddt(allRho(), allh())
+      + fvm::div(allPhi(), allh())
+      - fvm::laplacian(allAlpha, allh())
+     ==
+        allSource()
+    );
+
+    hEqn.relax();
+    hEqn.solve(allMesh().solver(allh().select(finalIter)));
+}
diff --git a/applications/solvers/heatTransfer/chtMultiRegionFoam/chtMultiRegionFoam.C b/applications/solvers/heatTransfer/chtMultiRegionFoam/chtMultiRegionFoam.C
index b65ecf5118e0908642ff045171af0f2dad0e58a9..927562c144dacf0a83f2ab5c26d9f76e9e1eaab2 100644
--- a/applications/solvers/heatTransfer/chtMultiRegionFoam/chtMultiRegionFoam.C
+++ b/applications/solvers/heatTransfer/chtMultiRegionFoam/chtMultiRegionFoam.C
@@ -39,6 +39,11 @@ Description
 #include "solidRegionDiffNo.H"
 #include "basicSolidThermo.H"
 #include "radiationModel.H"
+#include "fvFieldReconstructor.H"
+#include "mixedFvPatchFields.H"
+#include "fvFieldDecomposer.H"
+#include "harmonic.H"
+#include "rmap.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -49,12 +54,40 @@ int main(int argc, char *argv[])
 
     regionProperties rp(runTime);
 
+    const label nAllRegions =
+        rp.fluidRegionNames().size()
+      + rp.solidRegionNames().size();
+    PtrList<labelIOList> cellProcAddressing(nAllRegions);
+    PtrList<labelIOList> faceProcAddressing(nAllRegions);
+    PtrList<labelIOList> boundaryProcAddressing(nAllRegions);
+    PtrList<fvMesh> procMeshes(nAllRegions);
+
+    // Load meshes, fluid first
+    labelList fluidToProc(identity(rp.fluidRegionNames().size()));
+    labelList solidToProc(rp.solidRegionNames().size());
+    forAll(solidToProc, i)
+    {
+        solidToProc[i] = fluidToProc.size()+i;
+    }
+
+    // Get the coupled solution flag
+    #include "readPIMPLEControls.H"
+
+    if (temperatureCoupled)
+    {
+        Info<< "Solving single enthalpy for all equations" << nl << endl;
+    }
+
     #include "createFluidMeshes.H"
     #include "createSolidMeshes.H"
 
     #include "createFluidFields.H"
     #include "createSolidFields.H"
 
+    // Temperature solved on single mesh
+    #include "createAllMesh.H"
+    #include "createAllFields.H"
+
     #include "initContinuityErrs.H"
 
     #include "readTimeControls.H"
@@ -81,9 +114,10 @@ int main(int argc, char *argv[])
 
         Info<< "Time = " << runTime.timeName() << nl << endl;
 
+
         if (nOuterCorr != 1)
         {
-            forAll(fluidRegions, i)
+            forAll(fluidToProc, i)
             {
                 #include "setRegionFluidFields.H"
                 #include "storeOldFluidFields.H"
@@ -96,22 +130,133 @@ int main(int argc, char *argv[])
         {
             bool finalIter = oCorr == nOuterCorr-1;
 
-            forAll(fluidRegions, i)
+            if (finalIter)
+            {
+                forAll(procMeshes, procI)
+                {
+                    procMeshes[procI].data::add("finalIteration", true);
+                }
+            }
+
+
+            PtrList<surfaceScalarField> procPhi(nAllRegions);
+            PtrList<surfaceScalarField> procAlpha(nAllRegions);
+
+
+            // Solve (uncoupled) or set up (coupled) the temperature equation
+            // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+            forAll(solidToProc, i)
+            {
+                label procI = solidToProc[i];
+
+                Info<< "\nSolving temperature for solid region "
+                    << procMeshes[procI].name() << endl;
+                #include "setRegionSolidFields.H"
+                #include "readSolidMultiRegionPIMPLEControls.H"
+
+                if (temperatureCoupled)
+                {
+                    // Map my properties to overall h equation
+                    #include "rmapSolid.H"
+                }
+                else
+                {
+                    #include "solveSolid.H"
+                }
+            }
+
+
+            forAll(fluidToProc, i)
+            {
+                label procI = fluidToProc[i];
+
+                Info<< "\nSolving temperature for fluid region "
+                    << procMeshes[procI].name() << endl;
+                #include "setRegionFluidFields.H"
+                #include "readFluidMultiRegionPIMPLEControls.H"
+
+                if (oCorr == 0)
+                {
+                    #include "rhoEqn.H"
+                }
+
+                if (temperatureCoupled)
+                {
+                    // Map my properties to overall h equation
+                    #include "rmapFluid.H"
+                }
+                else
+                {
+                    #include "hEqn.H"
+                }
+            }
+
+
+            // Solve combined h equation
+            // ~~~~~~~~~~~~~~~~~~~~~~~~~
+
+            if (temperatureCoupled)
             {
-                Info<< "\nSolving for fluid region "
-                    << fluidRegions[i].name() << endl;
+                Info<< "\nSolving single enthalpy for all regions"
+                    << endl;
+
+                // Solve combined h
+                #include "allhEqn.H"
+
+                forAll(solidToProc, i)
+                {
+                    label procI = solidToProc[i];
+                    #include "setRegionSolidFields.H"
+                    #include "readSolidMultiRegionPIMPLEControls.H"
+
+                    #include "mapSolid.H"
+                }
+
+                forAll(fluidToProc, i)
+                {
+                    label procI = fluidToProc[i];
+                    #include "setRegionFluidFields.H"
+                    #include "readFluidMultiRegionPIMPLEControls.H"
+
+                    #include "mapFluid.H"
+                }
+            }
+
+
+            // Update thermos
+            // ~~~~~~~~~~~~~~
+
+            forAll(fluidToProc, i)
+            {
+                Info<< "\nUpdating thermo for fluid region "
+                    << procMeshes[fluidToProc[i]].name() << endl;
+
                 #include "setRegionFluidFields.H"
                 #include "readFluidMultiRegionPIMPLEControls.H"
-                #include "solveFluid.H"
+
+                thermo.correct();
+                rad.correct();
+                #include "solvePressureVelocityFluid.H"
             }
 
-            forAll(solidRegions, i)
+            forAll(solidToProc, i)
             {
-                Info<< "\nSolving for solid region "
-                    << solidRegions[i].name() << endl;
+                Info<< "\nUpdating thermo for solid region "
+                    << procMeshes[solidToProc[i]].name() << endl;
                 #include "setRegionSolidFields.H"
                 #include "readSolidMultiRegionPIMPLEControls.H"
-                #include "solveSolid.H"
+
+                thermo.correct();
+            }
+
+
+            if (finalIter)
+            {
+                forAll(procMeshes, procI)
+                {
+                    procMeshes[procI].data::remove("finalIteration");
+                }
             }
         }
 
diff --git a/applications/solvers/heatTransfer/chtMultiRegionFoam/createAllFields.H b/applications/solvers/heatTransfer/chtMultiRegionFoam/createAllFields.H
new file mode 100644
index 0000000000000000000000000000000000000000..faa8eaac5872eded563c1d464978a13a2c874710
--- /dev/null
+++ b/applications/solvers/heatTransfer/chtMultiRegionFoam/createAllFields.H
@@ -0,0 +1,64 @@
+    autoPtr<volScalarField> allRho;
+    autoPtr<volScalarField> allh;
+    autoPtr<volScalarField> allVolAlpha;
+    autoPtr<fvScalarMatrix> allSource;
+
+    if (temperatureCoupled)
+    {
+        allRho.reset
+        (
+            new volScalarField
+            (
+                IOobject
+                (
+                    "rho",
+                    runTime.timeName(),
+                    allMesh(),
+                    IOobject::NO_READ,
+                    IOobject::NO_WRITE
+                ),
+                allMesh(),
+                dimensionedScalar("rho", dimDensity, 0.0)
+            )
+        );
+
+        allh.reset
+        (
+            new volScalarField
+            (
+                IOobject
+                (
+                    "h",
+                    runTime.timeName(),
+                    allMesh(),
+                    IOobject::NO_READ,
+                    IOobject::NO_WRITE
+                ),
+                allMesh(),
+                dimensionedScalar("h", dimEnergy/dimMass, 0.0),
+                mixedFvPatchScalarField::typeName
+            )
+        );
+
+        allVolAlpha.reset
+        (
+            new volScalarField
+            (
+                IOobject
+                (
+                    "volAlpha",
+                    runTime.timeName(),
+                    allMesh(),
+                    IOobject::NO_READ,
+                    IOobject::NO_WRITE
+                ),
+                allMesh(),
+                dimensionedScalar("volAlpha", dimMass/dimLength/dimTime, 0.0)
+            )
+        );
+
+        allSource.reset
+        (
+            new fvMatrix<scalar>(allh(), allh().dimensions()*dimMass/dimTime)
+        );
+    }
diff --git a/applications/solvers/heatTransfer/chtMultiRegionFoam/createAllMesh.H b/applications/solvers/heatTransfer/chtMultiRegionFoam/createAllMesh.H
new file mode 100644
index 0000000000000000000000000000000000000000..8bff40e48a02a4059f76a5e383a2c1316db55a2d
--- /dev/null
+++ b/applications/solvers/heatTransfer/chtMultiRegionFoam/createAllMesh.H
@@ -0,0 +1,63 @@
+//
+// createAllMesh.H
+// ~~~~~~~~~~~~~~~
+
+    autoPtr<fvMesh> allMesh;
+    autoPtr<fvFieldReconstructor> procToAllMapper;
+    PtrList<fvFieldDecomposer> allToProcMappers;
+
+    if (temperatureCoupled)
+    {
+        Foam::Info
+            << "Create mesh for time = "
+            << runTime.timeName() << Foam::nl << Foam::endl;
+
+        allMesh.reset
+        (
+            new Foam::fvMesh
+            (
+                Foam::IOobject
+                (
+                    Foam::fvMesh::defaultRegion,
+                    runTime.timeName(),
+                    runTime,
+                    Foam::IOobject::MUST_READ
+                )
+            )
+        );
+
+        procToAllMapper.reset
+        (
+            new fvFieldReconstructor
+            (
+                allMesh(),
+                procMeshes,
+                faceProcAddressing,
+                cellProcAddressing,
+                boundaryProcAddressing
+            )
+        );
+
+
+        allToProcMappers.setSize
+        (
+            rp.fluidRegionNames().size()
+          + rp.solidRegionNames().size()
+        );
+
+        forAll(allToProcMappers, i)
+        {
+            allToProcMappers.set
+            (
+                i,
+                new fvFieldDecomposer
+                (
+                    allMesh(),
+                    procMeshes[i],
+                    faceProcAddressing[i],
+                    cellProcAddressing[i],
+                    boundaryProcAddressing[i]
+                )
+            );
+        }
+    }
diff --git a/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/compressibleMultiRegionCourantNo.H b/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/compressibleMultiRegionCourantNo.H
index b5db5078f1ab81134f8efe86fbc6d67a8fab3984..61b7b1034089b01475bb2f00316c64012ae96ceb 100644
--- a/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/compressibleMultiRegionCourantNo.H
+++ b/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/compressibleMultiRegionCourantNo.H
@@ -1,12 +1,12 @@
     scalar CoNum = -GREAT;
 
-    forAll(fluidRegions, regionI)
+    forAll(fluidToProc, regionI)
     {
         CoNum = max
         (
             compressibleCourantNo
             (
-                fluidRegions[regionI],
+                procMeshes[fluidToProc[regionI]],
                 runTime,
                 rhoFluid[regionI],
                 phiFluid[regionI]
diff --git a/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/createFluidFields.H b/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/createFluidFields.H
index f6788d26eb3ecccb2bea1484949a781e7f3010a3..667b39d64631e31c1b6d69854f42025ee20dd2fc 100644
--- a/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/createFluidFields.H
+++ b/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/createFluidFields.H
@@ -1,30 +1,36 @@
     // Initialise fluid field pointer lists
-    PtrList<basicRhoThermo> thermoFluid(fluidRegions.size());
-    PtrList<volScalarField> rhoFluid(fluidRegions.size());
-    PtrList<volScalarField> KFluid(fluidRegions.size());
-    PtrList<volVectorField> UFluid(fluidRegions.size());
-    PtrList<surfaceScalarField> phiFluid(fluidRegions.size());
-    PtrList<uniformDimensionedVectorField> gFluid(fluidRegions.size());
-    PtrList<compressible::turbulenceModel> turbulence(fluidRegions.size());
-    PtrList<volScalarField> p_rghFluid(fluidRegions.size());
-    PtrList<volScalarField> ghFluid(fluidRegions.size());
-    PtrList<surfaceScalarField> ghfFluid(fluidRegions.size());
-    PtrList<radiation::radiationModel> radiation(fluidRegions.size());
-    PtrList<volScalarField> DpDtFluid(fluidRegions.size());
-
-    List<scalar> initialMassFluid(fluidRegions.size());
+    PtrList<basicRhoThermo> thermoFluid(rp.fluidRegionNames().size());
+    PtrList<volScalarField> rhoFluid(rp.fluidRegionNames().size());
+    PtrList<volScalarField> KFluid(rp.fluidRegionNames().size());
+    PtrList<volVectorField> UFluid(rp.fluidRegionNames().size());
+    PtrList<surfaceScalarField> phiFluid(rp.fluidRegionNames().size());
+    PtrList<uniformDimensionedVectorField> gFluid(rp.fluidRegionNames().size());
+    PtrList<compressible::turbulenceModel> turbulence
+    (
+        rp.fluidRegionNames().size()
+    );
+    PtrList<volScalarField> p_rghFluid(rp.fluidRegionNames().size());
+    PtrList<volScalarField> ghFluid(rp.fluidRegionNames().size());
+    PtrList<surfaceScalarField> ghfFluid(rp.fluidRegionNames().size());
+    PtrList<radiation::radiationModel> radiation(rp.fluidRegionNames().size());
+    PtrList<volScalarField> DpDtFluid(rp.fluidRegionNames().size());
+
+    List<scalar> initialMassFluid(rp.fluidRegionNames().size());
 
     // Populate fluid field pointer lists
-    forAll(fluidRegions, i)
+    forAll(rp.fluidRegionNames(), i)
     {
         Info<< "*** Reading fluid mesh thermophysical properties for region "
-            << fluidRegions[i].name() << nl << endl;
+            << rp.fluidRegionNames()[i] << nl << endl;
+
+        label procI = fluidToProc[i];
+
 
         Info<< "    Adding to thermoFluid\n" << endl;
         thermoFluid.set
         (
             i,
-            basicRhoThermo::New(fluidRegions[i]).ptr()
+            basicRhoThermo::New(procMeshes[procI]).ptr()
         );
 
         Info<< "    Adding to rhoFluid\n" << endl;
@@ -37,7 +43,7 @@
                 (
                     "rho",
                     runTime.timeName(),
-                    fluidRegions[i],
+                    procMeshes[procI],
                     IOobject::NO_READ,
                     IOobject::AUTO_WRITE
                 ),
@@ -55,7 +61,7 @@
                 (
                     "K",
                     runTime.timeName(),
-                    fluidRegions[i],
+                    procMeshes[procI],
                     IOobject::NO_READ,
                     IOobject::NO_WRITE
                 ),
@@ -73,11 +79,11 @@
                 (
                     "U",
                     runTime.timeName(),
-                    fluidRegions[i],
+                    procMeshes[procI],
                     IOobject::MUST_READ,
                     IOobject::AUTO_WRITE
                 ),
-                fluidRegions[i]
+                procMeshes[procI]
             )
         );
 
@@ -91,12 +97,12 @@
                 (
                     "phi",
                     runTime.timeName(),
-                    fluidRegions[i],
+                    procMeshes[procI],
                     IOobject::READ_IF_PRESENT,
                     IOobject::AUTO_WRITE
                 ),
                 linearInterpolate(rhoFluid[i]*UFluid[i])
-                    & fluidRegions[i].Sf()
+                    & procMeshes[procI].Sf()
             )
         );
 
@@ -110,7 +116,7 @@
                 (
                     "g",
                     runTime.constant(),
-                    fluidRegions[i],
+                    procMeshes[procI],
                     IOobject::MUST_READ,
                     IOobject::NO_WRITE
                 )
@@ -137,14 +143,14 @@
         ghFluid.set
         (
             i,
-            new volScalarField("gh", gFluid[i] & fluidRegions[i].C())
+            new volScalarField("gh", gFluid[i] & procMeshes[procI].C())
         );
 
         Info<< "    Adding to ghfFluid\n" << endl;
         ghfFluid.set
         (
             i,
-            new surfaceScalarField("ghf", gFluid[i] & fluidRegions[i].Cf())
+            new surfaceScalarField("ghf", gFluid[i] & procMeshes[procI].Cf())
         );
 
         p_rghFluid.set
@@ -156,11 +162,11 @@
                 (
                     "p_rgh",
                     runTime.timeName(),
-                    fluidRegions[i],
+                    procMeshes[procI],
                     IOobject::MUST_READ,
                     IOobject::AUTO_WRITE
                 ),
-                fluidRegions[i]
+                procMeshes[procI]
             )
         );
 
diff --git a/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/createFluidMeshes.H b/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/createFluidMeshes.H
index 30a2e1089f8875cf507ac0d4d76492830cf9647c..73b533b0d91136a1a16d1395752373e034c43bb7 100644
--- a/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/createFluidMeshes.H
+++ b/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/createFluidMeshes.H
@@ -1,13 +1,13 @@
-    PtrList<fvMesh> fluidRegions(rp.fluidRegionNames().size());
-
     forAll(rp.fluidRegionNames(), i)
     {
         Info<< "Create fluid mesh for region " << rp.fluidRegionNames()[i]
             << " for time = " << runTime.timeName() << nl << endl;
 
-        fluidRegions.set
+        label procI = fluidToProc[i];
+
+        procMeshes.set
         (
-            i,
+            procI,
             new fvMesh
             (
                 IOobject
@@ -19,4 +19,58 @@
                 )
             )
         );
+
+        if (temperatureCoupled)
+        {
+            cellProcAddressing.set
+            (
+                procI,
+                new labelIOList
+                (
+                    IOobject
+                    (
+                        "cellRegionAddressing",
+                        procMeshes[procI].facesInstance(),
+                        procMeshes[procI].meshSubDir,
+                        procMeshes[procI],
+                        IOobject::MUST_READ,
+                        IOobject::NO_WRITE
+                    )
+                )
+            );
+
+            faceProcAddressing.set
+            (
+                procI,
+                new labelIOList
+                (
+                    IOobject
+                    (
+                        "faceRegionAddressing",
+                        procMeshes[procI].facesInstance(),
+                        procMeshes[procI].meshSubDir,
+                        procMeshes[procI],
+                        IOobject::MUST_READ,
+                        IOobject::NO_WRITE
+                    )
+                )
+            );
+
+            boundaryProcAddressing.set
+            (
+                procI,
+                new labelIOList
+                (
+                    IOobject
+                    (
+                        "boundaryRegionAddressing",
+                        procMeshes[procI].facesInstance(),
+                        procMeshes[procI].meshSubDir,
+                        procMeshes[procI],
+                        IOobject::MUST_READ,
+                        IOobject::NO_WRITE
+                    )
+                )
+            );
+        }
     }
diff --git a/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/initContinuityErrs.H b/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/initContinuityErrs.H
index 1a7f5a3262c79506f0459fd1bedbbbe1bd086e72..8cc47b1ca01a5fb88563b8ec14c205a097a68e19 100644
--- a/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/initContinuityErrs.H
+++ b/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/initContinuityErrs.H
@@ -1 +1 @@
-List<scalar> cumulativeContErr(fluidRegions.size(), 0.0);
+List<scalar> cumulativeContErr(fluidToProc.size(), 0.0);
diff --git a/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/mapFluid.H b/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/mapFluid.H
new file mode 100644
index 0000000000000000000000000000000000000000..75d83afd09ffe23a1f85014b71f747b4e35920b2
--- /dev/null
+++ b/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/mapFluid.H
@@ -0,0 +1,3 @@
+h = allToProcMappers[procI].decomposeField(allh(), true);
+h.oldTime().timeIndex() = allh().oldTime().timeIndex();
+h.correctBoundaryConditions();
diff --git a/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/rmapFluid.H b/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/rmapFluid.H
new file mode 100644
index 0000000000000000000000000000000000000000..576d883f0129b711b2d50ba317aa42d8dd2b0536
--- /dev/null
+++ b/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/rmapFluid.H
@@ -0,0 +1,56 @@
+// Note:Map rho and rho.oldTime() since fluid rho assigned to at
+// end of iteration.
+rmap
+(
+    allRho(),
+    rho,
+    faceProcAddressing[procI],
+    cellProcAddressing[procI],
+    boundaryProcAddressing[procI]
+);
+rmap
+(
+    allRho().oldTime(),
+    rho.oldTime(),
+    faceProcAddressing[procI],
+    cellProcAddressing[procI],
+    boundaryProcAddressing[procI]
+);
+
+// Necessary? Probably only for boundary values since bcs on
+// h are not the same as those on allh
+
+rmap
+(
+    allh(),
+    h,
+    faceProcAddressing[procI],
+    cellProcAddressing[procI],
+    boundaryProcAddressing[procI]
+);
+
+procAlpha.set(procI, fvc::interpolate(turb.alphaEff()));
+
+rmap
+(
+    allVolAlpha(),
+    turb.alphaEff()(),
+    faceProcAddressing[procI],
+    cellProcAddressing[procI],
+    boundaryProcAddressing[procI]
+);
+
+rmap
+(
+    allSource(),
+    (DpDt + rad.Sh(thermo))(),
+    faceProcAddressing[procI],
+    cellProcAddressing[procI],
+    boundaryProcAddressing[procI]
+);
+
+procPhi.set
+(
+    procI,
+    new surfaceScalarField(phi)
+);
diff --git a/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/setRegionFluidFields.H b/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/setRegionFluidFields.H
index 81c6d25bb0ccc68597a0b154e0b7c3baa98552ba..5bc0fffa4048d57a290dfd5296fbc0beea62823a 100644
--- a/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/setRegionFluidFields.H
+++ b/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/setRegionFluidFields.H
@@ -1,4 +1,4 @@
-    fvMesh& mesh = fluidRegions[i];
+    fvMesh& mesh = procMeshes[fluidToProc[i]];
 
     basicRhoThermo& thermo = thermoFluid[i];
     volScalarField& rho = rhoFluid[i];
diff --git a/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/solvePressureVelocityFluid.H b/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/solvePressureVelocityFluid.H
new file mode 100644
index 0000000000000000000000000000000000000000..d04a301112c86483cdd81493fd5985f3caca2f8b
--- /dev/null
+++ b/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/solvePressureVelocityFluid.H
@@ -0,0 +1,11 @@
+#include "UEqn.H"
+
+// --- PISO loop
+for (int corr=0; corr<nCorr; corr++)
+{
+    #include "pEqn.H"
+}
+
+turb.correct();
+
+rho = thermo.rho();
diff --git a/applications/solvers/heatTransfer/chtMultiRegionFoam/readPIMPLEControls.H b/applications/solvers/heatTransfer/chtMultiRegionFoam/readPIMPLEControls.H
index 7405dee8d5ae5a8c9eb1caa8f867526a6eac4823..6d34d4388fd5f41d9134bb9c9b3de23bd07bca69 100644
--- a/applications/solvers/heatTransfer/chtMultiRegionFoam/readPIMPLEControls.H
+++ b/applications/solvers/heatTransfer/chtMultiRegionFoam/readPIMPLEControls.H
@@ -6,3 +6,6 @@
 
     const int nOuterCorr =
         pimple.lookupOrDefault<int>("nOuterCorrectors", 1);
+
+    const Switch temperatureCoupled =
+        pimple.lookupOrDefault<Switch>("temperatureCoupled", false);
diff --git a/applications/solvers/heatTransfer/chtMultiRegionFoam/rmap.H b/applications/solvers/heatTransfer/chtMultiRegionFoam/rmap.H
new file mode 100644
index 0000000000000000000000000000000000000000..d9c8e350600585212ec7c5bca78bf0bc4a211e9a
--- /dev/null
+++ b/applications/solvers/heatTransfer/chtMultiRegionFoam/rmap.H
@@ -0,0 +1,96 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+Global
+    rmap
+
+Description
+    map field on subset of mesh onto overall field. Rewrites boundary
+    conditions to be mixed.
+
+    The source fields can have different patch types for the same destination
+    patch. To work around this it attempts to convert all patch fields into
+    mixed type since this can accomodate anything from fixedValue to
+    fixedGradient.
+
+SourceFiles
+    rmap.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef rmap_H
+#define rmap_H
+
+#include "volFields.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+//- Map patchField
+template<class Type>
+static void rmap
+(
+    fvPatchField<Type>& destBC,
+    const labelList& reverseAddressing,
+    const fvPatchField<Type>& sourceBC
+);
+
+//- Map volField
+template<class Type>
+static void rmap
+(
+    GeometricField<Type, fvPatchField, volMesh>& dest,
+    const GeometricField<Type, fvPatchField, volMesh>& source,
+    const labelList& faceProcAddressing,
+    const labelList& cellProcAddressing,
+    const labelList& boundaryProcAddressing
+);
+
+//- Map fvMatrix
+template<class Type>
+static void rmap
+(
+    fvMatrix<Type>& dest,
+    const fvMatrix<Type>& source,
+    const labelList& faceProcAddressing,
+    const labelList& cellProcAddressing,
+    const labelList& boundaryProcAddressing
+);
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#ifdef NoRepository
+#   include "rmapTemplates.C"
+#endif
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/applications/solvers/heatTransfer/chtMultiRegionFoam/rmapTemplates.C b/applications/solvers/heatTransfer/chtMultiRegionFoam/rmapTemplates.C
new file mode 100644
index 0000000000000000000000000000000000000000..6dbf50a81c201d52570cdea50287fa609938bc23
--- /dev/null
+++ b/applications/solvers/heatTransfer/chtMultiRegionFoam/rmapTemplates.C
@@ -0,0 +1,309 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+\*---------------------------------------------------------------------------*/
+
+#include "rmap.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+template<class Type>
+void Foam::rmap
+(
+    fvPatchField<Type>& destBC,
+    const labelList& reverseAddressing,
+    const fvPatchField<Type>& sourceBC
+)
+{
+    // Assign value
+    destBC.Field<Type>::rmap(sourceBC, reverseAddressing);
+
+    // Assign other properties
+    if (isA<mixedFvPatchField<Type> >(destBC))
+    {
+        mixedFvPatchField<Type>& mp =
+            refCast<mixedFvPatchField<Type> >(destBC);
+
+        if (isA<mixedFvPatchField<Type> >(sourceBC))
+        {
+            const mixedFvPatchField<Type>& Tp =
+                refCast<const mixedFvPatchField<Type> >(sourceBC);
+
+            mp.refValue().rmap(Tp.refValue(), reverseAddressing);
+            mp.refGrad().rmap(Tp.refGrad(), reverseAddressing);
+            mp.valueFraction().rmap(Tp.valueFraction(), reverseAddressing);
+        }
+        else if (isA<fixedGradientFvPatchField<Type> >(sourceBC))
+        {
+            const fixedGradientFvPatchField<Type>& Tp =
+                refCast<const fixedGradientFvPatchField<Type> >
+                (
+                    sourceBC
+                );
+            // Make pure fixedGradient
+            mp.refValue().rmap(Tp, reverseAddressing); // unused
+            mp.refGrad().rmap(Tp.gradient(), reverseAddressing);
+            mp.valueFraction().rmap
+            (
+                Field<Type>(reverseAddressing.size(), 0.0),
+                reverseAddressing
+            );
+        }
+        else if (isA<zeroGradientFvPatchField<Type> >(sourceBC))
+        {
+            // Make pure fixedGradient with gradient = 0
+            mp.refValue().rmap(sourceBC, reverseAddressing); // unused
+            mp.refGrad().rmap
+            (
+                Field<Type>(reverseAddressing.size(), 0.0),
+                reverseAddressing
+            );
+            mp.valueFraction().rmap
+            (
+                Field<Type>(reverseAddressing.size(), 0.0),
+                reverseAddressing
+            );
+        }
+        else if (isA<fixedValueFvPatchField<Type> >(sourceBC))
+        {
+            // Make pure fixedValue
+            mp.refValue().rmap(sourceBC, reverseAddressing);
+            mp.refGrad().rmap
+            (
+                Field<Type>(reverseAddressing.size(), 0.0),
+                reverseAddressing
+            ); // unused
+            mp.valueFraction().rmap
+            (
+                Field<Type>(reverseAddressing.size(), 1.0),
+                reverseAddressing
+            );
+        }
+        else if (isA<calculatedFvPatchField<Type> >(sourceBC))
+        {
+            // Make pure fixedValue
+            mp.refValue().rmap(sourceBC, reverseAddressing);
+            mp.refGrad().rmap
+            (
+                Field<Type>(reverseAddressing.size(), 0.0),
+                reverseAddressing
+            ); // unused
+            mp.valueFraction().rmap
+            (
+                Field<Type>(reverseAddressing.size(), 1.0),
+                reverseAddressing
+            );
+        }
+        else
+        {
+            FatalErrorIn("rmap(..)")
+                << "Don't know how to map source bc "
+                << sourceBC.type()
+                << " into a mixed boundary condition at "
+                << destBC.patch().name()
+                << exit(FatalError);
+        }
+    }
+    else if (isA<fixedGradientFvPatchField<Type> >(destBC))
+    {
+        fixedGradientFvPatchField<Type>& mp =
+            refCast<fixedGradientFvPatchField<Type> >(destBC);
+
+        if (isA<fixedGradientFvPatchField<Type> >(sourceBC))
+        {
+            const fixedGradientFvPatchField<Type>& Tp =
+                refCast<const fixedGradientFvPatchField<Type> >
+                (
+                    sourceBC
+                );
+            mp.gradient().rmap(Tp.gradient(), reverseAddressing);
+        }
+        else if (isA<mixedFvPatchField<Type> >(sourceBC))
+        {
+            const mixedFvPatchField<Type>& Tp =
+                refCast<const mixedFvPatchField<Type> >(sourceBC);
+            mp.gradient().rmap(Tp.snGrad(), reverseAddressing);
+        }
+        else if (isA<zeroGradientFvPatchField<Type> >(sourceBC))
+        {
+            mp.gradient().rmap
+            (
+                Field<Type>(reverseAddressing.size(), 0.0),
+                reverseAddressing
+            );
+        }
+        else
+        {
+            FatalErrorIn("rmap(..)")
+                << "Don't know how to map source bc "
+                << sourceBC.type()
+                << " into a fixedGradient boundary condition at "
+                << destBC.patch().name()
+                << exit(FatalError);
+        }
+    }
+}
+
+
+template<class Type>
+void Foam::rmap
+(
+    GeometricField<Type, fvPatchField, volMesh>& dest,
+    const GeometricField<Type, fvPatchField, volMesh>& source,
+    const labelList& faceProcAddressing,
+    const labelList& cellProcAddressing,
+    const labelList& boundaryProcAddressing
+)
+{
+    if (dest.dimensions() != source.dimensions())
+    {
+        FatalErrorIn("rmap(..)")
+            << "Different dimensions for = for fields " << dest.name()
+            << " and " << source.name() << endl
+            << "     dimensions : " << dest.dimensions()
+            << " = " << source.dimensions() << endl
+            << exit(FatalError);
+    }
+
+    // Copy internal field
+    dest.internalField().rmap(source.internalField(), cellProcAddressing);
+
+    // Copy boundary properties as mixed
+    forAll(source.boundaryField(), patchI)
+    {
+        label curBPatch = boundaryProcAddressing[patchI];
+
+        if (curBPatch == -1)
+        {
+            // Unknown patch. Do not change any values.
+        }
+        else
+        {
+            // Get addressing slice for this patch
+            const labelList::subList cp =
+                source.mesh().boundary()[patchI].patchSlice
+                (
+                    faceProcAddressing
+                );
+
+            const label curPatchStart =
+                dest.mesh().boundaryMesh()[curBPatch].start();
+
+            labelList reverseAddressing(cp.size());
+
+            forAll(cp, faceI)
+            {
+                // Subtract one to take into account offsets for
+                // face direction.
+                if (cp[faceI] <= 0)
+                {
+                    FatalErrorIn("rmap(..)")
+                        << "Problem:"
+                        << " patch:" << source.mesh().boundary()[patchI].name()
+                        << " field:" << source.name()
+                        << " local face:" << faceI
+                        << " mapped to:" << cp[faceI] << exit(FatalError);
+                }
+
+                reverseAddressing[faceI] = cp[faceI] - 1 - curPatchStart;
+            }
+
+            // Map curBPatch from source patch. Is like rmap but also
+            // copies non-value properties from alike patchFields.
+            rmap
+            (
+                dest.boundaryField()[curBPatch],
+                reverseAddressing,
+                source.boundaryField()[patchI]
+            );
+        }
+    }
+
+    // Copy timeIndex
+    dest.timeIndex() = source.timeIndex();
+}
+
+
+template<class Type>
+void Foam::rmap
+(
+    fvMatrix<Type>& dest,
+    const fvMatrix<Type>& source,
+    const labelList& faceProcAddressing,
+    const labelList& cellProcAddressing,
+    const labelList& boundaryProcAddressing
+)
+{
+    dest.source().rmap(source.source(), cellProcAddressing);
+
+    FieldField<Field, Type>& sourceInternal =
+        const_cast<fvMatrix<Type>&>(source).internalCoeffs();
+    FieldField<Field, Type>& sourceBoundary =
+        const_cast<fvMatrix<Type>&>(source).boundaryCoeffs();
+
+    forAll(sourceInternal, patchI)
+    {
+        label curBPatch = boundaryProcAddressing[patchI];
+
+        if (curBPatch == -1)
+        {
+            // Unknown patch. Do not change any values.
+        }
+        else
+        {
+            // Get addressing slice for this patch
+            const fvMesh& sourceMesh = source.psi().mesh();
+
+            const labelList::subList cp =
+                sourceMesh.boundary()[patchI].patchSlice
+                (
+                    faceProcAddressing
+                );
+
+            const label curPatchStart =
+                dest.psi().mesh().boundaryMesh()[curBPatch].start();
+
+            labelList reverseAddressing(cp.size());
+
+            forAll(cp, faceI)
+            {
+                // Subtract one to take into account offsets for
+                // face direction.
+                reverseAddressing[faceI] = cp[faceI] - 1 - curPatchStart;
+            }
+            dest.internalCoeffs()[curBPatch].rmap
+            (
+                sourceInternal[patchI],
+                reverseAddressing
+            );
+            dest.boundaryCoeffs()[curBPatch].rmap
+            (
+                sourceBoundary[patchI],
+                reverseAddressing
+            );
+        }
+    }
+}
+
+
+// ************************************************************************* //
diff --git a/applications/solvers/heatTransfer/chtMultiRegionFoam/solid/createSolidFields.H b/applications/solvers/heatTransfer/chtMultiRegionFoam/solid/createSolidFields.H
index 837305659e6c088fa7048bb0e174a6da57fc418c..ab58752d80a0573d4fb8f51f2609375feaa4623c 100644
--- a/applications/solvers/heatTransfer/chtMultiRegionFoam/solid/createSolidFields.H
+++ b/applications/solvers/heatTransfer/chtMultiRegionFoam/solid/createSolidFields.H
@@ -1,12 +1,36 @@
     // Initialise solid field pointer lists
-    PtrList<basicSolidThermo> thermos(solidRegions.size());
+    PtrList<basicSolidThermo> thermoSolid(rp.solidRegionNames().size());
+    PtrList<volScalarField> hSolid(rp.solidRegionNames().size());
 
     // Populate solid field pointer lists
-    forAll(solidRegions, i)
+    forAll(rp.solidRegionNames(), i)
     {
         Info<< "*** Reading solid mesh thermophysical properties for region "
-            << solidRegions[i].name() << nl << endl;
+            << rp.solidRegionNames()[i] << nl << endl;
 
-        Info<< "    Adding to thermos\n" << endl;
-        thermos.set(i, basicSolidThermo::New(solidRegions[i]));
+        label procI = solidToProc[i];
+
+        Info<< "    Adding to thermoSolid\n" << endl;
+        thermoSolid.set(i, basicSolidThermo::New(procMeshes[procI]));
+
+        if (temperatureCoupled)
+        {
+            Info<< "    Adding to hSolid\n" << endl;
+            hSolid.set
+            (
+                i,
+                new volScalarField
+                (
+                    IOobject
+                    (
+                        "h",
+                        runTime.timeName(),
+                        procMeshes[procI],
+                        IOobject::MUST_READ,
+                        IOobject::AUTO_WRITE
+                    ),
+                    procMeshes[procI]
+                )
+            );
+        }
     }
diff --git a/applications/solvers/heatTransfer/chtMultiRegionFoam/solid/createSolidMeshes.H b/applications/solvers/heatTransfer/chtMultiRegionFoam/solid/createSolidMeshes.H
index eb50be23808e6ffdf31c17fca398bb5366f24c7e..10b5f4160cee55cc88d1e4fa77f63f1fe229f3e7 100644
--- a/applications/solvers/heatTransfer/chtMultiRegionFoam/solid/createSolidMeshes.H
+++ b/applications/solvers/heatTransfer/chtMultiRegionFoam/solid/createSolidMeshes.H
@@ -1,13 +1,13 @@
-    PtrList<fvMesh> solidRegions(rp.solidRegionNames().size());
-
     forAll(rp.solidRegionNames(), i)
     {
         Info<< "Create solid mesh for region " << rp.solidRegionNames()[i]
             << " for time = " << runTime.timeName() << nl << endl;
 
-        solidRegions.set
+        label procI = solidToProc[i];
+
+        procMeshes.set
         (
-            i,
+            procI,
             new fvMesh
             (
                 IOobject
@@ -20,8 +20,57 @@
             )
         );
 
-        // Force calculation of geometric properties to prevent it being done
-        // later in e.g. some boundary evaluation
-        //(void)solidRegions[i].weights();
-        //(void)solidRegions[i].deltaCoeffs();
+        if (temperatureCoupled)
+        {
+            cellProcAddressing.set
+            (
+                procI,
+                new labelIOList
+                (
+                    IOobject
+                    (
+                        "cellRegionAddressing",
+                        procMeshes[procI].facesInstance(),
+                        procMeshes[procI].meshSubDir,
+                        procMeshes[procI],
+                        IOobject::MUST_READ,
+                        IOobject::NO_WRITE
+                    )
+                )
+            );
+
+            faceProcAddressing.set
+            (
+                procI,
+                new labelIOList
+                (
+                    IOobject
+                    (
+                        "faceRegionAddressing",
+                        procMeshes[procI].facesInstance(),
+                        procMeshes[procI].meshSubDir,
+                        procMeshes[procI],
+                        IOobject::MUST_READ,
+                        IOobject::NO_WRITE
+                    )
+                )
+            );
+
+            boundaryProcAddressing.set
+            (
+                procI,
+                new labelIOList
+                (
+                    IOobject
+                    (
+                        "boundaryRegionAddressing",
+                        procMeshes[procI].facesInstance(),
+                        procMeshes[procI].meshSubDir,
+                        procMeshes[procI],
+                        IOobject::MUST_READ,
+                        IOobject::NO_WRITE
+                    )
+                )
+            );
+        }
     }
diff --git a/applications/solvers/heatTransfer/chtMultiRegionFoam/solid/mapSolid.H b/applications/solvers/heatTransfer/chtMultiRegionFoam/solid/mapSolid.H
new file mode 100644
index 0000000000000000000000000000000000000000..ca6e506347d5d76fba7b19299e545fabea583ca2
--- /dev/null
+++ b/applications/solvers/heatTransfer/chtMultiRegionFoam/solid/mapSolid.H
@@ -0,0 +1,15 @@
+{
+    volScalarField& h = hSolid[i];
+
+    h = allToProcMappers[procI].decomposeField(allh(), true);
+    h.oldTime().timeIndex() = allh().oldTime().timeIndex();
+
+    T += (h-h.oldTime())/cp;
+    // Correct T boundary conditions and update h boundary
+    // conditions accordingly.
+    volScalarField::GeometricBoundaryField Told = T.boundaryField();
+    T.correctBoundaryConditions();
+    h.boundaryField() +=
+        cp.boundaryField()
+      * (T.boundaryField()-Told);
+}
diff --git a/applications/solvers/heatTransfer/chtMultiRegionFoam/solid/rmapSolid.H b/applications/solvers/heatTransfer/chtMultiRegionFoam/solid/rmapSolid.H
new file mode 100644
index 0000000000000000000000000000000000000000..b36474a531cb66108eba65be7e6c8dbb61704767
--- /dev/null
+++ b/applications/solvers/heatTransfer/chtMultiRegionFoam/solid/rmapSolid.H
@@ -0,0 +1,90 @@
+{
+    volScalarField& h = hSolid[i];
+
+    procPhi.setSize(nAllRegions);
+    procAlpha.setSize(nAllRegions);
+
+    rmap
+    (
+        allRho(),
+        rho,
+        faceProcAddressing[procI],
+        cellProcAddressing[procI],
+        boundaryProcAddressing[procI]
+    );
+
+    // Necessary? Probably only for boundary values since bcs on
+    // h are not the same as those on allh
+    rmap
+    (
+        allh(),
+        h,
+        faceProcAddressing[procI],
+        cellProcAddressing[procI],
+        boundaryProcAddressing[procI]
+    );
+
+
+    tmp<volScalarField> Kcp(K/cp);
+
+    rmap
+    (
+        allVolAlpha(),
+        Kcp(),
+        faceProcAddressing[procI],
+        cellProcAddressing[procI],
+        boundaryProcAddressing[procI]
+    );
+
+    procAlpha.set(procI, fvc::interpolate(Kcp));
+
+    // allSource is initialised to zero already
+    //rmap
+    //(
+    //    allSource(),
+    //    volScalarField
+    //    (
+    //        IOobject
+    //        (
+    //            "procSource",
+    //            runTime.timeName(),
+    //            mesh,
+    //            IOobject::NO_READ,
+    //            IOobject::AUTO_WRITE
+    //        ),
+    //        mesh,
+    //        dimensionedScalar
+    //        (
+    //            "procSource",
+    //            allh().dimensions()*dimDensity/dimTime,
+    //            0.0
+    //        )
+    //    ),
+    //    faceProcAddressing[procI],
+    //    cellProcAddressing[procI],
+    //    boundaryProcAddressing[procI]
+    //);
+
+    procPhi.set
+    (
+        procI,
+        new surfaceScalarField
+        (
+            IOobject
+            (
+                "phi",
+                runTime.timeName(),
+                mesh,
+                IOobject::NO_READ,
+                IOobject::AUTO_WRITE
+            ),
+            mesh,
+            dimensionedScalar
+            (
+                "phi",
+                dimDensity*dimVelocity*dimArea,
+                0.0
+            )
+        )
+    );
+}
diff --git a/applications/solvers/heatTransfer/chtMultiRegionFoam/solid/setRegionSolidFields.H b/applications/solvers/heatTransfer/chtMultiRegionFoam/solid/setRegionSolidFields.H
index a843ed8bd75f562bbba0dfb157356b36aaaaf5fd..a1dbe88c0abeb1a08bd53f4270cee3d830d385ff 100644
--- a/applications/solvers/heatTransfer/chtMultiRegionFoam/solid/setRegionSolidFields.H
+++ b/applications/solvers/heatTransfer/chtMultiRegionFoam/solid/setRegionSolidFields.H
@@ -1,5 +1,5 @@
-    fvMesh& mesh = solidRegions[i];
-    basicSolidThermo& thermo = thermos[i];
+    fvMesh& mesh = procMeshes[solidToProc[i]];
+    basicSolidThermo& thermo = thermoSolid[i];
 
     tmp<volScalarField> trho = thermo.rho();
     const volScalarField& rho = trho();
diff --git a/applications/solvers/heatTransfer/chtMultiRegionFoam/solid/solidRegionDiffusionNo.H b/applications/solvers/heatTransfer/chtMultiRegionFoam/solid/solidRegionDiffusionNo.H
index 77dc6f04bf44ba748359c2f8bf3267307416b650..5564d3bd3a8ada7dd6d3f39e755ae8a51e903015 100644
--- a/applications/solvers/heatTransfer/chtMultiRegionFoam/solid/solidRegionDiffusionNo.H
+++ b/applications/solvers/heatTransfer/chtMultiRegionFoam/solid/solidRegionDiffusionNo.H
@@ -1,6 +1,6 @@
     scalar DiNum = -GREAT;
 
-    forAll(solidRegions, i)
+    forAll(solidToProc, i)
     {
 #       include "setRegionSolidFields.H"
 
@@ -8,7 +8,7 @@
         (
             solidRegionDiffNo
             (
-                solidRegions[i],
+                procMeshes[solidToProc[i]],
                 runTime,
                 rho*cp,
                 K
diff --git a/applications/solvers/heatTransfer/chtMultiRegionFoam/solid/solveSolid.H b/applications/solvers/heatTransfer/chtMultiRegionFoam/solid/solveSolid.H
index d8aa03283b413d632634933e396f09ac4ab64e9b..96cd32ddb37a3e7ef2aebd1f14602692177c4b43 100644
--- a/applications/solvers/heatTransfer/chtMultiRegionFoam/solid/solveSolid.H
+++ b/applications/solvers/heatTransfer/chtMultiRegionFoam/solid/solveSolid.H
@@ -1,8 +1,3 @@
-if (finalIter)
-{
-    mesh.data::add("finalIteration", true);
-}
-
 {
     for (int nonOrth=0; nonOrth<=nNonOrthCorr; nonOrth++)
     {
@@ -17,10 +12,3 @@ if (finalIter)
 
     Info<< "Min/max T:" << min(T) << ' ' << max(T) << endl;
 }
-
-thermo.correct();
-
-if (finalIter)
-{
-    mesh.data::remove("finalIteration");
-}
diff --git a/applications/solvers/incompressible/pimpleFoam/pimpleDyMFoam/pEqn.H b/applications/solvers/incompressible/pimpleFoam/pimpleDyMFoam/pEqn.H
index 7e84ef50fe6d24cffbb957a59986051a09822bb5..3e8a587768f17e523c035889b5fbdfc929b60bc7 100644
--- a/applications/solvers/incompressible/pimpleFoam/pimpleDyMFoam/pEqn.H
+++ b/applications/solvers/incompressible/pimpleFoam/pimpleDyMFoam/pEqn.H
@@ -7,6 +7,11 @@ if (pimple.nCorr() <= 1)
 
 phi = (fvc::interpolate(U) & mesh.Sf());
 
+if (ddtPhiCorr)
+{
+    phi += fvc::ddtPhiCorr(rAU, U, phi);
+}
+
 if (p.needReference())
 {
     fvc::makeRelative(phi, U);
diff --git a/applications/solvers/incompressible/pimpleFoam/pimpleDyMFoam/readControls.H b/applications/solvers/incompressible/pimpleFoam/pimpleDyMFoam/readControls.H
index 8f48f5d7d437f3796a427ffb6ba4fcae6057801e..2ad7f610f0fba573bb101c4a0b078a48cd31dbfd 100644
--- a/applications/solvers/incompressible/pimpleFoam/pimpleDyMFoam/readControls.H
+++ b/applications/solvers/incompressible/pimpleFoam/pimpleDyMFoam/readControls.H
@@ -8,3 +8,5 @@
     const bool checkMeshCourantNo =
         pimpleDict.lookupOrDefault("checkMeshCourantNo", false);
 
+    const bool ddtPhiCorr =
+        pimpleDict.lookupOrDefault("ddtPhiCorr", true);
diff --git a/applications/solvers/multiphase/interFoam/interDyMFoam/interDyMFoam.C b/applications/solvers/multiphase/interFoam/interDyMFoam/interDyMFoam.C
index 8e3500c9d6ad7f80d38c7e360c2dabf5ec2f7ae5..1face6ddd57a9ad664f9a7811403fc8cc49d9a68 100644
--- a/applications/solvers/multiphase/interFoam/interDyMFoam/interDyMFoam.C
+++ b/applications/solvers/multiphase/interFoam/interDyMFoam/interDyMFoam.C
@@ -58,6 +58,9 @@ int main(int argc, char *argv[])
     #include "CourantNo.H"
     #include "setInitialDeltaT.H"
 
+    surfaceScalarField phiAbs("phiAbs", phi);
+    fvc::makeAbsolute(phiAbs, U);
+
     // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
     Info<< "\nStarting time loop\n" << endl;
 
@@ -67,9 +70,6 @@ int main(int argc, char *argv[])
         #include "alphaCourantNo.H"
         #include "CourantNo.H"
 
-        // Make the fluxes absolute
-        fvc::makeAbsolute(phi, U);
-
         #include "setDeltaT.H"
 
         runTime++;
@@ -78,8 +78,18 @@ int main(int argc, char *argv[])
 
         scalar timeBeforeMeshUpdate = runTime.elapsedCpuTime();
 
-        // Do any mesh changes
-        mesh.update();
+        {
+            // Calculate the relative velocity used to map the relative flux phi
+            volVectorField Urel("Urel", U);
+
+            if (mesh.moving())
+            {
+                Urel -= fvc::reconstruct(fvc::meshPhi(U));
+            }
+
+            // Do any mesh changes
+            mesh.update();
+        }
 
         if (mesh.changing())
         {
@@ -96,9 +106,6 @@ int main(int argc, char *argv[])
             #include "correctPhi.H"
         }
 
-        // Make the fluxes relative to the mesh motion
-        fvc::makeRelative(phi, U);
-
         if (mesh.changing() && checkMeshCourantNo)
         {
             #include "meshCourantNo.H"
diff --git a/applications/solvers/multiphase/interFoam/interDyMFoam/pEqn.H b/applications/solvers/multiphase/interFoam/interDyMFoam/pEqn.H
index 84c1fe45b6a40666d5a7a1f184da5a1700eab522..4b90d9949929bc3a5b7d761acc8294604c9d4b51 100644
--- a/applications/solvers/multiphase/interFoam/interDyMFoam/pEqn.H
+++ b/applications/solvers/multiphase/interFoam/interDyMFoam/pEqn.H
@@ -3,16 +3,19 @@
     surfaceScalarField rAUf(fvc::interpolate(rAU));
 
     U = rAU*UEqn.H();
-    surfaceScalarField phiU("phiU", (fvc::interpolate(U) & mesh.Sf()));
+
+    phiAbs =
+        (fvc::interpolate(U) & mesh.Sf())
+      + fvc::ddtPhiCorr(rAU, rho, U, phiAbs);
 
     if (p_rgh.needReference())
     {
-        fvc::makeRelative(phiU, U);
-        adjustPhi(phiU, U, p_rgh);
-        fvc::makeAbsolute(phiU, U);
+        fvc::makeRelative(phiAbs, U);
+        adjustPhi(phiAbs, U, p_rgh);
+        fvc::makeAbsolute(phiAbs, U);
     }
 
-    phi = phiU +
+    phi = phiAbs +
     (
         fvc::interpolate(interface.sigmaK())*fvc::snGrad(alpha1)
       - ghf*fvc::snGrad(rho)
@@ -38,11 +41,13 @@
         }
     }
 
-    U += rAU*fvc::reconstruct((phi - phiU)/rAUf);
+    U += rAU*fvc::reconstruct((phi - phiAbs)/rAUf);
     U.correctBoundaryConditions();
 
     #include "continuityErrs.H"
 
+    phiAbs = phi;
+
     // Make the fluxes relative to the mesh motion
     fvc::makeRelative(phi, U);
 
diff --git a/applications/solvers/multiphase/multiphaseEulerFoam/Make/files b/applications/solvers/multiphase/multiphaseEulerFoam/Make/files
index f71c44324ac7db6982d4755fa57ec062430e8d30..b5b45045f11358eaa1805ba448847d6bf4655222 100644
--- a/applications/solvers/multiphase/multiphaseEulerFoam/Make/files
+++ b/applications/solvers/multiphase/multiphaseEulerFoam/Make/files
@@ -1,3 +1,4 @@
 multiphaseEulerFoam.C
+multiphaseFixedFluxPressure/multiphaseFixedFluxPressureFvPatchScalarField.C
 
 EXE = $(FOAM_APPBIN)/multiphaseEulerFoam
diff --git a/applications/solvers/multiphase/multiphaseEulerFoam/Make/options b/applications/solvers/multiphase/multiphaseEulerFoam/Make/options
index 8fc20e86237ec7b86f3cc24054e04e40f9320b92..06ffdda61cf603df1bc740aeb3500974b45b0e67 100644
--- a/applications/solvers/multiphase/multiphaseEulerFoam/Make/options
+++ b/applications/solvers/multiphase/multiphaseEulerFoam/Make/options
@@ -1,6 +1,7 @@
 EXE_INC = \
     -IphaseModel/lnInclude \
     -ImultiphaseSystem/lnInclude \
+    -ImultiphaseFixedFluxPressure \
     /*-IkineticTheoryModels/lnInclude*/ \
     -IinterfacialModels/lnInclude \
     -I$(LIB_SRC)/transportModels \
diff --git a/applications/solvers/multiphase/multiphaseEulerFoam/createMRFZones.H b/applications/solvers/multiphase/multiphaseEulerFoam/createMRFZones.H
index 161446a8e6f2397982c0579c232b8ce3e458053d..326c934eaf1bd14c666b921c2e8b819c2d897e70 100644
--- a/applications/solvers/multiphase/multiphaseEulerFoam/createMRFZones.H
+++ b/applications/solvers/multiphase/multiphaseEulerFoam/createMRFZones.H
@@ -1,2 +1,8 @@
     MRFZones mrfZones(mesh);
+
+    forAllIter(PtrDictionary<phaseModel>, fluid.phases(), iter)
+    {
+        mrfZones.correctBoundaryVelocity(iter().U());
+    }
+
     mrfZones.correctBoundaryVelocity(U);
diff --git a/applications/solvers/multiphase/multiphaseEulerFoam/pEqn.H b/applications/solvers/multiphase/multiphaseEulerFoam/pEqn.H
index 5f7c38ebf08fdc5abeee9b65de1b619e63f1f5d1..6cbfbf2d16a040fe7b8caf5483f824d9137768f1 100644
--- a/applications/solvers/multiphase/multiphaseEulerFoam/pEqn.H
+++ b/applications/solvers/multiphase/multiphaseEulerFoam/pEqn.H
@@ -53,12 +53,12 @@
 
         phase.U() = rAUs[phasei]*UEqns[phasei].H();
 
+        mrfZones.absoluteFlux(phase.phi());
         phase.phi() =
         (
             (fvc::interpolate(phase.U()) & mesh.Sf())
           + fvc::ddtPhiCorr(rAUs[phasei], alpha, phase.U(), phase.phi())
         );
-
         mrfZones.relativeFlux(phase.phi());
         phase.phi() += rAlphaAUfs[phasei]*(g & mesh.Sf());
 
@@ -241,7 +241,6 @@
                     }
                 }
 
-                phase.U() = fvc::reconstruct(phase.phi());
                 phase.U().correctBoundaryConditions();
 
                 U += alpha*phase.U();
diff --git a/applications/utilities/mesh/generation/extrude/extrudeToRegionMesh/extrudeToRegionMesh.C b/applications/utilities/mesh/generation/extrude/extrudeToRegionMesh/extrudeToRegionMesh.C
index 3549dc9560eaf00f99772fffa89f879a01e3b6da..0a085485f14206e5e8d113a1b54a7e1cc2efceb5 100644
--- a/applications/utilities/mesh/generation/extrude/extrudeToRegionMesh/extrudeToRegionMesh.C
+++ b/applications/utilities/mesh/generation/extrude/extrudeToRegionMesh/extrudeToRegionMesh.C
@@ -924,6 +924,7 @@ int main(int argc, char *argv[])
 
     #include "addRegionOption.H"
     #include "addOverwriteOption.H"
+    argList::addOption("dict", "name", "specify alternative dictionary");
     argList::addBoolOption("AMI", "apply mapped AMI boundary type");
 
     #include "setRootCase.H"
@@ -932,18 +933,14 @@ int main(int argc, char *argv[])
 
     const word oldInstance = mesh.pointsInstance();
     bool overwrite = args.optionFound("overwrite");
-
-    mappedPatchBase::sampleMode sampleMode = mappedPatchBase::NEARESTPATCHFACE;
-    if (args.optionFound("AMI"))
-    {
-        sampleMode = mappedPatchBase::NEARESTPATCHFACEAMI;
-    }
+    const word dictName
+        (args.optionLookupOrDefault<word>("dict", "extrudeToRegionMeshDict"));
 
     IOdictionary dict
     (
         IOobject
         (
-            "extrudeToRegionMeshDict",
+            dictName,
             runTime.system(),
             runTime,
             IOobject::MUST_READ_IF_MODIFIED
@@ -963,6 +960,9 @@ int main(int argc, char *argv[])
         dict.lookup("faceZonesShadow") >> zoneShadowNames;
     }
 
+    mappedPatchBase::sampleMode sampleMode =
+        mappedPatchBase::sampleModeNames_[dict.lookup("sampleMode")];
+
     const Switch oneD(dict.lookup("oneD"));
     const Switch adaptMesh(dict.lookup("adaptMesh"));
 
diff --git a/applications/utilities/mesh/generation/extrude/extrudeToRegionMesh/extrudeToRegionMeshDict b/applications/utilities/mesh/generation/extrude/extrudeToRegionMesh/extrudeToRegionMeshDict
index 7aa652fb79422b8543894cea2b83ab86d1d23be5..b5f14db5d6ef6183dbb11f0f791fa7dfba4d49ca 100644
--- a/applications/utilities/mesh/generation/extrude/extrudeToRegionMesh/extrudeToRegionMeshDict
+++ b/applications/utilities/mesh/generation/extrude/extrudeToRegionMesh/extrudeToRegionMeshDict
@@ -15,10 +15,10 @@ FoamFile
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 // Name of region to create
-region  liquidFilm;
+region          liquidFilm;
 
 // FaceZones to extrude
-faceZones (f0);
+faceZones       (f0);
 
 // FaceZone shadow
 //faceZonesShadow (fBaffleShadow);
@@ -30,10 +30,13 @@ faceZones (f0);
 // - extruding boundary faces: repatched to be on mapped patches
 // If false: leave original mesh intact. Extruded mesh will still have
 // mapped patch which might need to be adapted.
-adaptMesh true;
+adaptMesh       true;
+
+// Sample mode for inter-region communication
+sampleMode      nearestPatchFace;
 
 // Extrude 1D-columns of cells?
-oneD false;
+oneD            false;
 
 // If oneD is true. Specify which boundary is wanted between the layers
 //oneDPolyPatchType emptyPolyPatch; //wedgePolyPatch
@@ -42,23 +45,23 @@ oneD false;
 //- Extrusion model to use. The only logical choice is linearNormal?
 
 //- Linear extrusion in normal direction
-extrudeModel        linearNormal;
+extrudeModel    linearNormal;
 
 //- Linear extrusion in specified direction
-//extrudeModel        linearDirection;
+// extrudeModel   linearDirection;
 
 //- Wedge extrusion. If nLayers is 1 assumes symmetry around plane.
-// extrudeModel        wedge;
+// extrudeModel   wedge;
 
 //- Extrudes into sphere around (0 0 0)
-//extrudeModel        linearRadial;
+// extrudeModel   linearRadial;
 
 //- Extrudes into sphere with grading according to pressure (atmospherics)
-//extrudeModel        sigmaRadial;
+// extrudeModel   sigmaRadial;
 
-nLayers             10;
+nLayers         10;
 
-expansionRatio      0.9;
+expansionRatio  0.9;
 
 linearNormalCoeffs
 {
diff --git a/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMeshDict b/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMeshDict
index 0d88051cede9aa56eb204cf97a35519ca051775a..2bbc9b42fc655d8bfc0d880a266142dce8430280 100644
--- a/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMeshDict
+++ b/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMeshDict
@@ -70,7 +70,7 @@ castellatedMeshControls
     // If local number of cells is >= maxLocalCells on any processor
     // switches from from refinement followed by balancing
     // (current method) to (weighted) balancing before refinement.
-    maxLocalCells 1000000;
+    maxLocalCells 100000;
 
     // Overall cell limit (approximately). Refinement will stop immediately
     // upon reaching this number so a refinement level might not complete.
@@ -311,6 +311,11 @@ addLayersControls
     // get used. Up to nRelaxIter it uses the settings in meshQualityControls,
     // after nRelaxIter it uses the values in meshQualityControls::relaxed.
     nRelaxedIter 20;
+
+    // Additional reporting: if there are just a few faces where there
+    // are mesh errors (after adding the layers) print their face centres.
+    // This helps in tracking down problematic mesh areas.
+    //additionalReporting true;
 }
 
 // Generic mesh quality settings. At any undoable phase these determine
diff --git a/applications/utilities/mesh/manipulation/splitMeshRegions/splitMeshRegions.C b/applications/utilities/mesh/manipulation/splitMeshRegions/splitMeshRegions.C
index 5ce408d305818c6384af8911be189431a6aa3787..b34676fac5c0d7d0975f0e9029133d06399b4fae 100644
--- a/applications/utilities/mesh/manipulation/splitMeshRegions/splitMeshRegions.C
+++ b/applications/utilities/mesh/manipulation/splitMeshRegions/splitMeshRegions.C
@@ -55,8 +55,10 @@ Description
     this if you don't mind having disconnected domains in a single region.
     This option requires all cells to be in one (and one only) cellZone.
 
+
     - Should work in parallel.
     cellZones can differ on either side of processor boundaries in which case
+    the faces get moved from processor patch to directMapped patch. Not
     the faces get moved from processor patch to mapped patch. Not
     very well tested.
 
@@ -79,6 +81,8 @@ Description
         - faceRegionAddressing  :   ,,      face                ,,  face in
         the original mesh + 'turning index'. For a face in the same orientation
         this is the original facelabel+1, for a turned face this is -facelabel-1
+        - boundaryRegionAddressing : for every patch in this region the
+        patch in the original mesh (or -1 if added patch)
 \*---------------------------------------------------------------------------*/
 
 #include "SortableList.H"
@@ -1231,6 +1235,36 @@ void createAndWriteRegion
         << " from region" << regionI
         << " cells back to base mesh." << endl;
     cellProcAddressing.write();
+
+    labelIOList boundaryProcAddressing
+    (
+        IOobject
+        (
+            "boundaryRegionAddressing",
+            newMesh().facesInstance(),
+            newMesh().meshSubDir,
+            newMesh(),
+            IOobject::NO_READ,
+            IOobject::NO_WRITE,
+            false
+        ),
+        labelList(nNewPatches, -1)
+    );
+    forAll(oldToNew, i)
+    {
+        if (!addedPatches.found(i))
+        {
+            label newI = oldToNew[i];
+            if (newI >= 0 && newI < nNewPatches)
+            {
+                boundaryProcAddressing[oldToNew[i]] = i;
+            }
+        }
+    }
+    Info<< "Writing map " << boundaryProcAddressing.name()
+        << " from region" << regionI
+        << " boundary back to base mesh." << endl;
+    boundaryProcAddressing.write();
 }
 
 
diff --git a/applications/utilities/mesh/manipulation/topoSet/topoSetDict b/applications/utilities/mesh/manipulation/topoSet/topoSetDict
index 93194848c283794f5d5667bfd66c20e3aa7ad6ad..7dd6cf4e935936f87e6b20299917dfb6b6329106 100644
--- a/applications/utilities/mesh/manipulation/topoSet/topoSetDict
+++ b/applications/utilities/mesh/manipulation/topoSet/topoSetDict
@@ -33,24 +33,28 @@ FoamFile
 //
 //    // Select by explicitly providing cell labels
 //    source labelToCell;
+//    sourceInfo
 //    {
 //        value (12 13 56);   // labels of cells
 //    }
 //
 //    // Copy elements from cellSet
 //    source cellToCell;
+//    sourceInfo
 //    {
 //        set c1;
 //    }
 //
 //    // Cells in cell zone
 //    source zoneToCell;
+//    sourceInfo
 //    {
 //        name ".*Zone";      // Name of cellZone, regular expressions allowed
 //    }
 //
 //    // Cells on master or slave side of faceZone
 //    source faceZoneToCell;
+//    sourceInfo
 //    {
 //        name ".*Zone";      // Name of faceZone, regular expressions allowed
 //        option master;      // master/slave
@@ -58,6 +62,7 @@ FoamFile
 //
 //    // Select based on faceSet
 //    source faceToCell;
+//    sourceInfo
 //    {
 //        set f0;             // Name of faceSet
 //
@@ -69,6 +74,7 @@ FoamFile
 //
 //    // Select based on pointSet
 //    source pointToCell;
+//    sourceInfo
 //    {
 //        set p0;
 //        option any;         // cell with any point in pointSet
@@ -77,12 +83,14 @@ FoamFile
 //
 //    // Select based on cellShape
 //    source shapeToCell;
+//    sourceInfo
 //    {
 //        type hex;           // hex/wedge/prism/pyr/tet/tetWedge/splitHex
 //    }
 //
 //    // Cells with cell centre within box
 //    source boxToCell;
+//    sourceInfo
 //    {
 //       box   (0 0 0) (1 1 1);
 //    }
@@ -90,6 +98,7 @@ FoamFile
 //    // Cells with cell centre within box
 //    // Is skewed, rotated box. Given as origin and three spanning vectors.
 //    source rotatedBoxToCell;
+//    sourceInfo
 //    {
 //       origin   (0.2 0.2 -10);
 //       i        (0.2 0.2 0);
@@ -99,6 +108,7 @@ FoamFile
 //
 //    // Cells with centre within cylinder
 //    source cylinderToCell;
+//    sourceInfo
 //    {
 //       p1       (0.2 0.2 -10); // start point on cylinder axis
 //       p2       (0.2 0.2 0);   // end point on cylinder axis
@@ -107,6 +117,7 @@ FoamFile
 //
 //    // Cells with centre within sphere
 //    source sphereToCell;
+//    sourceInfo
 //    {
 //       centre   (0.2 0.2 -10);
 //       radius   5.0;
@@ -114,12 +125,14 @@ FoamFile
 //
 //    // Cells with cellCentre nearest to coordinates
 //    source nearestToCell;
+//    sourceInfo
 //    {
 //       points ((0 0 0) (1 1 1)(2 2 2));
 //    }
 //
 //    // Select based on surface
 //    source surfaceToCell;
+//    sourceInfo
 //    {
 //        file            "www.avl.com-geometry.stl";
 //        outsidePoints   ((-99 -99 -59));    // definition of outside
@@ -135,6 +148,7 @@ FoamFile
 //
 //    // values of field within certain range
 //    source fieldToCell;
+//    sourceInfo
 //    {
 //        fieldName   U;      // Note: uses mag(U) since volVectorField
 //        min         0.1;
@@ -143,6 +157,7 @@ FoamFile
 //
 //    // Mesh region (non-face connected part of (subset of)mesh)
 //    source regionToCell;
+//    sourceInfo
 //    {
 //        set         c0;         // name of cellSet giving mesh subset
 //        insidePoint (1 2 3);    // point inside region to select
@@ -155,12 +170,14 @@ FoamFile
 //
 //    // Copy elements from faceSet
 //    source faceToFace;
+//    sourceInfo
 //    {
 //        set f1;
 //    }
 //
 //    // Select based on cellSet
 //    source cellToFace;
+//    sourceInfo
 //    {
 //        set c0;
 //        option all;         // All faces of cells
@@ -169,6 +186,7 @@ FoamFile
 //
 //    // Select based on pointSet
 //    source pointToFace;
+//    sourceInfo
 //    {
 //        set p0;
 //        option any;         // Faces using any point in pointSet
@@ -177,30 +195,35 @@ FoamFile
 //
 //    //  Select by explicitly providing face labels
 //    source labelToFace;
+//    sourceInfo
 //    {
 //        value (12 13 56);   // labels of faces
 //    }
 //
 //    // All faces of patch
 //    source patchToFace;
+//    sourceInfo
 //    {
 //        name ".*Wall";      // Name of patch, regular expressions allowed
 //    }
 //
 //    // All faces of faceZone
 //    source zoneToFace;
+//    sourceInfo
 //    {
 //        name ".*Zone1";     // Name of faceZone, regular expressions allowed
 //    }
 //
 //    // Faces with face centre within box
 //    source boxToFace;
+//    sourceInfo
 //    {
 //        box  (0 0 0) (1 1 1);
 //    }
 //
 //    // Faces with normal to within certain angle aligned with vector.
 //    source normalToFace;
+//    sourceInfo
 //    {
 //        normal (0 0 1);     // Vector
 //        cos     0.01;       // Tolerance (max cos of angle)
@@ -213,12 +236,14 @@ FoamFile
 //
 //    // Copy elements from pointSet
 //    source pointToPoint;
+//    sourceInfo
 //    {
 //        set p1;
 //    }
 //
 //    // Select based on cellSet
 //    source cellToPoint;
+//    sourceInfo
 //    {
 //        set c0;
 //        option all;         // all points of cell
@@ -226,6 +251,7 @@ FoamFile
 //
 //    // Select based on faceSet
 //    source faceToPoint;
+//    sourceInfo
 //    {
 //        set f0;             // name of faceSet
 //        option all;         // all points of face
@@ -233,30 +259,35 @@ FoamFile
 //
 //    // Select by explicitly providing point labels
 //    source labelToPoint;
+//    sourceInfo
 //    {
 //        value (12 13 56);   // labels of points
 //    }
 //
 //    // All points in pointzone
 //    source zoneToPoint;
+//    sourceInfo
 //    {
 //        name ".*Zone";      // name of pointZone, regular expressions allowed
 //    }
 //
 //    // Points nearest to coordinates
 //    source nearestToPoint;
+//    sourceInfo
 //    {
 //       points ((0 0 0) (1 1 1));
 //    }
 //
 //    // Points with coordinate within box
 //    source boxToPoint;
+//    sourceInfo
 //    {
 //       box   (0 0 0) (1 1 1);
 //    }
 //
 //    // Select based on surface
 //    source surfaceToPoint;
+//    sourceInfo
 //    {
 //        file            "www.avl.com-geometry.stl";
 //        nearDistance    0.1;    // points near to surface
@@ -275,6 +306,7 @@ FoamFile
 //
 //    // Select based on cellSet
 //    source setToCellZone;
+//    sourceInfo
 //    {
 //        set c0;           // name of cellSet
 //    }
@@ -285,12 +317,14 @@ FoamFile
 // ~~~~~~~~~~~
 //    // Select based on faceSet without orientation
 //    source setToFaceZone;
+//    sourceInfo
 //    {
 //        set f0;           // name of faceSet
 //    }
 //
 //    // Select based on faceSet, using cellSet to determine orientation
 //    source setsToFaceZone;
+//    sourceInfo
 //    {
 //        faceSet f0;       // name of faceSet
 //        cellSet c0;       // name of cellSet of slave side
diff --git a/applications/utilities/parallelProcessing/decomposePar/Make/files b/applications/utilities/parallelProcessing/decomposePar/Make/files
index 125f6b81e70155299ceff3857b31f7c0326d7090..cad5ac1ce3fba213b585ad2d7e3dff96b3bb9054 100644
--- a/applications/utilities/parallelProcessing/decomposePar/Make/files
+++ b/applications/utilities/parallelProcessing/decomposePar/Make/files
@@ -3,7 +3,6 @@ domainDecomposition.C
 domainDecompositionMesh.C
 domainDecompositionDistribute.C
 dimFieldDecomposer.C
-fvFieldDecomposer.C
 pointFieldDecomposer.C
 lagrangianFieldDecomposer.C
 
diff --git a/applications/utilities/parallelProcessing/decomposePar/Make/options b/applications/utilities/parallelProcessing/decomposePar/Make/options
index 7a9f1df3f592ddf510c6a99c6754d3dc5cd20ecb..7194eb1bce4743f0b8a0e7961ef91c49d903a339 100644
--- a/applications/utilities/parallelProcessing/decomposePar/Make/options
+++ b/applications/utilities/parallelProcessing/decomposePar/Make/options
@@ -1,4 +1,5 @@
 EXE_INC = \
+    -I$(LIB_SRC)/parallel/decompose/decompose/lnInclude \
     -I$(LIB_SRC)/parallel/decompose/decompositionMethods/lnInclude \
     -I$(LIB_SRC)/finiteVolume/lnInclude \
     -I$(LIB_SRC)/lagrangian/basic/lnInclude \
@@ -6,6 +7,7 @@ EXE_INC = \
 
 EXE_LIBS = \
     -lfiniteVolume \
+    -ldecompose \
     -lgenericPatchFields \
     -ldecompositionMethods -L$(FOAM_LIBBIN)/dummy -lmetisDecomp -lscotchDecomp \
     -llagrangian \
diff --git a/applications/utilities/postProcessing/foamCalc/foamCalcApp.C b/applications/utilities/postProcessing/foamCalc/foamCalcApp.C
index e9fb6975700d7a74a5cd43244bdd1154f07d2a9e..39d0a581d509bc84a2dd95a7f6310f72c97d6b64 100644
--- a/applications/utilities/postProcessing/foamCalc/foamCalcApp.C
+++ b/applications/utilities/postProcessing/foamCalc/foamCalcApp.C
@@ -43,6 +43,7 @@ Description
 int main(int argc, char *argv[])
 {
     Foam::timeSelector::addOptions();
+#   include "addRegionOption.H"
     Foam::argList::addBoolOption
     (
         "noWrite",
@@ -74,7 +75,7 @@ int main(int argc, char *argv[])
 #   include "setRootCase.H"
 #   include "createTime.H"
     Foam::instantList timeDirs = Foam::timeSelector::select0(runTime, args);
-#   include "createMesh.H"
+#   include "createNamedMesh.H"
 
     utility().tryPreCalc(args, runTime, mesh);
 
diff --git a/applications/utilities/postProcessing/miscellaneous/execFlowFunctionObjects/execFlowFunctionObjects.C b/applications/utilities/postProcessing/miscellaneous/execFlowFunctionObjects/execFlowFunctionObjects.C
index fe84a1daa040c649056250bb4c1cf6e5059a34ab..f0487ac2a2a5c5c9b62ff39ba8168c93a1615099 100644
--- a/applications/utilities/postProcessing/miscellaneous/execFlowFunctionObjects/execFlowFunctionObjects.C
+++ b/applications/utilities/postProcessing/miscellaneous/execFlowFunctionObjects/execFlowFunctionObjects.C
@@ -37,6 +37,11 @@ Description
 
 #include "calc.H"
 
+#include "volFields.H"
+#include "surfaceFields.H"
+#include "pointFields.H"
+#include "ReadFields.H"
+
 #include "incompressible/singlePhaseTransportModel/singlePhaseTransportModel.H"
 
 #include "incompressible/RAS/RASModel/RASModel.H"
@@ -84,203 +89,268 @@ namespace Foam
 
 void Foam::calc(const argList& args, const Time& runTime, const fvMesh& mesh)
 {
-    Info<< "    Reading phi" << endl;
-    surfaceScalarField phi
-    (
-        IOobject
-        (
-            "phi",
-            runTime.timeName(),
-            mesh,
-            IOobject::MUST_READ
-        ),
-        mesh
-    );
-
-    Info<< "    Reading U" << endl;
-    volVectorField U
-    (
-        IOobject
-        (
-            "U",
-            runTime.timeName(),
-            mesh,
-            IOobject::MUST_READ
-        ),
-        mesh
-    );
-
-    Info<< "    Reading p" << endl;
-    volScalarField p
-    (
-        IOobject
-        (
-            "p",
-            runTime.timeName(),
-            mesh,
-            IOobject::MUST_READ
-        ),
-        mesh
-    );
-
-    if (phi.dimensions() == dimensionSet(0, 3, -1, 0, 0))
+    if (args.optionFound("noFlow"))
     {
-        IOobject RASPropertiesHeader
-        (
-            "RASProperties",
-            runTime.constant(),
-            mesh,
-            IOobject::MUST_READ_IF_MODIFIED,
-            IOobject::NO_WRITE,
-            false
-        );
+        Info<< "    Operating in no-flow mode; no models will be loaded."
+            << " All vol, surface and point fields will be loaded." << endl;
 
-        IOobject LESPropertiesHeader
-        (
-            "LESProperties",
-            runTime.constant(),
-            mesh,
-            IOobject::MUST_READ_IF_MODIFIED,
-            IOobject::NO_WRITE,
-            false
-        );
+        // Read objects in time directory
+        IOobjectList objects(mesh, runTime.timeName());
 
-        if (RASPropertiesHeader.headerOk())
-        {
-            IOdictionary RASProperties(RASPropertiesHeader);
+        // Read vol fields.
 
-            singlePhaseTransportModel laminarTransport(U, phi);
+        PtrList<volScalarField> vsFlds;
+        ReadFields(mesh, objects, vsFlds);
 
-            autoPtr<incompressible::RASModel> RASModel
-            (
-                incompressible::RASModel::New
-                (
-                    U,
-                    phi,
-                    laminarTransport
-                )
-            );
-            execFlowFunctionObjects(args, runTime);
-        }
-        else if (LESPropertiesHeader.headerOk())
-        {
-            IOdictionary LESProperties(LESPropertiesHeader);
+        PtrList<volVectorField> vvFlds;
+        ReadFields(mesh, objects, vvFlds);
 
-            singlePhaseTransportModel laminarTransport(U, phi);
+        PtrList<volSphericalTensorField> vstFlds;
+        ReadFields(mesh, objects, vstFlds);
 
-            autoPtr<incompressible::LESModel> sgsModel
-            (
-                incompressible::LESModel::New(U, phi, laminarTransport)
-            );
+        PtrList<volSymmTensorField> vsymtFlds;
+        ReadFields(mesh, objects, vsymtFlds);
 
-            execFlowFunctionObjects(args, runTime);
-        }
-        else
-        {
-            IOdictionary transportProperties
-            (
-                IOobject
-                (
-                    "transportProperties",
-                    runTime.constant(),
-                    mesh,
-                    IOobject::MUST_READ_IF_MODIFIED,
-                    IOobject::NO_WRITE
-                )
-            );
+        PtrList<volTensorField> vtFlds;
+        ReadFields(mesh, objects, vtFlds);
 
-            dimensionedScalar nu(transportProperties.lookup("nu"));
+        // Read surface fields.
 
-            execFlowFunctionObjects(args, runTime);
-        }
+        PtrList<surfaceScalarField> ssFlds;
+        ReadFields(mesh, objects, ssFlds);
+
+        PtrList<surfaceVectorField> svFlds;
+        ReadFields(mesh, objects, svFlds);
+
+        PtrList<surfaceSphericalTensorField> sstFlds;
+        ReadFields(mesh, objects, sstFlds);
+
+        PtrList<surfaceSymmTensorField> ssymtFlds;
+        ReadFields(mesh, objects, ssymtFlds);
+
+        PtrList<surfaceTensorField> stFlds;
+        ReadFields(mesh, objects, stFlds);
+
+        // Read point fields.
+        const pointMesh& pMesh = pointMesh::New(mesh);
+
+        PtrList<pointScalarField> psFlds;
+        ReadFields(pMesh, objects, psFlds);
+
+        PtrList<pointVectorField> pvFlds;
+        ReadFields(pMesh, objects, pvFlds);
+
+        PtrList<pointSphericalTensorField> pstFlds;
+        ReadFields(pMesh, objects, pstFlds);
+
+        PtrList<pointSymmTensorField> psymtFlds;
+        ReadFields(pMesh, objects, psymtFlds);
+
+        PtrList<pointTensorField> ptFlds;
+        ReadFields(pMesh, objects, ptFlds);
+
+        execFlowFunctionObjects(args, runTime);
     }
-    else if (phi.dimensions() == dimensionSet(1, 0, -1, 0, 0))
+    else
     {
-        autoPtr<basicPsiThermo> thermo(basicPsiThermo::New(mesh));
-
-        volScalarField rho
+        Info<< "    Reading phi" << endl;
+        surfaceScalarField phi
         (
             IOobject
             (
-                "rho",
+                "phi",
                 runTime.timeName(),
-                mesh
+                mesh,
+                IOobject::MUST_READ
             ),
-            thermo->rho()
+            mesh
         );
 
-        IOobject RASPropertiesHeader
+        Info<< "    Reading U" << endl;
+        volVectorField U
         (
-            "RASProperties",
-            runTime.constant(),
-            mesh,
-            IOobject::MUST_READ_IF_MODIFIED,
-            IOobject::NO_WRITE,
-            false
+            IOobject
+            (
+                "U",
+                runTime.timeName(),
+                mesh,
+                IOobject::MUST_READ
+            ),
+            mesh
         );
 
-        IOobject LESPropertiesHeader
+        Info<< "    Reading p" << endl;
+        volScalarField p
         (
-            "LESProperties",
-            runTime.constant(),
-            mesh,
-            IOobject::MUST_READ_IF_MODIFIED,
-            IOobject::NO_WRITE,
-            false
+            IOobject
+            (
+                "p",
+                runTime.timeName(),
+                mesh,
+                IOobject::MUST_READ
+            ),
+            mesh
         );
 
-        if (RASPropertiesHeader.headerOk())
+        if (phi.dimensions() == dimensionSet(0, 3, -1, 0, 0))
         {
-            IOdictionary RASProperties(RASPropertiesHeader);
-
-            autoPtr<compressible::RASModel> RASModel
+            IOobject RASPropertiesHeader
             (
-                compressible::RASModel::New
-                (
-                    rho,
-                    U,
-                    phi,
-                    thermo()
-                )
+                "RASProperties",
+                runTime.constant(),
+                mesh,
+                IOobject::MUST_READ_IF_MODIFIED,
+                IOobject::NO_WRITE,
+                false
             );
 
-            execFlowFunctionObjects(args, runTime);
-        }
-        else if (LESPropertiesHeader.headerOk())
-        {
-            IOdictionary LESProperties(LESPropertiesHeader);
-
-            autoPtr<compressible::LESModel> sgsModel
+            IOobject LESPropertiesHeader
             (
-                compressible::LESModel::New(rho, U, phi, thermo())
+                "LESProperties",
+                runTime.constant(),
+                mesh,
+                IOobject::MUST_READ_IF_MODIFIED,
+                IOobject::NO_WRITE,
+                false
             );
 
-            execFlowFunctionObjects(args, runTime);
+            if (RASPropertiesHeader.headerOk())
+            {
+                IOdictionary RASProperties(RASPropertiesHeader);
+
+                singlePhaseTransportModel laminarTransport(U, phi);
+
+                autoPtr<incompressible::RASModel> RASModel
+                (
+                    incompressible::RASModel::New
+                    (
+                        U,
+                        phi,
+                        laminarTransport
+                    )
+                );
+                execFlowFunctionObjects(args, runTime);
+            }
+            else if (LESPropertiesHeader.headerOk())
+            {
+                IOdictionary LESProperties(LESPropertiesHeader);
+
+                singlePhaseTransportModel laminarTransport(U, phi);
+
+                autoPtr<incompressible::LESModel> sgsModel
+                (
+                    incompressible::LESModel::New(U, phi, laminarTransport)
+                );
+
+                execFlowFunctionObjects(args, runTime);
+            }
+            else
+            {
+                IOdictionary transportProperties
+                (
+                    IOobject
+                    (
+                        "transportProperties",
+                        runTime.constant(),
+                        mesh,
+                        IOobject::MUST_READ_IF_MODIFIED,
+                        IOobject::NO_WRITE
+                    )
+                );
+
+                dimensionedScalar nu(transportProperties.lookup("nu"));
+
+                execFlowFunctionObjects(args, runTime);
+            }
         }
-        else
+        else if (phi.dimensions() == dimensionSet(1, 0, -1, 0, 0))
         {
-            IOdictionary transportProperties
+            autoPtr<basicPsiThermo> thermo(basicPsiThermo::New(mesh));
+
+            volScalarField rho
             (
                 IOobject
                 (
-                    "transportProperties",
-                    runTime.constant(),
-                    mesh,
-                    IOobject::MUST_READ_IF_MODIFIED,
-                    IOobject::NO_WRITE
-                )
+                    "rho",
+                    runTime.timeName(),
+                    mesh
+                ),
+                thermo->rho()
+            );
+
+            IOobject RASPropertiesHeader
+            (
+                "RASProperties",
+                runTime.constant(),
+                mesh,
+                IOobject::MUST_READ_IF_MODIFIED,
+                IOobject::NO_WRITE,
+                false
+            );
+
+            IOobject LESPropertiesHeader
+            (
+                "LESProperties",
+                runTime.constant(),
+                mesh,
+                IOobject::MUST_READ_IF_MODIFIED,
+                IOobject::NO_WRITE,
+                false
             );
 
-            dimensionedScalar mu(transportProperties.lookup("mu"));
+            if (RASPropertiesHeader.headerOk())
+            {
+                IOdictionary RASProperties(RASPropertiesHeader);
 
-            execFlowFunctionObjects(args, runTime);
+                autoPtr<compressible::RASModel> RASModel
+                (
+                    compressible::RASModel::New
+                    (
+                        rho,
+                        U,
+                        phi,
+                        thermo()
+                    )
+                );
+
+                execFlowFunctionObjects(args, runTime);
+            }
+            else if (LESPropertiesHeader.headerOk())
+            {
+                IOdictionary LESProperties(LESPropertiesHeader);
+
+                autoPtr<compressible::LESModel> sgsModel
+                (
+                    compressible::LESModel::New(rho, U, phi, thermo())
+                );
+
+                execFlowFunctionObjects(args, runTime);
+            }
+            else
+            {
+                IOdictionary transportProperties
+                (
+                    IOobject
+                    (
+                        "transportProperties",
+                        runTime.constant(),
+                        mesh,
+                        IOobject::MUST_READ_IF_MODIFIED,
+                        IOobject::NO_WRITE
+                    )
+                );
+
+                dimensionedScalar mu(transportProperties.lookup("mu"));
+
+                execFlowFunctionObjects(args, runTime);
+            }
+        }
+        else
+        {
+            FatalErrorIn(args.executable())
+                << "Incorrect dimensions of phi: " << phi.dimensions()
+                << nl << exit(FatalError);
         }
-    }
-    else
-    {
-        FatalErrorIn(args.executable())
-            << "Incorrect dimensions of phi: " << phi.dimensions()
-            << nl << exit(FatalError);
     }
 }
 
diff --git a/applications/utilities/postProcessing/sampling/sample/sampleDict b/applications/utilities/postProcessing/sampling/sample/sampleDict
index 191e006d1af0926238b5e2a2365ec8a23f316fbe..9a77a6641738e71c7cb209a4b9548ffbc9ed5018 100644
--- a/applications/utilities/postProcessing/sampling/sample/sampleDict
+++ b/applications/utilities/postProcessing/sampling/sample/sampleDict
@@ -188,8 +188,25 @@ surfaces
         // cell, can be arbitrarily far away.
         type            patchInternalField;
         patches         ( ".*Wall.*" );
-        distance        0.0001;
         interpolate     true;
+
+
+        // Optional: specify how to obtain sampling points from the patch
+        //           face centres (default is 'normal')
+        //
+        //  //- Specify distance to offset in normal direction
+        offsetMode  normal;
+        distance    0.1;
+        //
+        //  //- Specify single uniform offset
+        //  offsetMode  uniform;
+        //  offset      (0 0 0.0001);
+        //
+        //  //- Specify offset per patch face
+        //  offsetMode  nonuniform;
+        //  offsets     ((0 0 0.0001) (0 0 0.0002));
+
+
         // Optional: whether to leave as faces (=default) or triangulate
         // triangulate     false;
     }
@@ -255,6 +272,7 @@ surfaces
         distance        0.0;
 
         interpolate     false;
+        regularise      false;       // Optional: do not simplify
         // mergeTol        1e-10;    // Optional: fraction of mesh bounding box
                                      // to merge points (default=1e-6)
     }
diff --git a/applications/utilities/postProcessing/velocityField/streamFunction/streamFunction.C b/applications/utilities/postProcessing/velocityField/streamFunction/streamFunction.C
index 850b8cbb5c7df5d64710c487da6c7b707efeafe5..c5c024b3ef5cf05998a554c8ffcc751fe76c10a7 100644
--- a/applications/utilities/postProcessing/velocityField/streamFunction/streamFunction.C
+++ b/applications/utilities/postProcessing/velocityField/streamFunction/streamFunction.C
@@ -42,13 +42,14 @@ Description
 int main(int argc, char *argv[])
 {
     timeSelector::addOptions();
+#   include "addRegionOption.H"
 
 #   include "setRootCase.H"
 #   include "createTime.H"
 
     instantList timeDirs = timeSelector::select0(runTime, args);
 
-#   include "createMeshNoClear.H"
+#   include "createNamedMesh.H"
 
     pointMesh pMesh(mesh);
 
diff --git a/etc/config/settings.csh b/etc/config/settings.csh
index 457c1fd8ad50000a62d72c746b2124a59c29d1ec..93f3e506abdff716446fbfd173f00d76a5e42fb6 100644
--- a/etc/config/settings.csh
+++ b/etc/config/settings.csh
@@ -486,6 +486,14 @@ case QSMPI:
     _foamAddLib     $MPI_ARCH_PATH/lib
     breaksw
 
+case SGIMPI:
+    setenv FOAM_MPI ${MPI_ROOT##*/}
+    setenv MPI_ARCH_PATH $MPI_ROOT
+
+    _foamAddPath    $MPI_ARCH_PATH/bin
+    _foamAddLib     $MPI_ARCH_PATH/lib
+    breaksw
+
 default:
     setenv FOAM_MPI dummy
     breaksw
diff --git a/etc/config/settings.sh b/etc/config/settings.sh
index 8297f43deaa486f393306606b8320d53c99a8a28..5111ef405a3152cf02d526e1322127e6a346e0a3 100644
--- a/etc/config/settings.sh
+++ b/etc/config/settings.sh
@@ -510,6 +510,14 @@ QSMPI)
     _foamAddLib     $MPI_ARCH_PATH/lib
     ;;
 
+SGIMPI)
+    export FOAM_MPI=${MPI_ROOT##*/}
+    export MPI_ARCH_PATH=$MPI_ROOT
+
+    _foamAddPath    $MPI_ARCH_PATH/bin
+    _foamAddLib     $MPI_ARCH_PATH/lib
+    ;;
+
 *)
     export FOAM_MPI=dummy
     ;;
diff --git a/src/OpenFOAM/db/functionObjects/OutputFilterFunctionObject/OutputFilterFunctionObject.C b/src/OpenFOAM/db/functionObjects/OutputFilterFunctionObject/OutputFilterFunctionObject.C
index effd031a1952cc8ea96da15b32f16ef61628b355..86a28677778d1ae1da2cfaae27fe8f510791474e 100644
--- a/src/OpenFOAM/db/functionObjects/OutputFilterFunctionObject/OutputFilterFunctionObject.C
+++ b/src/OpenFOAM/db/functionObjects/OutputFilterFunctionObject/OutputFilterFunctionObject.C
@@ -37,6 +37,18 @@ void Foam::OutputFilterFunctionObject<OutputFilter>::readDict()
     dict_.readIfPresent("dictionary", dictName_);
     dict_.readIfPresent("enabled", enabled_);
     dict_.readIfPresent("storeFilter", storeFilter_);
+    dict_.readIfPresent("timeStart", timeStart_);
+    dict_.readIfPresent("timeEnd", timeEnd_);
+}
+
+
+template<class OutputFilter>
+bool Foam::OutputFilterFunctionObject<OutputFilter>::active() const
+{
+    return
+        enabled_
+     && time_.value() >= timeStart_
+     && time_.value() <= timeEnd_;
 }
 
 
@@ -94,6 +106,8 @@ Foam::OutputFilterFunctionObject<OutputFilter>::OutputFilterFunctionObject
     dictName_(),
     enabled_(true),
     storeFilter_(true),
+    timeStart_(-VGREAT),
+    timeEnd_(VGREAT),
     outputControl_(t, dict)
 {
     readDict();
@@ -121,7 +135,7 @@ bool Foam::OutputFilterFunctionObject<OutputFilter>::start()
 {
     readDict();
 
-    if (enabled_&&storeFilter_)
+    if (enabled_ && storeFilter_)
     {
         allocateFilter();
     }
@@ -136,7 +150,7 @@ bool Foam::OutputFilterFunctionObject<OutputFilter>::execute
     const bool forceWrite
 )
 {
-    if (enabled_)
+    if (active())
     {
         if (!storeFilter_)
         {
@@ -163,7 +177,7 @@ bool Foam::OutputFilterFunctionObject<OutputFilter>::execute
 template<class OutputFilter>
 bool Foam::OutputFilterFunctionObject<OutputFilter>::end()
 {
-    if (enabled_)
+    if (active())
     {
         if (!storeFilter_)
         {
diff --git a/src/OpenFOAM/db/functionObjects/OutputFilterFunctionObject/OutputFilterFunctionObject.H b/src/OpenFOAM/db/functionObjects/OutputFilterFunctionObject/OutputFilterFunctionObject.H
index 35347f86d4ff8b5b230d01a7c4bbb40c06c3008e..0b264cb80602e7ba5877a9b973b9d7972a385c3a 100644
--- a/src/OpenFOAM/db/functionObjects/OutputFilterFunctionObject/OutputFilterFunctionObject.H
+++ b/src/OpenFOAM/db/functionObjects/OutputFilterFunctionObject/OutputFilterFunctionObject.H
@@ -68,18 +68,28 @@ class OutputFilterFunctionObject
         //- Input dictionary
         dictionary dict_;
 
-        //- Name of region
-        word regionName_;
 
-        //- Optional dictionary name to supply required inputs
-        word dictName_;
+        // Optional user inputs
 
-        //- Switch for the execution of the functionObject
-        bool enabled_;
+            //- Name of region - defaults to name of polyMesh::defaultRegion
+            word regionName_;
+
+            //- Dictionary name to supply required inputs
+            word dictName_;
+
+            //- Switch for the execution - defaults to 'yes/on'
+            bool enabled_;
+
+            //- Switch to store filter in between writes or use on-the-fly
+            //  construction - defaults to true
+            bool storeFilter_;
+
+            //- Activation time - defaults to -VGREAT
+            scalar timeStart_;
+
+            //- De-activation time - defaults to VGREAT
+            scalar timeEnd_;
 
-        //- Switch to store filter in between writes or use on-the-fly
-        //  construction
-        bool storeFilter_;
 
         //- Output controls
         outputFilterOutputControl outputControl_;
@@ -99,6 +109,9 @@ class OutputFilterFunctionObject
         //- Destroys most of the data associated with this object.
         void destroyFilter();
 
+        //- Returns true if active (enabled and within time bounds)
+        bool active() const;
+
         //- Disallow default bitwise copy construct
         OutputFilterFunctionObject(const OutputFilterFunctionObject&);
 
diff --git a/src/OpenFOAM/interpolations/interpolateSplineXY/interpolateSplineXY.C b/src/OpenFOAM/interpolations/interpolateSplineXY/interpolateSplineXY.C
index a73a7bc4e6d9adbabc61e8503dbda6a925ba38d9..c0720d90cbd345132f13a2c104f6c1d7e3c7c4d7 100644
--- a/src/OpenFOAM/interpolations/interpolateSplineXY/interpolateSplineXY.C
+++ b/src/OpenFOAM/interpolations/interpolateSplineXY/interpolateSplineXY.C
@@ -40,7 +40,7 @@ Foam::Field<Type> Foam::interpolateSplineXY
 
     forAll(xNew, i)
     {
-        yNew[i] = interpolateSmoothXY(xNew[i], xOld, yOld);
+        yNew[i] = interpolateSplineXY(xNew[i], xOld, yOld);
     }
 
     return yNew;
diff --git a/src/OpenFOAM/meshes/polyMesh/polyBoundaryMesh/polyBoundaryMesh.C b/src/OpenFOAM/meshes/polyMesh/polyBoundaryMesh/polyBoundaryMesh.C
index a520550c3fcfc36ec251f86a17802da131ac78ae..94a1597d96f2a1d648e3f7c4220b97a82df8be3a 100644
--- a/src/OpenFOAM/meshes/polyMesh/polyBoundaryMesh/polyBoundaryMesh.C
+++ b/src/OpenFOAM/meshes/polyMesh/polyBoundaryMesh/polyBoundaryMesh.C
@@ -514,7 +514,8 @@ Foam::label Foam::polyBoundaryMesh::whichPatch(const label faceIndex) const
         FatalErrorIn
         (
             "polyBoundaryMesh::whichPatch(const label faceIndex) const"
-        )   << "given label greater than the number of geometric faces"
+        )   << "given label " << faceIndex
+            << " greater than the number of geometric faces " << mesh().nFaces()
             << abort(FatalError);
     }
 
diff --git a/src/conversion/meshReader/starcd/STARCDMeshReader.C b/src/conversion/meshReader/starcd/STARCDMeshReader.C
index 6162da0f9b9bf0eac11b84cad9c6f700569dae68..a7aca36d7fc26199fa813b909f585488d57c455d 100644
--- a/src/conversion/meshReader/starcd/STARCDMeshReader.C
+++ b/src/conversion/meshReader/starcd/STARCDMeshReader.C
@@ -24,7 +24,7 @@ License
 \*---------------------------------------------------------------------------*/
 
 #include "STARCDMeshReader.H"
-#include "cyclicPolyPatch.H"
+#include "oldCyclicPolyPatch.H"
 #include "emptyPolyPatch.H"
 #include "wallPolyPatch.H"
 #include "symmetryPolyPatch.H"
@@ -950,7 +950,7 @@ void Foam::meshReaders::STARCD::readBoundary(const fileName& inputName)
         {
             // incorrect. should be cyclicPatch but this
             // requires info on connected faces.
-            patchTypes_[patchI] = cyclicPolyPatch::typeName;
+            patchTypes_[patchI] = oldCyclicPolyPatch::typeName;
             patchPhysicalTypes_[patchI] = patchTypes_[patchI];
         }
         else if (origType == "baffle")
diff --git a/src/dynamicFvMesh/dynamicRefineFvMesh/dynamicRefineFvMesh.C b/src/dynamicFvMesh/dynamicRefineFvMesh/dynamicRefineFvMesh.C
index a6a6545e9f3ee6bffdd39a53a3dc83665d312dd9..0af332a336de54520688e2108e15e03c61dd7b7d 100644
--- a/src/dynamicFvMesh/dynamicRefineFvMesh/dynamicRefineFvMesh.C
+++ b/src/dynamicFvMesh/dynamicRefineFvMesh/dynamicRefineFvMesh.C
@@ -186,7 +186,16 @@ void Foam::dynamicRefineFvMesh::readDict()
         ).subDict(typeName + "Coeffs")
     );
 
-    correctFluxes_ = List<Pair<word> >(refineDict.lookup("correctFluxes"));
+    List<Pair<word> > fluxVelocities = List<Pair<word> >
+    (
+        refineDict.lookup("correctFluxes")
+    );
+    // Rework into hashtable.
+    correctFluxes_.resize(fluxVelocities.size());
+    forAll(fluxVelocities, i)
+    {
+        correctFluxes_.insert(fluxVelocities[i][0], fluxVelocities[i][1]);
+    }
 
     dumpLevel_ = Switch(refineDict.lookup("dumpLevel"));
 }
@@ -289,23 +298,46 @@ Foam::dynamicRefineFvMesh::refine
                 << " split faces " << endl;
         }
 
-        forAll(correctFluxes_, i)
+        HashTable<const surfaceScalarField*> fluxes
+        (
+            lookupClass<surfaceScalarField>()
+        );
+        forAllConstIter(HashTable<const surfaceScalarField*>, fluxes, iter)
         {
+            if (!correctFluxes_.found(iter.key()))
+            {
+                WarningIn("dynamicRefineFvMesh::refine(const labelList&)")
+                    << "Cannot find surfaceScalarField " << iter.key()
+                    << " in user-provided flux mapping table "
+                    << correctFluxes_ << endl
+                    << "    The flux mapping table is used to recreate the"
+                    << " flux on newly created faces." << endl
+                    << "    Either add the entry if it is a flux or use ("
+                    << iter.key() << " none) to suppress this warning."
+                    << endl;
+                continue;
+            }
+
+            const word& UName = correctFluxes_[iter.key()];
+
+            if (UName == "none")
+            {
+                continue;
+            }
+
             if (debug)
             {
-                Info<< "Mapping flux " << correctFluxes_[i][0]
-                    << " using interpolated flux " << correctFluxes_[i][1]
+                Info<< "Mapping flux " << iter.key()
+                    << " using interpolated flux " << UName
                     << endl;
             }
-            surfaceScalarField& phi = const_cast<surfaceScalarField&>
-            (
-                lookupObject<surfaceScalarField>(correctFluxes_[i][0])
-            );
+
+            surfaceScalarField& phi = const_cast<surfaceScalarField&>(*iter());
             const surfaceScalarField phiU
             (
                 fvc::interpolate
                 (
-                    lookupObject<volVectorField>(correctFluxes_[i][1])
+                    lookupObject<volVectorField>(UName)
                 )
               & Sf()
             );
@@ -482,27 +514,51 @@ Foam::dynamicRefineFvMesh::unrefine
         const labelList& reversePointMap = map().reversePointMap();
         const labelList& reverseFaceMap = map().reverseFaceMap();
 
-        forAll(correctFluxes_, i)
+        HashTable<const surfaceScalarField*> fluxes
+        (
+            lookupClass<surfaceScalarField>()
+        );
+        forAllConstIter(HashTable<const surfaceScalarField*>, fluxes, iter)
         {
+            if (!correctFluxes_.found(iter.key()))
+            {
+                WarningIn("dynamicRefineFvMesh::refine(const labelList&)")
+                    << "Cannot find surfaceScalarField " << iter.key()
+                    << " in user-provided flux mapping table "
+                    << correctFluxes_ << endl
+                    << "    The flux mapping table is used to recreate the"
+                    << " flux on newly created faces." << endl
+                    << "    Either add the entry if it is a flux or use ("
+                    << iter.key() << " none) to suppress this warning."
+                    << endl;
+                continue;
+            }
+
+            const word& UName = correctFluxes_[iter.key()];
+
+            if (UName == "none")
+            {
+                continue;
+            }
+
             if (debug)
             {
-                Info<< "Mapping flux " << correctFluxes_[i][0]
-                    << " using interpolated flux " << correctFluxes_[i][1]
+                Info<< "Mapping flux " << iter.key()
+                    << " using interpolated flux " << UName
                     << endl;
             }
-            surfaceScalarField& phi = const_cast<surfaceScalarField&>
-            (
-                lookupObject<surfaceScalarField>(correctFluxes_[i][0])
-            );
-            surfaceScalarField phiU
+
+            surfaceScalarField& phi = const_cast<surfaceScalarField&>(*iter());
+            const surfaceScalarField phiU
             (
                 fvc::interpolate
                 (
-                    lookupObject<volVectorField>(correctFluxes_[i][1])
+                    lookupObject<volVectorField>(UName)
                 )
               & Sf()
             );
 
+
             forAllConstIter(Map<label>, faceToSplitPoint, iter)
             {
                 label oldFaceI = iter.key();
diff --git a/src/dynamicFvMesh/dynamicRefineFvMesh/dynamicRefineFvMesh.H b/src/dynamicFvMesh/dynamicRefineFvMesh/dynamicRefineFvMesh.H
index 06dfbd666d107ae2c1557908928210e94151deb4..2dfe09d07554706ef6246eca8d3a904f82fc0fdd 100644
--- a/src/dynamicFvMesh/dynamicRefineFvMesh/dynamicRefineFvMesh.H
+++ b/src/dynamicFvMesh/dynamicRefineFvMesh/dynamicRefineFvMesh.H
@@ -64,7 +64,7 @@ protected:
         Switch dumpLevel_;
 
         //- Fluxes to map
-        List<Pair<word> > correctFluxes_;
+        HashTable<word> correctFluxes_;
 
         //- Number of refinement/unrefinement steps done so far.
         label nRefinementIterations_;
diff --git a/src/finiteVolume/Make/files b/src/finiteVolume/Make/files
index aabb0a3ca371eb4e37e0bc6511079e7817893e87..971740c7dab76d78af367655372dfa0d47096db5 100644
--- a/src/finiteVolume/Make/files
+++ b/src/finiteVolume/Make/files
@@ -127,7 +127,6 @@ $(derivedFvPatchFields)/fan/fanFvPatchFields.C
 $(derivedFvPatchFields)/fanPressure/fanPressureFvPatchScalarField.C
 $(derivedFvPatchFields)/buoyantPressure/buoyantPressureFvPatchScalarField.C
 $(derivedFvPatchFields)/fixedFluxPressure/fixedFluxPressureFvPatchScalarField.C
-$(derivedFvPatchFields)/multiphaseFixedFluxPressure/multiphaseFixedFluxPressureFvPatchScalarField.C
 $(derivedFvPatchFields)/fixedInternalValueFvPatchField/fixedInternalValueFvPatchFields.C
 $(derivedFvPatchFields)/fixedNormalSlip/fixedNormalSlipFvPatchFields.C
 $(derivedFvPatchFields)/fixedPressureCompressibleDensity/fixedPressureCompressibleDensityFvPatchScalarField.C
diff --git a/src/finiteVolume/cfdTools/general/adjustPhi/adjustPhi.C b/src/finiteVolume/cfdTools/general/adjustPhi/adjustPhi.C
index 9eb89527f3e54695fd3589abb72d788dd72cd065..7c72beaf99d5a7c4fea84146b544b018de48d2f3 100644
--- a/src/finiteVolume/cfdTools/general/adjustPhi/adjustPhi.C
+++ b/src/finiteVolume/cfdTools/general/adjustPhi/adjustPhi.C
@@ -107,7 +107,7 @@ bool Foam::adjustPhi
         {
             massCorr = (massIn - fixedMassOut)/adjustableMassOut;
         }
-        else if (mag(fixedMassOut - massIn)/totalFlux > 1e-10)
+        else if (mag(fixedMassOut - massIn)/totalFlux > 1e-8)
         {
             FatalErrorIn
             (
diff --git a/src/finiteVolume/cfdTools/general/fieldSources/basicSource/radialActuationDiskSource/radialActuationDiskSourceTemplates.C b/src/finiteVolume/cfdTools/general/fieldSources/basicSource/radialActuationDiskSource/radialActuationDiskSourceTemplates.C
index 2fea641d30508a8d75e81ec7b5f40862d27d4703..6c8469fda8958d4276e14a586cb83974c02512b1 100644
--- a/src/finiteVolume/cfdTools/general/fieldSources/basicSource/radialActuationDiskSource/radialActuationDiskSourceTemplates.C
+++ b/src/finiteVolume/cfdTools/general/fieldSources/basicSource/radialActuationDiskSource/radialActuationDiskSourceTemplates.C
@@ -59,7 +59,7 @@ addRadialActuationDiskAxialInertialResistance
     const Field<scalar> zoneCellVolumes(mesh().cellVolumes(), cells);
 
     const vector avgCentre = gSum(zoneCellVolumes*zoneCellCentres)/V();
-    const scalar maxR = mag(max(zoneCellCentres - avgCentre));
+    const scalar maxR = gMax(mag(zoneCellCentres - avgCentre));
 
     scalar intCoeffs =
         coeffs_[0]
diff --git a/src/finiteVolume/cfdTools/general/solutionControl/pimpleControl/pimpleControl.C b/src/finiteVolume/cfdTools/general/solutionControl/pimpleControl/pimpleControl.C
index 8707d021ade2e0ea7b9ead32bcd52ddd2b0a4642..87c3f13090bf012ef6f41d39361664e04167ea2a 100644
--- a/src/finiteVolume/cfdTools/general/solutionControl/pimpleControl/pimpleControl.C
+++ b/src/finiteVolume/cfdTools/general/solutionControl/pimpleControl/pimpleControl.C
@@ -59,36 +59,37 @@ bool Foam::pimpleControl::criteriaSatisfied()
     bool firstIter = corr_ == 1;
 
     bool achieved = true;
-    const dictionary& solverDict = mesh_.solverPerformanceDict();
+    bool checked = false;    // safety that some checks were indeed performed
 
+    const dictionary& solverDict = mesh_.solverPerformanceDict();
     forAllConstIter(dictionary, solverDict, iter)
     {
         const word& variableName = iter().keyword();
-        label fieldI = applyToField(variableName);
+        const label fieldI = applyToField(variableName);
         if (fieldI != -1)
         {
             const List<lduMatrix::solverPerformance> sp(iter().stream());
             const scalar residual = sp.last().initialResidual();
 
+            checked = true;
+
             if (firstIter)
             {
                 residualControl_[fieldI].initialResidual =
                     sp.first().initialResidual();
             }
 
-            bool absCheck = residual < residualControl_[fieldI].absTol;
-
+            const bool absCheck = residual < residualControl_[fieldI].absTol;
             bool relCheck = false;
 
             scalar relative = 0.0;
             if (!firstIter)
             {
-                scalar iniRes =
+                const scalar iniRes =
                     residualControl_[fieldI].initialResidual
                   + ROOTVSMALL;
 
                 relative = residual/iniRes;
-
                 relCheck = relative < residualControl_[fieldI].relTol;
             }
 
@@ -110,7 +111,7 @@ bool Foam::pimpleControl::criteriaSatisfied()
         }
     }
 
-    return achieved;
+    return checked && achieved;
 }
 
 
@@ -129,7 +130,13 @@ Foam::pimpleControl::pimpleControl(fvMesh& mesh)
     if (nOuterCorr_ > 1)
     {
         Info<< nl;
-        if (!residualControl_.empty())
+        if (residualControl_.empty())
+        {
+            Info<< algorithmName_ << ": no residual control data found. "
+                << "Calculations will employ " << nOuterCorr_
+                << " corrector loops" << nl << endl;
+        }
+        else
         {
             Info<< algorithmName_ << ": max iterations = " << nOuterCorr_
                 << endl;
@@ -142,12 +149,6 @@ Foam::pimpleControl::pimpleControl(fvMesh& mesh)
             }
             Info<< endl;
         }
-        else
-        {
-            Info<< algorithmName_ << ": no residual control data found. " << nl
-                << "Calculations will employ " << nOuterCorr_
-                << " corrector loops" << nl << endl;
-        }
     }
     else
     {
diff --git a/src/finiteVolume/cfdTools/general/solutionControl/pimpleControl/pimpleControl.H b/src/finiteVolume/cfdTools/general/solutionControl/pimpleControl/pimpleControl.H
index 54831aa97d9bcee309dd2295019ae8fa5579bc28..3b891a5aa93097e3041aa042b97ee8482b3c17f6 100644
--- a/src/finiteVolume/cfdTools/general/solutionControl/pimpleControl/pimpleControl.H
+++ b/src/finiteVolume/cfdTools/general/solutionControl/pimpleControl/pimpleControl.H
@@ -69,10 +69,10 @@ protected:
 
     // Protected Member Functions
 
-        //- Read constrols from fvSolution dictionary
+        //- Read controls from fvSolution dictionary
         virtual void read();
 
-        //- Return true if all convergence checks are satified
+        //- Return true if all convergence checks are satisfied
         virtual bool criteriaSatisfied();
 
         //- Disallow default bitwise copy construct
diff --git a/src/finiteVolume/cfdTools/general/solutionControl/simpleControl/simpleControl.C b/src/finiteVolume/cfdTools/general/solutionControl/simpleControl/simpleControl.C
index f40f19e04af6ba8ad3886ea425edc0a95120e683..d2b603a5e01961e43e2ef3fa3c4344de0a3497ce 100644
--- a/src/finiteVolume/cfdTools/general/solutionControl/simpleControl/simpleControl.C
+++ b/src/finiteVolume/cfdTools/general/solutionControl/simpleControl/simpleControl.C
@@ -50,17 +50,20 @@ bool Foam::simpleControl::criteriaSatisfied()
     }
 
     bool achieved = true;
-    const dictionary& solverDict = mesh_.solverPerformanceDict();
+    bool checked = false;    // safety that some checks were indeed performed
 
+    const dictionary& solverDict = mesh_.solverPerformanceDict();
     forAllConstIter(dictionary, solverDict, iter)
     {
         const word& variableName = iter().keyword();
-        label fieldI = applyToField(variableName);
+        const label fieldI = applyToField(variableName);
         if (fieldI != -1)
         {
             const List<lduMatrix::solverPerformance> sp(iter().stream());
             const scalar residual = sp.first().initialResidual();
 
+            checked = true;
+
             bool absCheck = residual < residualControl_[fieldI].absTol;
             achieved = achieved && absCheck;
 
@@ -75,7 +78,7 @@ bool Foam::simpleControl::criteriaSatisfied()
         }
     }
 
-    return achieved;
+    return checked && achieved;
 }
 
 
@@ -90,7 +93,13 @@ Foam::simpleControl::simpleControl(fvMesh& mesh)
 
     Info<< nl;
 
-    if (residualControl_.size() > 0)
+    if (residualControl_.empty())
+    {
+        Info<< algorithmName_ << ": no convergence criteria found. "
+            << "Calculations will run for " << mesh_.time().endTime().value()
+            << " steps." << nl << endl;
+    }
+    else
     {
         Info<< algorithmName_ << ": convergence criteria" << nl;
         forAll(residualControl_, i)
@@ -101,12 +110,6 @@ Foam::simpleControl::simpleControl(fvMesh& mesh)
         }
         Info<< endl;
     }
-    else
-    {
-        Info<< algorithmName_ << ": no convergence criteria found. "
-            << "Calculations will run for " << mesh_.time().endTime().value()
-            << " steps." << nl << endl;
-    }
 }
 
 
diff --git a/src/finiteVolume/cfdTools/general/solutionControl/simpleControl/simpleControl.H b/src/finiteVolume/cfdTools/general/solutionControl/simpleControl/simpleControl.H
index e4a2e69cbaea328c943ee04522ccf310983c3d02..ee718ce424b884e6c894e2c1acdb12e5888397ca 100644
--- a/src/finiteVolume/cfdTools/general/solutionControl/simpleControl/simpleControl.H
+++ b/src/finiteVolume/cfdTools/general/solutionControl/simpleControl/simpleControl.H
@@ -59,10 +59,10 @@ protected:
 
     // Protected Member Functions
 
-        //- Read constrols from fvSolution dictionary
+        //- Read controls from fvSolution dictionary
         void read();
 
-        //- Return true if all convergence checks are satified
+        //- Return true if all convergence checks are satisfied
         bool criteriaSatisfied();
 
         //- Disallow default bitwise copy construct
diff --git a/src/finiteVolume/cfdTools/general/solutionControl/solutionControl/solutionControl.C b/src/finiteVolume/cfdTools/general/solutionControl/solutionControl/solutionControl.C
index e1ea4007d539ad2f340543294d3a75b4b19cbba5..1e4eadce045033a3b7b5a91328eb83de51d74625 100644
--- a/src/finiteVolume/cfdTools/general/solutionControl/solutionControl/solutionControl.C
+++ b/src/finiteVolume/cfdTools/general/solutionControl/solutionControl/solutionControl.C
@@ -76,7 +76,8 @@ void Foam::solutionControl::read(const bool absTolOnly)
                 {
                     FatalErrorIn("bool Foam::solutionControl::read()")
                         << "Residual data for " << iter().keyword()
-                        << " must be specified as a dictionary";
+                        << " must be specified as a dictionary"
+                        << exit(FatalError);
                 }
             }
 
diff --git a/src/finiteVolume/cfdTools/general/solutionControl/solutionControl/solutionControl.H b/src/finiteVolume/cfdTools/general/solutionControl/solutionControl/solutionControl.H
index 75565551a290e5b4d9a6dd736f73ed8b188457bc..82dd73dd9a11d9ee814f391f2dde40d82f08957d 100644
--- a/src/finiteVolume/cfdTools/general/solutionControl/solutionControl/solutionControl.H
+++ b/src/finiteVolume/cfdTools/general/solutionControl/solutionControl/solutionControl.H
@@ -40,7 +40,7 @@ namespace Foam
 {
 
 /*---------------------------------------------------------------------------*\
-                  Class solutionControl Declaration
+                       Class solutionControl Declaration
 \*---------------------------------------------------------------------------*/
 
 class solutionControl
@@ -78,19 +78,19 @@ protected:
             //- Flag to indicate to solve for momentum
             bool momentumPredictor_;
 
-            //- Flag to indictae to solve using transonic algorithm
+            //- Flag to indicate to solve using transonic algorithm
             bool transonic_;
 
 
     // Protected Member Functions
 
-        //- Read constrols from fvSolution dictionary
+        //- Read controls from fvSolution dictionary
         virtual void read(const bool absTolOnly);
 
         //- Return index of field in residualControl_ if present
         virtual label applyToField(const word& fieldName) const;
 
-        //- Return true if all convergence checks are satified
+        //- Return true if all convergence checks are satisfied
         virtual bool criteriaSatisfied() = 0;
 
         //- Store previous iteration fields
@@ -142,7 +142,7 @@ public:
             //- Flag to indicate to solve for momentum
             inline bool momentumPredictor() const;
 
-            //- Flag to indictae to solve using transonic algorithm
+            //- Flag to indicate to solve using transonic algorithm
             inline bool transonic() const;
 };
 
diff --git a/src/finiteVolume/fields/fvPatchFields/derived/mappedField/mappedFieldFvPatchField.C b/src/finiteVolume/fields/fvPatchFields/derived/mappedField/mappedFieldFvPatchField.C
index e02fa12ef21db3ea38329a04fc7af9ba13386ded..ae597b4bfccd5b97ef7a2cda69a9623c62b4d16f 100644
--- a/src/finiteVolume/fields/fvPatchFields/derived/mappedField/mappedFieldFvPatchField.C
+++ b/src/finiteVolume/fields/fvPatchFields/derived/mappedField/mappedFieldFvPatchField.C
@@ -204,14 +204,13 @@ void mappedFieldFvPatchField<Type>::updateCoeffs()
     {
         case NEARESTCELL:
         {
-            const mapDistribute& distMap = mappedPatchBase::map();
             newValues = sampleField();
 
-            distMap.distribute(newValues);
+            this->distribute(newValues);
 
             break;
         }
-        case NEARESTPATCHFACE:
+        case NEARESTPATCHFACE: case NEARESTPATCHFACEAMI:
         {
             const label nbrPatchID =
                 nbrMesh.boundaryMesh().findPatchID(samplePatch());
@@ -228,36 +227,8 @@ void mappedFieldFvPatchField<Type>::updateCoeffs()
 
             const fieldType& nbrField = sampleField();
 
-            const mapDistribute& distMap = mappedPatchBase::map();
             newValues = nbrField.boundaryField()[nbrPatchID];
-            distMap.distribute(newValues);
-
-            break;
-        }
-        case mappedPatchBase::NEARESTPATCHFACEAMI:
-        {
-            const label nbrPatchID =
-                nbrMesh.boundaryMesh().findPatchID(samplePatch());
-
-            if (nbrPatchID < 0)
-            {
-                FatalErrorIn
-                (
-                    "void mappedFixedValueFvPatchField<Type>::updateCoeffs()"
-                )<< "Unable to find sample patch " << samplePatch()
-                 << " in region " << sampleRegion()
-                 << " for patch " << this->patch().name() << nl
-                 << abort(FatalError);
-            }
-
-//            const fieldType& nbrField = sampleField();
-//            newValues = mpp.AMI().interpolateToSource(nbrField);
-
-            notImplemented
-            (
-                "void mappedFieldFvPatchField<Type>::updateCoeffs() "
-                "with mappedPatchBase::NEARESTPATCHFACEAMI"
-            );
+            this->distribute(newValues);
 
             break;
         }
@@ -279,9 +250,7 @@ void mappedFieldFvPatchField<Type>::updateCoeffs()
                 }
             }
 
-            const mapDistribute& distMap = mappedPatchBase::map();
-            distMap.distribute(allValues);
-
+            this->distribute(allValues);
             newValues.transfer(allValues);
 
             break;
diff --git a/src/finiteVolume/fields/fvPatchFields/derived/mappedFixedInternalValue/mappedFixedInternalValueFvPatchField.C b/src/finiteVolume/fields/fvPatchFields/derived/mappedFixedInternalValue/mappedFixedInternalValueFvPatchField.C
index 8920d39502a15425d54159a66aeba9f9fe7c3ace..819f39ecfb88b20368f1f8c6db3522d87066fc36 100644
--- a/src/finiteVolume/fields/fvPatchFields/derived/mappedFixedInternalValue/mappedFixedInternalValueFvPatchField.C
+++ b/src/finiteVolume/fields/fvPatchFields/derived/mappedFixedInternalValue/mappedFixedInternalValueFvPatchField.C
@@ -114,43 +114,66 @@ void Foam::mappedFixedInternalValueFvPatchField<Type>::updateCoeffs()
     const mappedPatchBase& mpp =
         refCast<const mappedPatchBase>(this->patch().patch());
     const fvMesh& nbrMesh = refCast<const fvMesh>(mpp.sampleMesh());
-    const label samplePatchI = mpp.samplePolyPatch().index();
-    const fvPatch& nbrPatch = nbrMesh.boundary()[samplePatchI];
 
-
-    // Retrieve the neighbour field
-    const fvPatchField<Type>& nbrField =
-        nbrPatch.template lookupPatchField<FieldType, Type>
-        (
-            this->dimensionedInternalField().name()
-        );
-
-    // Retrieve the neighbour patch internal field
-    Field<Type> nbrIntFld(nbrField.patchInternalField());
+    Field<Type> nbrIntFld;
 
     switch (mpp.mode())
     {
-        case (mappedPatchBase::NEARESTPATCHFACEAMI):
+        case mappedPatchBase::NEARESTCELL:
         {
-            // Retrieve the neighbour patch internal field
-            nbrIntFld = mpp.AMI().interpolateToSource(nbrIntFld);
+            FatalErrorIn
+            (
+                "void mappedFixedValueFvPatchField<Type>::updateCoeffs()"
+            )   << "Cannot apply "
+                << mappedPatchBase::sampleModeNames_
+                   [
+                       mappedPatchBase::NEARESTCELL
+                   ]
+                << " mapping mode for patch " << this->patch().name()
+                << exit(FatalError);
+
             break;
         }
-        default:
+        case mappedPatchBase::NEARESTPATCHFACE:
         {
-            const mapDistribute& distMap = mpp.map();
+            const label samplePatchI = mpp.samplePolyPatch().index();
+            const fvPatchField<Type>& nbrPatchField =
+                this->sampleField().boundaryField()[samplePatchI];
+            nbrIntFld = nbrPatchField.patchInternalField();
+            mpp.distribute(nbrIntFld);
+
+            break;
+        }
+        case mappedPatchBase::NEARESTFACE:
+        {
+            Field<Type> allValues(nbrMesh.nFaces(), pTraits<Type>::zero);
+
+            const FieldType& nbrField = this->sampleField();
+
+            forAll(nbrField.boundaryField(), patchI)
+            {
+                const fvPatchField<Type>& pf = nbrField.boundaryField()[patchI];
+                const Field<Type> pif(pf.patchInternalField());
+
+                label faceStart = pf.patch().start();
+
+                forAll(pf, faceI)
+                {
+                    allValues[faceStart++] = pif[faceI];
+                }
+            }
+
+            mpp.distribute(allValues);
+            nbrIntFld.transfer(allValues);
 
-            mapDistribute::distribute
-            (
-                Pstream::defaultCommsType,
-                distMap.schedule(),
-                distMap.constructSize(),
-                distMap.subMap(),           // what to send
-                distMap.constructMap(),     // what to receive
-                nbrIntFld
-            );
             break;
         }
+        default:
+        {
+            FatalErrorIn("mappedFixedValueFvPatchField<Type>::updateCoeffs()")
+                << "Unknown sampling mode: " << mpp.mode()
+                << abort(FatalError);
+        }
     }
 
     // Restore tag
diff --git a/src/finiteVolume/fields/fvPatchFields/derived/mappedFixedValue/mappedFixedValueFvPatchField.C b/src/finiteVolume/fields/fvPatchFields/derived/mappedFixedValue/mappedFixedValueFvPatchField.C
index ffe8960fa71132d5b11b82593d9e8288e42042e4..930a931206a754ebd5711cc16f3463ab6346e02f 100644
--- a/src/finiteVolume/fields/fvPatchFields/derived/mappedFixedValue/mappedFixedValueFvPatchField.C
+++ b/src/finiteVolume/fields/fvPatchFields/derived/mappedFixedValue/mappedFixedValueFvPatchField.C
@@ -283,30 +283,6 @@ void mappedFixedValueFvPatchField<Type>::updateCoeffs()
             break;
         }
         case mappedPatchBase::NEARESTPATCHFACE:
-        {
-            const mapDistribute& distMap = mpp.map();
-
-            const label nbrPatchID =
-                nbrMesh.boundaryMesh().findPatchID(mpp.samplePatch());
-
-            if (nbrPatchID < 0)
-            {
-                FatalErrorIn
-                (
-                    "void mappedFixedValueFvPatchField<Type>::updateCoeffs()"
-                )<< "Unable to find sample patch " << mpp.samplePatch()
-                 << " in region " << mpp.sampleRegion()
-                 << " for patch " << this->patch().name() << nl
-                 << abort(FatalError);
-            }
-
-            const fieldType& nbrField = sampleField();
-
-            newValues = nbrField.boundaryField()[nbrPatchID];
-            distMap.distribute(newValues);
-
-            break;
-        }
         case mappedPatchBase::NEARESTPATCHFACEAMI:
         {
             const label nbrPatchID =
@@ -324,9 +300,9 @@ void mappedFixedValueFvPatchField<Type>::updateCoeffs()
             }
 
             const fieldType& nbrField = sampleField();
-            newValues = nbrField.boundaryField()[nbrPatchID];
 
-            newValues = mpp.AMI().interpolateToSource(newValues);
+            newValues = nbrField.boundaryField()[nbrPatchID];
+            mpp.distribute(newValues);
 
             break;
         }
diff --git a/src/finiteVolume/fields/fvPatchFields/derived/mappedFixedValue/mappedFixedValueFvPatchField.H b/src/finiteVolume/fields/fvPatchFields/derived/mappedFixedValue/mappedFixedValueFvPatchField.H
index b7838497e5a2ce3f661f9dbc33b2a00c1ef945eb..d60ae3bc3ca88960b8dba13f230c8a55479fdde4 100644
--- a/src/finiteVolume/fields/fvPatchFields/derived/mappedFixedValue/mappedFixedValueFvPatchField.H
+++ b/src/finiteVolume/fields/fvPatchFields/derived/mappedFixedValue/mappedFixedValueFvPatchField.H
@@ -71,7 +71,10 @@ class mappedFixedValueFvPatchField
 :
     public fixedValueFvPatchField<Type>
 {
-    // Private data
+
+protected:
+
+    // Protected data
 
         //- Name of field to sample - defaults to field associated with this
         //  patchField if not specified
@@ -90,7 +93,7 @@ class mappedFixedValueFvPatchField
         mutable autoPtr<interpolation<Type> > interpolator_;
 
 
-    // Private Member Functions
+    // Protected Member Functions
 
         //- Field to sample. Either on my or nbr mesh
         const GeometricField<Type, fvPatchField, volMesh>& sampleField() const;
diff --git a/src/finiteVolume/fields/fvPatchFields/derived/mappedFlowRate/mappedFlowRateFvPatchVectorField.C b/src/finiteVolume/fields/fvPatchFields/derived/mappedFlowRate/mappedFlowRateFvPatchVectorField.C
index 9584f2b96ca6994558c5628d64b767fe5012754b..63aadec6a166fd65c7872afdadfc3af4ef63f3be 100644
--- a/src/finiteVolume/fields/fvPatchFields/derived/mappedFlowRate/mappedFlowRateFvPatchVectorField.C
+++ b/src/finiteVolume/fields/fvPatchFields/derived/mappedFlowRate/mappedFlowRateFvPatchVectorField.C
@@ -28,7 +28,6 @@ License
 #include "addToRunTimeSelectionTable.H"
 #include "fvPatchFieldMapper.H"
 #include "mappedPatchBase.H"
-#include "mapDistribute.H"
 #include "surfaceFields.H"
 
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
@@ -128,7 +127,7 @@ void Foam::mappedFlowRateFvPatchVectorField::updateCoeffs()
     scalarList phi =
         nbrPatch.lookupPatchField<surfaceScalarField, scalar>(nbrPhiName_);
 
-    mpp.map().distribute(phi);
+    mpp.distribute(phi);
 
 
     const surfaceScalarField& phiName =
diff --git a/src/finiteVolume/fields/fvPatchFields/derived/mappedVelocityFluxFixedValue/mappedVelocityFluxFixedValueFvPatchField.C b/src/finiteVolume/fields/fvPatchFields/derived/mappedVelocityFluxFixedValue/mappedVelocityFluxFixedValueFvPatchField.C
index 29f6afa027f49b807a62815c66319e9e681492be..00be69fc850cad6c4bf4c3b78383a6846ff074ce 100644
--- a/src/finiteVolume/fields/fvPatchFields/derived/mappedVelocityFluxFixedValue/mappedVelocityFluxFixedValueFvPatchField.C
+++ b/src/finiteVolume/fields/fvPatchFields/derived/mappedVelocityFluxFixedValue/mappedVelocityFluxFixedValueFvPatchField.C
@@ -176,13 +176,10 @@ void Foam::mappedVelocityFluxFixedValueFvPatchField::updateCoeffs()
     (
         mappedVelocityFluxFixedValueFvPatchField::patch().patch()
     );
-    const mapDistribute& distMap = mpp.map();
     const fvMesh& nbrMesh = refCast<const fvMesh>(mpp.sampleMesh());
     const word& fieldName = dimensionedInternalField().name();
-    const volVectorField& UField = nbrMesh.lookupObject<volVectorField>
-    (
-        fieldName
-    );
+    const volVectorField& UField =
+        nbrMesh.lookupObject<volVectorField>(fieldName);
 
     surfaceScalarField& phiField = const_cast<surfaceScalarField&>
     (
@@ -213,26 +210,25 @@ void Foam::mappedVelocityFluxFixedValueFvPatchField::updateCoeffs()
                 }
             }
 
-            distMap.distribute(allUValues);
+            mpp.distribute(allUValues);
             newUValues.transfer(allUValues);
 
-            distMap.distribute(allPhiValues);
+            mpp.distribute(allPhiValues);
             newPhiValues.transfer(allPhiValues);
 
             break;
         }
         case mappedPolyPatch::NEARESTPATCHFACE:
+        case mappedPolyPatch::NEARESTPATCHFACEAMI:
         {
-            const label nbrPatchID = nbrMesh.boundaryMesh().findPatchID
-            (
-                mpp.samplePatch()
-            );
+            const label nbrPatchID =
+                nbrMesh.boundaryMesh().findPatchID(mpp.samplePatch());
 
             newUValues = UField.boundaryField()[nbrPatchID];
-            distMap.distribute(newUValues);
+            mpp.distribute(newUValues);
 
             newPhiValues = phiField.boundaryField()[nbrPatchID];
-            distMap.distribute(newPhiValues);
+            mpp.distribute(newPhiValues);
 
             break;
         }
@@ -242,8 +238,9 @@ void Foam::mappedVelocityFluxFixedValueFvPatchField::updateCoeffs()
             (
                 "mappedVelocityFluxFixedValueFvPatchField::"
                 "updateCoeffs()"
-            )   << "patch can only be used in NEARESTPATCHFACE or NEARESTFACE "
-                << "mode" << nl << abort(FatalError);
+            )   << "patch can only be used in NEARESTPATCHFACE, "
+                << "NEARESTPATCHFACEAMI or NEARESTFACE mode" << nl
+                << abort(FatalError);
         }
     }
 
diff --git a/src/finiteVolume/fields/fvPatchFields/derived/multiphaseFixedFluxPressure/multiphaseFixedFluxPressureFvPatchScalarField.C b/src/finiteVolume/fields/fvPatchFields/derived/multiphaseFixedFluxPressure/multiphaseFixedFluxPressureFvPatchScalarField.C
deleted file mode 100644
index be534fb8fac0938fd62ff698e36fc7eb068d4397..0000000000000000000000000000000000000000
--- a/src/finiteVolume/fields/fvPatchFields/derived/multiphaseFixedFluxPressure/multiphaseFixedFluxPressureFvPatchScalarField.C
+++ /dev/null
@@ -1,177 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
-     \\/     M anipulation  |
--------------------------------------------------------------------------------
-License
-    This file is part of OpenFOAM.
-
-    OpenFOAM is free software: you can redistribute it and/or modify it
-    under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
-    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-    for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
-
-\*---------------------------------------------------------------------------*/
-
-#include "multiphaseFixedFluxPressureFvPatchScalarField.H"
-#include "fvPatchFieldMapper.H"
-#include "volFields.H"
-#include "surfaceFields.H"
-#include "addToRunTimeSelectionTable.H"
-
-// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
-
-Foam::multiphaseFixedFluxPressureFvPatchScalarField::
-multiphaseFixedFluxPressureFvPatchScalarField
-(
-    const fvPatch& p,
-    const DimensionedField<scalar, volMesh>& iF
-)
-:
-    fixedGradientFvPatchScalarField(p, iF),
-    UName_("U"),
-    phiName_("phi"),
-    rhoName_("rho")
-{}
-
-
-Foam::multiphaseFixedFluxPressureFvPatchScalarField::
-multiphaseFixedFluxPressureFvPatchScalarField
-(
-    const multiphaseFixedFluxPressureFvPatchScalarField& ptf,
-    const fvPatch& p,
-    const DimensionedField<scalar, volMesh>& iF,
-    const fvPatchFieldMapper& mapper
-)
-:
-    fixedGradientFvPatchScalarField(ptf, p, iF, mapper),
-    UName_(ptf.UName_),
-    phiName_(ptf.phiName_),
-    rhoName_(ptf.rhoName_)
-{}
-
-
-Foam::multiphaseFixedFluxPressureFvPatchScalarField::
-multiphaseFixedFluxPressureFvPatchScalarField
-(
-    const fvPatch& p,
-    const DimensionedField<scalar, volMesh>& iF,
-    const dictionary& dict
-)
-:
-    fixedGradientFvPatchScalarField(p, iF),
-    UName_(dict.lookupOrDefault<word>("U", "U")),
-    phiName_(dict.lookupOrDefault<word>("phi", "phi")),
-    rhoName_(dict.lookupOrDefault<word>("rho", "rho"))
-{
-    if (dict.found("gradient"))
-    {
-        gradient() = scalarField("gradient", dict, p.size());
-        fixedGradientFvPatchScalarField::updateCoeffs();
-        fixedGradientFvPatchScalarField::evaluate();
-    }
-    else
-    {
-        fvPatchField<scalar>::operator=(patchInternalField());
-        gradient() = 0.0;
-    }
-}
-
-
-Foam::multiphaseFixedFluxPressureFvPatchScalarField::
-multiphaseFixedFluxPressureFvPatchScalarField
-(
-    const multiphaseFixedFluxPressureFvPatchScalarField& wbppsf
-)
-:
-    fixedGradientFvPatchScalarField(wbppsf),
-    UName_(wbppsf.UName_),
-    phiName_(wbppsf.phiName_),
-    rhoName_(wbppsf.rhoName_)
-{}
-
-
-Foam::multiphaseFixedFluxPressureFvPatchScalarField::
-multiphaseFixedFluxPressureFvPatchScalarField
-(
-    const multiphaseFixedFluxPressureFvPatchScalarField& wbppsf,
-    const DimensionedField<scalar, volMesh>& iF
-)
-:
-    fixedGradientFvPatchScalarField(wbppsf, iF),
-    UName_(wbppsf.UName_),
-    phiName_(wbppsf.phiName_),
-    rhoName_(wbppsf.rhoName_)
-{}
-
-
-// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
-
-void Foam::multiphaseFixedFluxPressureFvPatchScalarField::updateCoeffs()
-{
-    if (updated())
-    {
-        return;
-    }
-
-    const fvPatchField<vector>& Up =
-        patch().lookupPatchField<volVectorField, vector>(UName_);
-
-    const surfaceScalarField& phi =
-        db().lookupObject<surfaceScalarField>(phiName_);
-
-    fvsPatchField<scalar> phip =
-        patch().patchField<surfaceScalarField, scalar>(phi);
-
-    if (phi.dimensions() == dimDensity*dimVelocity*dimArea)
-    {
-        const fvPatchField<scalar>& rhop =
-            patch().lookupPatchField<volScalarField, scalar>(rhoName_);
-
-        phip /= rhop;
-    }
-
-    const fvsPatchField<scalar>& Dpp =
-        patch().lookupPatchField<surfaceScalarField, scalar>("Dp");
-
-    gradient() = (phip - (patch().Sf() & Up))/patch().magSf()/Dpp;
-
-    fixedGradientFvPatchScalarField::updateCoeffs();
-}
-
-
-void Foam::multiphaseFixedFluxPressureFvPatchScalarField::write
-(
-    Ostream& os
-) const
-{
-    fvPatchScalarField::write(os);
-    writeEntryIfDifferent<word>(os, "U", "U", UName_);
-    writeEntryIfDifferent<word>(os, "phi", "phi", phiName_);
-    writeEntryIfDifferent<word>(os, "rho", "rho", rhoName_);
-    gradient().writeEntry("gradient", os);
-}
-
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-namespace Foam
-{
-    makePatchTypeField
-    (
-        fvPatchScalarField,
-        multiphaseFixedFluxPressureFvPatchScalarField
-    );
-}
-
-// ************************************************************************* //
diff --git a/src/finiteVolume/fields/fvPatchFields/derived/multiphaseFixedFluxPressure/multiphaseFixedFluxPressureFvPatchScalarField.H b/src/finiteVolume/fields/fvPatchFields/derived/multiphaseFixedFluxPressure/multiphaseFixedFluxPressureFvPatchScalarField.H
deleted file mode 100644
index b97001a5c0ff6e84872f6a0718f105901cb6074f..0000000000000000000000000000000000000000
--- a/src/finiteVolume/fields/fvPatchFields/derived/multiphaseFixedFluxPressure/multiphaseFixedFluxPressureFvPatchScalarField.H
+++ /dev/null
@@ -1,154 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
-     \\/     M anipulation  |
--------------------------------------------------------------------------------
-License
-    This file is part of OpenFOAM.
-
-    OpenFOAM is free software: you can redistribute it and/or modify it
-    under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
-    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-    for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
-
-Class
-    Foam::multiphaseFixedFluxPressureFvPatchScalarField
-
-Description
-    Foam::multiphaseFixedFluxPressureFvPatchScalarField
-
-SourceFiles
-    multiphaseFixedFluxPressureFvPatchScalarField.C
-
-\*---------------------------------------------------------------------------*/
-
-#ifndef multiphaseFixedFluxPressureFvPatchScalarFields_H
-#define multiphaseFixedFluxPressureFvPatchScalarFields_H
-
-#include "fvPatchFields.H"
-#include "fixedGradientFvPatchFields.H"
-#include "Switch.H"
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-namespace Foam
-{
-
-/*---------------------------------------------------------------------------*\
-              Class multiphaseFixedFluxPressureFvPatch Declaration
-\*---------------------------------------------------------------------------*/
-
-class multiphaseFixedFluxPressureFvPatchScalarField
-:
-    public fixedGradientFvPatchScalarField
-{
-    // Private data
-
-        //- Name of the velocity field
-        word UName_;
-
-        //- Name of the flux transporting the field
-        word phiName_;
-
-        //- Name of the density field used to normalise the mass flux
-        //  if neccessary
-        word rhoName_;
-
-
-public:
-
-    //- Runtime type information
-    TypeName("multiphaseFixedFluxPressure");
-
-
-    // Constructors
-
-        //- Construct from patch and internal field
-        multiphaseFixedFluxPressureFvPatchScalarField
-        (
-            const fvPatch&,
-            const DimensionedField<scalar, volMesh>&
-        );
-
-        //- Construct from patch, internal field and dictionary
-        multiphaseFixedFluxPressureFvPatchScalarField
-        (
-            const fvPatch&,
-            const DimensionedField<scalar, volMesh>&,
-            const dictionary&
-        );
-
-        //- Construct by mapping given
-        //  multiphaseFixedFluxPressureFvPatchScalarField onto a new patch
-        multiphaseFixedFluxPressureFvPatchScalarField
-        (
-            const multiphaseFixedFluxPressureFvPatchScalarField&,
-            const fvPatch&,
-            const DimensionedField<scalar, volMesh>&,
-            const fvPatchFieldMapper&
-        );
-
-        //- Construct as copy
-        multiphaseFixedFluxPressureFvPatchScalarField
-        (
-            const multiphaseFixedFluxPressureFvPatchScalarField&
-        );
-
-        //- Construct and return a clone
-        virtual tmp<fvPatchScalarField> clone() const
-        {
-            return tmp<fvPatchScalarField>
-            (
-                new multiphaseFixedFluxPressureFvPatchScalarField(*this)
-            );
-        }
-
-        //- Construct as copy setting internal field reference
-        multiphaseFixedFluxPressureFvPatchScalarField
-        (
-            const multiphaseFixedFluxPressureFvPatchScalarField&,
-            const DimensionedField<scalar, volMesh>&
-        );
-
-        //- Construct and return a clone setting internal field reference
-        virtual tmp<fvPatchScalarField> clone
-        (
-            const DimensionedField<scalar, volMesh>& iF
-        ) const
-        {
-            return tmp<fvPatchScalarField>
-            (
-                new multiphaseFixedFluxPressureFvPatchScalarField(*this, iF)
-            );
-        }
-
-
-    // Member functions
-
-        //- 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/fields/fvPatchFields/derived/selfContainedMapped/selfContainedMappedFixedValueFvPatchField.C b/src/finiteVolume/fields/fvPatchFields/derived/selfContainedMapped/selfContainedMappedFixedValueFvPatchField.C
index 1a3334c927ab62f80724d83916246748d7aafa1c..e13eacc4bf8cd987dd68c7eb022dc67ab6a48372 100644
--- a/src/finiteVolume/fields/fvPatchFields/derived/selfContainedMapped/selfContainedMappedFixedValueFvPatchField.C
+++ b/src/finiteVolume/fields/fvPatchFields/derived/selfContainedMapped/selfContainedMappedFixedValueFvPatchField.C
@@ -229,7 +229,6 @@ void selfContainedMappedFixedValueFvPatchField<Type>::updateCoeffs()
 
     const fvMesh& thisMesh = this->patch().boundaryMesh().mesh();
     const fvMesh& nbrMesh = refCast<const fvMesh>(sampleMesh());
-    const mapDistribute& distMap = mappedPatchBase::map();
 
     // Result of obtaining remote values
     Field<Type> newValues;
@@ -238,6 +237,8 @@ void selfContainedMappedFixedValueFvPatchField<Type>::updateCoeffs()
     {
         case NEARESTCELL:
         {
+            const mapDistribute& distMap = mappedPatchBase::map();
+
             if (interpolationScheme_ != interpolationCell<Type>::typeName)
             {
                 // Need to do interpolation so need cells to sample.
@@ -275,12 +276,10 @@ void selfContainedMappedFixedValueFvPatchField<Type>::updateCoeffs()
 
             break;
         }
-        case NEARESTPATCHFACE:
+        case NEARESTPATCHFACE: case NEARESTPATCHFACEAMI:
         {
-            const label nbrPatchID = nbrMesh.boundaryMesh().findPatchID
-            (
-                samplePatch()
-            );
+            const label nbrPatchID =
+                nbrMesh.boundaryMesh().findPatchID(samplePatch());
             if (nbrPatchID < 0)
             {
                 FatalErrorIn
@@ -297,7 +296,7 @@ void selfContainedMappedFixedValueFvPatchField<Type>::updateCoeffs()
             const fieldType& nbrField = sampleField();
 
             newValues = nbrField.boundaryField()[nbrPatchID];
-            distMap.distribute(newValues);
+            this->distribute(newValues);
 
             break;
         }
@@ -319,7 +318,7 @@ void selfContainedMappedFixedValueFvPatchField<Type>::updateCoeffs()
                 }
             }
 
-            distMap.distribute(allValues);
+            this->distribute(allValues);
 
             newValues.transfer(allValues);
 
diff --git a/src/lagrangian/intermediate/parcels/Templates/KinematicParcel/KinematicParcel.C b/src/lagrangian/intermediate/parcels/Templates/KinematicParcel/KinematicParcel.C
index ef36b470581c5390c963ca3a2e9f6481140dd34c..7007e0167b5a636ed7deff1526e7429e951d75e8 100644
--- a/src/lagrangian/intermediate/parcels/Templates/KinematicParcel/KinematicParcel.C
+++ b/src/lagrangian/intermediate/parcels/Templates/KinematicParcel/KinematicParcel.C
@@ -324,6 +324,8 @@ bool Foam::KinematicParcel<ParcelType>::move
         }
 
         p.age() += dt;
+
+        td.cloud().functions().postMove(p, cellI, dt);
     }
 
     return td.keepParticle;
diff --git a/src/lagrangian/intermediate/parcels/include/makeParcelCloudFunctionObjects.H b/src/lagrangian/intermediate/parcels/include/makeParcelCloudFunctionObjects.H
index 0a68bee908a87f5a6e4671a93d3a532c808d096b..6eadb7fea82da1099277c395987ba3a49ea4c789 100644
--- a/src/lagrangian/intermediate/parcels/include/makeParcelCloudFunctionObjects.H
+++ b/src/lagrangian/intermediate/parcels/include/makeParcelCloudFunctionObjects.H
@@ -31,6 +31,7 @@ License
 #include "FacePostProcessing.H"
 #include "ParticleTracks.H"
 #include "PatchPostProcessing.H"
+#include "VoidFraction.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -40,7 +41,8 @@ License
                                                                               \
     makeCloudFunctionObjectType(FacePostProcessing, CloudType);               \
     makeCloudFunctionObjectType(ParticleTracks, CloudType);                   \
-    makeCloudFunctionObjectType(PatchPostProcessing, CloudType);
+    makeCloudFunctionObjectType(PatchPostProcessing, CloudType);              \
+    makeCloudFunctionObjectType(VoidFraction, CloudType);
 
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
diff --git a/src/lagrangian/intermediate/submodels/CloudFunctionObjects/CloudFunctionObject/CloudFunctionObject.C b/src/lagrangian/intermediate/submodels/CloudFunctionObjects/CloudFunctionObject/CloudFunctionObject.C
index 8ba3dd81b6276f303124a6fc2b19ac7fca9f8d9b..02416263cbce244c69e91b0fe39d69b7af690c9a 100644
--- a/src/lagrangian/intermediate/submodels/CloudFunctionObjects/CloudFunctionObject/CloudFunctionObject.C
+++ b/src/lagrangian/intermediate/submodels/CloudFunctionObjects/CloudFunctionObject/CloudFunctionObject.C
@@ -91,6 +91,18 @@ void Foam::CloudFunctionObject<CloudType>::postEvolve()
 }
 
 
+template<class CloudType>
+void Foam::CloudFunctionObject<CloudType>::postMove
+(
+    const typename CloudType::parcelType&,
+    const label,
+    const scalar
+)
+{
+    // do nothing
+}
+
+
 template<class CloudType>
 void Foam::CloudFunctionObject<CloudType>::postPatch
 (
@@ -98,14 +110,7 @@ void Foam::CloudFunctionObject<CloudType>::postPatch
     const label
 )
 {
-    notImplemented
-    (
-        "void Foam::CloudFunctionObject<CloudType>::postPatch"
-        "("
-            "const typename CloudType::parcelType&,"
-            "const label"
-        ")"
-    );
+    // do nothing
 }
 
 
@@ -115,13 +120,7 @@ void Foam::CloudFunctionObject<CloudType>::postFace
     const typename CloudType::parcelType&
 )
 {
-    notImplemented
-    (
-        "void Foam::CloudFunctionObject<CloudType>::postFace"
-        "("
-            "const typename CloudType::parcelType&"
-        ")"
-    );
+    // do nothing
 }
 
 
diff --git a/src/lagrangian/intermediate/submodels/CloudFunctionObjects/CloudFunctionObject/CloudFunctionObject.H b/src/lagrangian/intermediate/submodels/CloudFunctionObjects/CloudFunctionObject/CloudFunctionObject.H
index 607e2a8bd9e92a6554e68e030686bdd8926ce428..0ea373d5cb7cc8c4f13dc57a585681cd242ccb83 100644
--- a/src/lagrangian/intermediate/submodels/CloudFunctionObjects/CloudFunctionObject/CloudFunctionObject.H
+++ b/src/lagrangian/intermediate/submodels/CloudFunctionObjects/CloudFunctionObject/CloudFunctionObject.H
@@ -129,6 +129,14 @@ public:
             //- Post-evolve hook
             virtual void postEvolve();
 
+            //- Post-move hook
+            virtual void postMove
+            (
+                const typename CloudType::parcelType& p,
+                const label cellI,
+                const scalar dt
+            );
+
             //- Post-patch hook
             virtual void postPatch
             (
diff --git a/src/lagrangian/intermediate/submodels/CloudFunctionObjects/CloudFunctionObjectList/CloudFunctionObjectList.C b/src/lagrangian/intermediate/submodels/CloudFunctionObjects/CloudFunctionObjectList/CloudFunctionObjectList.C
index e9bf670e63ded2acc130ce3775b27065c87d7b1c..7c9e715c78f6e0f05c83da56346fcd3a4f325c12 100644
--- a/src/lagrangian/intermediate/submodels/CloudFunctionObjects/CloudFunctionObjectList/CloudFunctionObjectList.C
+++ b/src/lagrangian/intermediate/submodels/CloudFunctionObjects/CloudFunctionObjectList/CloudFunctionObjectList.C
@@ -127,6 +127,21 @@ void Foam::CloudFunctionObjectList<CloudType>::postEvolve()
 }
 
 
+template<class CloudType>
+void Foam::CloudFunctionObjectList<CloudType>::postMove
+(
+    const typename CloudType::parcelType& p,
+    const label cellI,
+    const scalar dt
+)
+{
+    forAll(*this, i)
+    {
+        this->operator[](i).postMove(p, cellI, dt);
+    }
+}
+
+
 template<class CloudType>
 void Foam::CloudFunctionObjectList<CloudType>::postPatch
 (
diff --git a/src/lagrangian/intermediate/submodels/CloudFunctionObjects/CloudFunctionObjectList/CloudFunctionObjectList.H b/src/lagrangian/intermediate/submodels/CloudFunctionObjects/CloudFunctionObjectList/CloudFunctionObjectList.H
index bffa812bda63264d4bf8122a956e686d4e76cc9f..edba8be4a4845b77ccb755edbe53154ce2a2d2bc 100644
--- a/src/lagrangian/intermediate/submodels/CloudFunctionObjects/CloudFunctionObjectList/CloudFunctionObjectList.H
+++ b/src/lagrangian/intermediate/submodels/CloudFunctionObjects/CloudFunctionObjectList/CloudFunctionObjectList.H
@@ -109,6 +109,14 @@ public:
             //- Post-evolve hook
             virtual void postEvolve();
 
+            //- Post-move hook
+            virtual void postMove
+            (
+                const typename CloudType::parcelType& p,
+                const label cellI,
+                const scalar dt
+            );
+
             //- Post-patch hook
             virtual void postPatch
             (
diff --git a/src/lagrangian/intermediate/submodels/CloudFunctionObjects/VoidFraction/VoidFraction.C b/src/lagrangian/intermediate/submodels/CloudFunctionObjects/VoidFraction/VoidFraction.C
new file mode 100644
index 0000000000000000000000000000000000000000..855db45c88a6d679342811c4f66dbd3c37d8562a
--- /dev/null
+++ b/src/lagrangian/intermediate/submodels/CloudFunctionObjects/VoidFraction/VoidFraction.C
@@ -0,0 +1,137 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+\*---------------------------------------------------------------------------*/
+
+#include "VoidFraction.H"
+#
+// * * * * * * * * * * * * * Protectd Member Functions * * * * * * * * * * * //
+
+template<class CloudType>
+void Foam::VoidFraction<CloudType>::write()
+{
+    if (thetaPtr_.valid())
+    {
+        thetaPtr_->write();
+    }
+    else
+    {
+        FatalErrorIn("void Foam::VoidFraction<CloudType>::write()")
+            << "thetaPtr not valid" << abort(FatalError);
+    }
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+template<class CloudType>
+Foam::VoidFraction<CloudType>::VoidFraction
+(
+    const dictionary& dict,
+    CloudType& owner
+)
+:
+    CloudFunctionObject<CloudType>(owner),
+    thetaPtr_(NULL)
+{}
+
+
+template<class CloudType>
+Foam::VoidFraction<CloudType>::VoidFraction
+(
+    const VoidFraction<CloudType>& vf
+)
+:
+    CloudFunctionObject<CloudType>(vf),
+    thetaPtr_(NULL)
+{}
+
+
+// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
+
+template<class CloudType>
+Foam::VoidFraction<CloudType>::~VoidFraction()
+{}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+template<class CloudType>
+void Foam::VoidFraction<CloudType>::preEvolve()
+{
+    if (thetaPtr_.valid())
+    {
+        thetaPtr_->internalField() = 0.0;
+    }
+    else
+    {
+        const fvMesh& mesh = this->owner().mesh();
+
+        thetaPtr_.reset
+        (
+            new volScalarField
+            (
+                IOobject
+                (
+                    this->owner().name() + "Theta",
+                    mesh.time().timeName(),
+                    mesh,
+                    IOobject::NO_READ,
+                    IOobject::NO_WRITE
+                ),
+                mesh,
+                dimensionedScalar("zero", dimless, 0.0)
+            )
+        );
+    }
+}
+
+
+template<class CloudType>
+void Foam::VoidFraction<CloudType>::postEvolve()
+{
+    volScalarField& theta = thetaPtr_();
+
+    const fvMesh& mesh = this->owner().mesh();
+
+    theta.internalField() /= mesh.time().deltaTValue()*mesh.V();
+
+    CloudFunctionObject<CloudType>::postEvolve();
+}
+
+
+template<class CloudType>
+void Foam::VoidFraction<CloudType>::postMove
+(
+    const parcelType& p,
+    const label cellI,
+    const scalar dt
+)
+{
+    volScalarField& theta = thetaPtr_();
+
+    theta[cellI] += dt*p.nParticle()*p.volume();
+}
+
+
+// ************************************************************************* //
diff --git a/src/lagrangian/intermediate/submodels/CloudFunctionObjects/VoidFraction/VoidFraction.H b/src/lagrangian/intermediate/submodels/CloudFunctionObjects/VoidFraction/VoidFraction.H
new file mode 100644
index 0000000000000000000000000000000000000000..0b15a6f620737598cd5a218440e4087654d0c009
--- /dev/null
+++ b/src/lagrangian/intermediate/submodels/CloudFunctionObjects/VoidFraction/VoidFraction.H
@@ -0,0 +1,137 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+Class
+    Foam::VoidFraction
+
+Description
+    Creates particle void fraction field on carrier phase
+
+SourceFiles
+    VoidFraction.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef VoidFraction_H
+#define VoidFraction_H
+
+#include "CloudFunctionObject.H"
+#include "volFields.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+                       Class VoidFraction Declaration
+\*---------------------------------------------------------------------------*/
+
+template<class CloudType>
+class VoidFraction
+:
+    public CloudFunctionObject<CloudType>
+{
+    // Private Data
+
+        // Typedefs
+
+            //- Convenience typedef for parcel type
+            typedef typename CloudType::parcelType parcelType;
+
+
+        //- Void fraction field
+        autoPtr<volScalarField> thetaPtr_;
+
+
+protected:
+
+    // Protected Member Functions
+
+        //- Write post-processing info
+        virtual void write();
+
+
+public:
+
+    //- Runtime type information
+    TypeName("voidFraction");
+
+
+    // Constructors
+
+        //- Construct from dictionary
+        VoidFraction(const dictionary& dict, CloudType& owner);
+
+        //- Construct copy
+        VoidFraction(const VoidFraction<CloudType>& vf);
+
+        //- Construct and return a clone
+        virtual autoPtr<CloudFunctionObject<CloudType> > clone() const
+        {
+            return autoPtr<CloudFunctionObject<CloudType> >
+            (
+                new VoidFraction<CloudType>(*this)
+            );
+        }
+
+
+    //- Destructor
+    virtual ~VoidFraction();
+
+
+    // Member Functions
+
+        // Evaluation
+
+            //- Pre-evolve hook
+            virtual void preEvolve();
+
+            //- Post-evolve hook
+            virtual void postEvolve();
+
+            //- Post-move hook
+            virtual void postMove
+            (   
+                const parcelType& p,
+                const label cellI,
+                const scalar dt
+            );
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#ifdef NoRepository
+#   include "VoidFraction.C"
+#endif
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/ConeNozzleInjection/ConeNozzleInjection.C b/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/ConeNozzleInjection/ConeNozzleInjection.C
index 80a5bed73fc5b336ca136588afea653b79523d46..08e824f35b1b52499b6caddd0bbe3e53e5231264 100644
--- a/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/ConeNozzleInjection/ConeNozzleInjection.C
+++ b/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/ConeNozzleInjection/ConeNozzleInjection.C
@@ -220,11 +220,14 @@ Foam::ConeNozzleInjection<CloudType>::ConeNozzleInjection
 :
     InjectionModel<CloudType>(im),
     injectionMethod_(im.injectionMethod_),
+    flowType_(im.flowType_),
     outerDiameter_(im.outerDiameter_),
     innerDiameter_(im.innerDiameter_),
     duration_(im.duration_),
     position_(im.position_),
     injectorCell_(im.injectorCell_),
+    tetFaceI_(im.tetFaceI_),
+    tetPtI_(im.tetPtI_),
     direction_(im.direction_),
     parcelsPerSecond_(im.parcelsPerSecond_),
     flowRateProfile_(im.flowRateProfile_().clone().ptr()),
@@ -235,9 +238,18 @@ Foam::ConeNozzleInjection<CloudType>::ConeNozzleInjection
     tanVec2_(im.tanVec1_),
     normal_(im.normal_),
     UMag_(im.UMag_),
-    Cd_(im.Cd_().clone().ptr()),
-    Pinj_(im.Pinj_().clone().ptr())
-{}
+    Cd_(NULL),
+    Pinj_(NULL)
+{
+    if (im.Cd_.valid())
+    {
+        Cd_.reset(im.Cd_().clone().ptr());
+    }
+    if (im.Pinj_.valid())
+    {
+        Pinj_.reset(im.Pinj_().clone().ptr());
+    }
+}
 
 
 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
diff --git a/src/lagrangian/intermediate/submodels/Kinematic/SurfaceFilmModel/SurfaceFilmModel/SurfaceFilmModel.C b/src/lagrangian/intermediate/submodels/Kinematic/SurfaceFilmModel/SurfaceFilmModel/SurfaceFilmModel.C
index 36dca28f6a4fcc09a01204b36abd82060d122f76..d080a624a2f68ca809fbcac43d5bdeaa1716ab1b 100644
--- a/src/lagrangian/intermediate/submodels/Kinematic/SurfaceFilmModel/SurfaceFilmModel/SurfaceFilmModel.C
+++ b/src/lagrangian/intermediate/submodels/Kinematic/SurfaceFilmModel/SurfaceFilmModel/SurfaceFilmModel.C
@@ -114,8 +114,8 @@ bool Foam::SurfaceFilmModel<CloudType>::transferParcel
         "bool Foam::SurfaceFilmModel<CloudType>::transferParcel"
         "("
             "parcelType&, "
-            "const label, "
-            "const bool&"
+            "const polyPatch&, "
+            "bool&"
         ")"
     );
 
@@ -156,11 +156,9 @@ void Foam::SurfaceFilmModel<CloudType>::inject(TrackData& td)
         const label filmPatchI = filmPatches[i];
         const label primaryPatchI = primaryPatches[i];
 
-        const mappedPatchBase& mapPatch = filmModel.mappedPatches()[filmPatchI];
-
         const labelList& injectorCellsPatch = pbm[primaryPatchI].faceCells();
 
-        cacheFilmFields(filmPatchI, primaryPatchI, mapPatch, filmModel);
+        cacheFilmFields(filmPatchI, primaryPatchI, filmModel);
 
         const vectorField& Cf = mesh.C().boundaryField()[primaryPatchI];
         const vectorField& Sf = mesh.Sf().boundaryField()[primaryPatchI];
@@ -172,13 +170,11 @@ void Foam::SurfaceFilmModel<CloudType>::inject(TrackData& td)
             {
                 const label cellI = injectorCellsPatch[j];
 
-                // The position is at the cell centre, which could be
-                // in any tet of the decomposed cell, so arbitrarily
-                // choose the first face of the cell as the tetFace
-                // and the first point on the face after the base
-                // point as the tetPt.  The tracking will
-                // pick the cell consistent with the motion in the
-                // first tracking step.
+                // The position could bein any tet of the decomposed cell,
+                // so arbitrarily choose the first face of the cell as the
+                // tetFace and the first point on the face after the base
+                // point as the tetPt.  The tracking will pick the cell
+                // consistent with the motion in the first tracking step.
                 const label tetFaceI = this->owner().mesh().cells()[cellI][0];
                 const label tetPtI = 1;
 
@@ -208,14 +204,22 @@ void Foam::SurfaceFilmModel<CloudType>::inject(TrackData& td)
 
                 setParcelProperties(*pPtr, j);
 
-                // Check new parcel properties
-//                td.cloud().checkParcelProperties(*pPtr, 0.0, true);
-                td.cloud().checkParcelProperties(*pPtr, 0.0, false);
-
-                // Add the new parcel to the cloud
-                td.cloud().addParticle(pPtr);
-
-                nParcelsInjected_++;
+                if (pPtr->nParticle() > 0.001)
+                {
+                    // Check new parcel properties
+    //                td.cloud().checkParcelProperties(*pPtr, 0.0, true);
+                    td.cloud().checkParcelProperties(*pPtr, 0.0, false);
+
+                    // Add the new parcel to the cloud
+                    td.cloud().addParticle(pPtr);
+
+                    nParcelsInjected_++;
+                }
+                else
+                {
+                    // TODO: cache mass and re-distribute?
+                    delete pPtr;
+                }
             }
         }
     }
@@ -227,26 +231,25 @@ void Foam::SurfaceFilmModel<CloudType>::cacheFilmFields
 (
     const label filmPatchI,
     const label primaryPatchI,
-    const mappedPatchBase& mapPatch,
     const regionModels::surfaceFilmModels::surfaceFilmModel& filmModel
 )
 {
     massParcelPatch_ = filmModel.cloudMassTrans().boundaryField()[filmPatchI];
-    mapPatch.distribute(massParcelPatch_);
+    filmModel.toPrimary(filmPatchI, massParcelPatch_);
 
     diameterParcelPatch_ =
         filmModel.cloudDiameterTrans().boundaryField()[filmPatchI];
-    mapPatch.distribute(diameterParcelPatch_);
+    filmModel.toPrimary(filmPatchI, diameterParcelPatch_);
 
     UFilmPatch_ = filmModel.Us().boundaryField()[filmPatchI];
-    mapPatch.distribute(UFilmPatch_);
+    filmModel.toPrimary(filmPatchI, UFilmPatch_);
 
     rhoFilmPatch_ = filmModel.rho().boundaryField()[filmPatchI];
-    mapPatch.distribute(rhoFilmPatch_);
+    filmModel.toPrimary(filmPatchI, rhoFilmPatch_);
 
     deltaFilmPatch_[primaryPatchI] =
         filmModel.delta().boundaryField()[filmPatchI];
-    mapPatch.distribute(deltaFilmPatch_[primaryPatchI]);
+    filmModel.toPrimary(filmPatchI, deltaFilmPatch_[primaryPatchI]);
 }
 
 
diff --git a/src/lagrangian/intermediate/submodels/Kinematic/SurfaceFilmModel/SurfaceFilmModel/SurfaceFilmModel.H b/src/lagrangian/intermediate/submodels/Kinematic/SurfaceFilmModel/SurfaceFilmModel/SurfaceFilmModel.H
index ae35db7ec57e9babb1e9a5d22f2442605efd9f0c..967e748f56c8385483aca4dd3c2f4f280fa42da6 100644
--- a/src/lagrangian/intermediate/submodels/Kinematic/SurfaceFilmModel/SurfaceFilmModel/SurfaceFilmModel.H
+++ b/src/lagrangian/intermediate/submodels/Kinematic/SurfaceFilmModel/SurfaceFilmModel/SurfaceFilmModel.H
@@ -116,7 +116,6 @@ protected:
         (
             const label filmPatchI,
             const label primaryPatchI,
-            const mappedPatchBase& mapPatch,
             const regionModels::surfaceFilmModels::surfaceFilmModel& filmModel
         );
 
diff --git a/src/lagrangian/intermediate/submodels/Thermodynamic/SurfaceFilmModel/ThermoSurfaceFilm/ThermoSurfaceFilm.C b/src/lagrangian/intermediate/submodels/Thermodynamic/SurfaceFilmModel/ThermoSurfaceFilm/ThermoSurfaceFilm.C
index c6f4b4054a84ce8434935a81a179c3495890079c..6a6c60db3984390169d526e356537dd40f29575a 100644
--- a/src/lagrangian/intermediate/submodels/Thermodynamic/SurfaceFilmModel/ThermoSurfaceFilm/ThermoSurfaceFilm.C
+++ b/src/lagrangian/intermediate/submodels/Thermodynamic/SurfaceFilmModel/ThermoSurfaceFilm/ThermoSurfaceFilm.C
@@ -643,7 +643,6 @@ void Foam::ThermoSurfaceFilm<CloudType>::cacheFilmFields
 (
     const label filmPatchI,
     const label primaryPatchI,
-    const mappedPatchBase& mapPatch,
     const regionModels::surfaceFilmModels::surfaceFilmModel& filmModel
 )
 {
@@ -651,15 +650,14 @@ void Foam::ThermoSurfaceFilm<CloudType>::cacheFilmFields
     (
         filmPatchI,
         primaryPatchI,
-        mapPatch,
         filmModel
     );
 
     TFilmPatch_ = filmModel.Ts().boundaryField()[filmPatchI];
-    mapPatch.distribute(TFilmPatch_);
+    filmModel.toPrimary(filmPatchI, TFilmPatch_);
 
     CpFilmPatch_ = filmModel.Cp().boundaryField()[filmPatchI];
-    mapPatch.distribute(CpFilmPatch_);
+    filmModel.toPrimary(filmPatchI, CpFilmPatch_);
 }
 
 
diff --git a/src/lagrangian/intermediate/submodels/Thermodynamic/SurfaceFilmModel/ThermoSurfaceFilm/ThermoSurfaceFilm.H b/src/lagrangian/intermediate/submodels/Thermodynamic/SurfaceFilmModel/ThermoSurfaceFilm/ThermoSurfaceFilm.H
index 66bd1395682b2b38de27006916ed5ab74e42604a..bddbfcc66e9f28034472ff045a00e984850fc896 100644
--- a/src/lagrangian/intermediate/submodels/Thermodynamic/SurfaceFilmModel/ThermoSurfaceFilm/ThermoSurfaceFilm.H
+++ b/src/lagrangian/intermediate/submodels/Thermodynamic/SurfaceFilmModel/ThermoSurfaceFilm/ThermoSurfaceFilm.H
@@ -227,7 +227,6 @@ protected:
             (
                 const label filmPatchI,
                 const label primaryPatchI,
-                const mappedPatchBase& distMap,
                 const regionModels::surfaceFilmModels::surfaceFilmModel&
                     filmModel
             );
diff --git a/src/lagrangian/spray/clouds/Templates/SprayCloud/SprayCloud.C b/src/lagrangian/spray/clouds/Templates/SprayCloud/SprayCloud.C
index a87007e3e1fe1b1940f5d139e29af833f75f2eb1..67723a6e02330b0ce2a87c28dc9e8cff5281e774 100644
--- a/src/lagrangian/spray/clouds/Templates/SprayCloud/SprayCloud.C
+++ b/src/lagrangian/spray/clouds/Templates/SprayCloud/SprayCloud.C
@@ -110,6 +110,11 @@ Foam::SprayCloud<CloudType>::SprayCloud
 
         Info << "Average parcel mass: " << averageParcelMass_ << endl;
     }
+
+    if (this->solution().resetSourcesOnStartup())
+    {
+        CloudType::resetSourceTerms();
+    }
 }
 
 
diff --git a/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriver.C b/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriver.C
index 10d6499905c12a51fdb0359efcc5c2595b946765..c494366f40b3498a8e3e170afe1b329616b883d3 100644
--- a/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriver.C
+++ b/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriver.C
@@ -46,6 +46,7 @@ Description
 #include "combineFaces.H"
 #include "IOmanip.H"
 #include "globalIndex.H"
+#include "DynamicField.H"
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
@@ -1990,6 +1991,7 @@ Foam::label Foam::autoLayerDriver::checkAndUnmark
 (
     const addPatchCellLayer& addLayer,
     const dictionary& meshQualityDict,
+    const bool additionalReporting,
     const List<labelPair>& baffles,
     const indirectPrimitivePatch& pp,
     const fvMesh& newMesh,
@@ -2032,6 +2034,12 @@ Foam::label Foam::autoLayerDriver::checkAndUnmark
     );
 
     // Check if any of the faces in error uses any face of an added cell
+    // - if additionalReporting print the few remaining areas for ease of
+    //   finding out where the problems are.
+
+    const label nReportMax = 10;
+    DynamicField<point> disabledFaceCentres(nReportMax);
+
     forAll(addedCells, oldPatchFaceI)
     {
         // Get the cells (in newMesh labels) per old patch face (in mesh
@@ -2052,12 +2060,58 @@ Foam::label Foam::autoLayerDriver::checkAndUnmark
                 )
             )
             {
+                if (additionalReporting && (nChanged < nReportMax))
+                {
+                    disabledFaceCentres.append
+                    (
+                        pp.faceCentres()[oldPatchFaceI]
+                    );
+                }
+
                 nChanged++;
             }
         }
     }
 
-    return returnReduce(nChanged, sumOp<label>());
+
+    label nChangedTotal = returnReduce(nChanged, sumOp<label>());
+
+    if (additionalReporting)
+    {
+        // Limit the number of points to be printed so that
+        // not too many points are reported when running in parallel
+        // Not accurate, i.e. not always nReportMax points are written,
+        // but this estimation avoid some communication here.
+        // The important thing, however, is that when only a few faces
+        // are disabled, their coordinates are printed, and this should be
+        // the case
+        label nReportLocal =
+            min
+            (
+                max(nChangedTotal / Pstream::nProcs(), 1),
+                min
+                (
+                    nChanged,
+                    max(nReportMax / Pstream::nProcs(), 1)
+                )
+            );
+
+        Pout<< "Checked mesh with layers. Disabled extrusion at " << endl;
+        for (label i=0; i < nReportLocal; i++)
+        {
+            Pout<< "    " << disabledFaceCentres[i] << endl;
+        }
+
+        label nReportTotal = returnReduce(nReportLocal, sumOp<label>());
+
+        if (nReportTotal < nChangedTotal)
+        {
+            Info<< "Suppressed disabled extrusion message for other "
+                << nChangedTotal - nReportTotal << " faces." << endl;
+        }
+    }
+
+    return nChangedTotal;
 }
 
 
@@ -2858,6 +2912,7 @@ void Foam::autoLayerDriver::addLayers
         (
             addLayer,
             meshQualityDict,
+            layerParams.additionalReporting(),
             newMeshBaffles,
             pp(),
             newMesh,
diff --git a/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriver.H b/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriver.H
index 9b7c4c9c5ffb409f7697dc5c8153e38ebef29992..6bbe54a7089d1cb8762844787684da334ff34c9e 100644
--- a/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriver.H
+++ b/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriver.H
@@ -331,6 +331,7 @@ class autoLayerDriver
                 (
                     const addPatchCellLayer& addLayer,
                     const dictionary& motionDict,
+                    const bool additionalReporting,
                     const List<labelPair>& baffles,
                     const indirectPrimitivePatch& pp,
                     const fvMesh&,
diff --git a/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/layerParameters/layerParameters.C b/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/layerParameters/layerParameters.C
index 0fcadf232277628e513c40e528457b08dcd564ed..d1f66fb6e93d15974f6ec47bd7ff2f07eccb0f68 100644
--- a/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/layerParameters/layerParameters.C
+++ b/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/layerParameters/layerParameters.C
@@ -137,98 +137,98 @@ Foam::labelList Foam::layerParameters::readNumLayers
 
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
-// Construct from dictionary
-Foam::layerParameters::layerParameters
-(
-    const PtrList<dictionary>& surfaceDicts,
-    const refinementSurfaces& refineSurfaces,
-    const labelList& globalToPatch,
-    const dictionary& dict,
-    const polyBoundaryMesh& boundaryMesh
-)
-:
-    numLayers_
-    (
-        readNumLayers
-        (
-            surfaceDicts,
-            refineSurfaces,
-            globalToPatch,
-            boundaryMesh
-        )
-    ),
-    expansionRatio_
-    (
-        numLayers_.size(),
-        readScalar(dict.lookup("expansionRatio"))
-    ),
-    relativeSizes_(false),
-    finalLayerThickness_
-    (
-        numLayers_.size(),
-        readScalar(dict.lookup("finalLayerRatio"))
-    ),
-    minThickness_
-    (
-        numLayers_.size(),
-        readScalar(dict.lookup("minThickness"))
-    ),
-    featureAngle_(readScalar(dict.lookup("featureAngle"))),
-    concaveAngle_
-    (
-        dict.lookupOrDefault("concaveAngle", defaultConcaveAngle)
-    ),
-    nGrow_(readLabel(dict.lookup("nGrow"))),
-    nSmoothSurfaceNormals_
-    (
-        readLabel(dict.lookup("nSmoothSurfaceNormals"))
-    ),
-    nSmoothNormals_(readLabel(dict.lookup("nSmoothNormals"))),
-    nSmoothThickness_(readLabel(dict.lookup("nSmoothThickness"))),
-    maxFaceThicknessRatio_
-    (
-        readScalar(dict.lookup("maxFaceThicknessRatio"))
-    ),
-    layerTerminationCos_
-    (
-        Foam::cos(degToRad(0.5*featureAngle_))
-    ),
-    maxThicknessToMedialRatio_
-    (
-        readScalar(dict.lookup("maxThicknessToMedialRatio"))
-    ),
-    minMedianAxisAngleCos_
-    (
-        Foam::cos(degToRad(readScalar(dict.lookup("minMedianAxisAngle"))))
-    ),
-    nBufferCellsNoExtrude_
-    (
-        readLabel(dict.lookup("nBufferCellsNoExtrude"))
-    ),
-    nSnap_(readLabel(dict.lookup("nSnap"))),
-    nLayerIter_(readLabel(dict.lookup("nLayerIter"))),
-    nRelaxedIter_(labelMax)
-{
-    if (nGrow_ > 0)
-    {
-        WarningIn("layerParameters::layerParameters(..)")
-            << "The nGrow parameter effect has changed with respect to 1.6.x."
-            << endl
-            << "Please set nGrow=0 for 1.6.x behaviour."
-            << endl;
-    }
-
-    dict.readIfPresent("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
+//Foam::layerParameters::layerParameters
+//(
+//    const PtrList<dictionary>& surfaceDicts,
+//    const refinementSurfaces& refineSurfaces,
+//    const labelList& globalToPatch,
+//    const dictionary& dict,
+//    const polyBoundaryMesh& boundaryMesh
+//)
+//:
+//    numLayers_
+//    (
+//        readNumLayers
+//        (
+//            surfaceDicts,
+//            refineSurfaces,
+//            globalToPatch,
+//            boundaryMesh
+//        )
+//    ),
+//    expansionRatio_
+//    (
+//        numLayers_.size(),
+//        readScalar(dict.lookup("expansionRatio"))
+//    ),
+//    relativeSizes_(false),
+//    finalLayerThickness_
+//    (
+//        numLayers_.size(),
+//        readScalar(dict.lookup("finalLayerRatio"))
+//    ),
+//    minThickness_
+//    (
+//        numLayers_.size(),
+//        readScalar(dict.lookup("minThickness"))
+//    ),
+//    featureAngle_(readScalar(dict.lookup("featureAngle"))),
+//    concaveAngle_
+//    (
+//        dict.lookupOrDefault("concaveAngle", defaultConcaveAngle)
+//    ),
+//    nGrow_(readLabel(dict.lookup("nGrow"))),
+//    nSmoothSurfaceNormals_
+//    (
+//        readLabel(dict.lookup("nSmoothSurfaceNormals"))
+//    ),
+//    nSmoothNormals_(readLabel(dict.lookup("nSmoothNormals"))),
+//    nSmoothThickness_(readLabel(dict.lookup("nSmoothThickness"))),
+//    maxFaceThicknessRatio_
+//    (
+//        readScalar(dict.lookup("maxFaceThicknessRatio"))
+//    ),
+//    layerTerminationCos_
+//    (
+//        Foam::cos(degToRad(0.5*featureAngle_))
+//    ),
+//    maxThicknessToMedialRatio_
+//    (
+//        readScalar(dict.lookup("maxThicknessToMedialRatio"))
+//    ),
+//    minMedianAxisAngleCos_
+//    (
+//        Foam::cos(degToRad(readScalar(dict.lookup("minMedianAxisAngle"))))
+//    ),
+//    nBufferCellsNoExtrude_
+//    (
+//        readLabel(dict.lookup("nBufferCellsNoExtrude"))
+//    ),
+//    nSnap_(readLabel(dict.lookup("nSnap"))),
+//    nLayerIter_(readLabel(dict.lookup("nLayerIter"))),
+//    nRelaxedIter_(labelMax)
+//{
+//    if (nGrow_ > 0)
+//    {
+//        WarningIn("layerParameters::layerParameters(..)")
+//            << "The nGrow parameter effect has changed with respect to 1.6.x."
+//            << endl
+//            << "Please set nGrow=0 for 1.6.x behaviour."
+//            << endl;
+//    }
+//
+//    dict.readIfPresent("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
@@ -289,7 +289,8 @@ Foam::layerParameters::layerParameters
     ),
     nSnap_(readLabel(dict.lookup("nRelaxIter"))),
     nLayerIter_(readLabel(dict.lookup("nLayerIter"))),
-    nRelaxedIter_(labelMax)
+    nRelaxedIter_(labelMax),
+    additionalReporting_(dict.lookupOrDefault("additionalReporting", false))
 {
     if (nGrow_ > 0)
     {
diff --git a/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/layerParameters/layerParameters.H b/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/layerParameters/layerParameters.H
index 58937bf69fd6f897d32ea15cc19a73f2cec7bff0..e6324131e94d8becf1626518c29eab68bf556c0c 100644
--- a/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/layerParameters/layerParameters.H
+++ b/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/layerParameters/layerParameters.H
@@ -105,6 +105,7 @@ class layerParameters
 
         label nRelaxedIter_;
 
+        Switch additionalReporting_;
 
     // Private Member Functions
 
@@ -128,15 +129,15 @@ public:
 
     // Constructors
 
-        //- Construct from dictionary - old syntax
-        layerParameters
-        (
-            const PtrList<dictionary>& surfaceDicts,
-            const refinementSurfaces& refineSurfaces,
-            const labelList& globalToPatch,
-            const dictionary& dict,
-            const polyBoundaryMesh& boundaryMesh
-        );
+        ////- Construct from dictionary - old syntax
+        //layerParameters
+        //(
+        //    const PtrList<dictionary>& surfaceDicts,
+        //    const refinementSurfaces& refineSurfaces,
+        //    const labelList& globalToPatch,
+        //    const dictionary& dict,
+        //    const polyBoundaryMesh& boundaryMesh
+        //);
 
         //- Construct from dictionary - new syntax
         layerParameters(const dictionary& dict, const polyBoundaryMesh&);
@@ -259,6 +260,12 @@ public:
                 return nSnap_;
             }
 
+            const Switch& additionalReporting() const
+            {
+                return additionalReporting_;
+            }
+
+
             // Overall
 
                 //- Number of overall layer addition iterations
diff --git a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolation.C b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolation.C
index e5abcf818f39de8051ac066b07f90872e32ac9e4..535583a9e13578de3a750ce3804e15122273fc17 100644
--- a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolation.C
+++ b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolation.C
@@ -97,9 +97,10 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::checkPatches
     boundBox bbSrc(srcPatch.points(), srcPatch.meshPoints());
     boundBox bbTgt(tgtPatch.points(), tgtPatch.meshPoints());
 
-    bbTgt.inflate(maxBoundsError);
+    boundBox bbTgtInf(bbTgt);
+    bbTgtInf.inflate(maxBoundsError);
 
-    if (!bbTgt.contains(bbSrc))
+    if (!bbTgtInf.contains(bbSrc))
     {
         WarningIn
         (
@@ -109,14 +110,46 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::checkPatches
                 "const primitivePatch&"
             ")"
         )   << "Source and target patch bounding boxes are not similar" << nl
-            << "    src span : " << bbSrc.span() << nl
-            << "    tgt span : " << bbTgt.span() << nl
-            << "    source: " << bbSrc << nl
-            << "    target: " << bbTgt << endl;
+            << "    source box span     : " << bbSrc.span() << nl
+            << "    target box span     : " << bbTgt.span() << nl
+            << "    source box          : " << bbSrc << nl
+            << "    target box          : " << bbTgt << nl
+            << "    inflated target box : " << bbTgtInf << endl;
     }
 }
 
 
+template<class SourcePatch, class TargetPatch>
+bool Foam::AMIInterpolation<SourcePatch, TargetPatch>::distributed
+(
+    const primitivePatch& srcPatch,
+    const primitivePatch& tgtPatch
+)
+{
+    if (Pstream::parRun())
+    {
+        List<label> facesPresentOnProc(Pstream::nProcs(), 0);
+        if ((srcPatch.size() > 0) || (tgtPatch.size() > 0))
+        {
+            facesPresentOnProc[Pstream::myProcNo()] = 1;
+        }
+        else
+        {
+            facesPresentOnProc[Pstream::myProcNo()] = 0;
+        }
+
+        Pstream::gatherList(facesPresentOnProc);
+        Pstream::scatterList(facesPresentOnProc);
+        if (sum(facesPresentOnProc) > 1)
+        {
+            return true;
+        }
+    }
+    
+    return false;
+}
+
+
 template<class SourcePatch, class TargetPatch>
 Foam::label
 Foam::AMIInterpolation<SourcePatch, TargetPatch>::calcOverlappingProcs
@@ -1158,7 +1191,7 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::update
 {
     static label patchI = 0;
 
-    if (Pstream::parRun())
+    if (Pstream::parRun() && distributed(srcPatch, tgtPatch))
     {
         // convert local addressing to global addressing
         globalIndex globalSrcFaces(srcPatch.size());
diff --git a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolation.H b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolation.H
index 8ad3be39ba079b7f9d4aa2782220acc563603bea..b9d73f24ee3446bae541fea490636b7d0a56df8d 100644
--- a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolation.H
+++ b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolation.H
@@ -167,6 +167,13 @@ class AMIInterpolation
 
         // Parallel functionality
 
+            //- Return true if faces are spread over multiple domains
+            bool distributed
+            (
+                const primitivePatch& srcPatch,
+                const primitivePatch& tgtPatch
+            );
+
             label calcOverlappingProcs
             (
                 const List<treeBoundBoxList>& procBb,
diff --git a/src/meshTools/mappedPatches/mappedPolyPatch/mappedPatchBase.H b/src/meshTools/mappedPatches/mappedPolyPatch/mappedPatchBase.H
index 34c7fa54792055d48b3ab1619549e2dc7b851fcd..68c432e97aadc3be08e4cdfea6b34cabe048b8ff 100644
--- a/src/meshTools/mappedPatches/mappedPolyPatch/mappedPatchBase.H
+++ b/src/meshTools/mappedPatches/mappedPolyPatch/mappedPatchBase.H
@@ -112,6 +112,10 @@ public:
             NORMAL              // use face normal + distance
         };
 
+        static const NamedEnum<sampleMode, 4> sampleModeNames_;
+
+        static const NamedEnum<offsetMode, 3> offsetModeNames_;
+
 
     //- Helper class for finding nearest
     // Nearest:
@@ -142,13 +146,9 @@ public:
     };
 
 
-private:
-
-    // Private data
-
-        static const NamedEnum<sampleMode, 4> sampleModeNames_;
+protected:
 
-        static const NamedEnum<offsetMode, 3> offsetModeNames_;
+    // Protected data
 
         //- Patch to sample
         const polyPatch& patch_;
@@ -199,7 +199,7 @@ private:
             dictionary surfDict_;
 
 
-    // Private Member Functions
+    // Protected Member Functions
 
         //- Collect single list of samples and originating processor+face.
         void collectSamples
@@ -339,6 +339,26 @@ public:
         }
 
 
+        //- Wrapper around map/interpolate data distribution
+        template<class Type>
+        void reverseDistribute(List<Type>& lst) const
+        {
+            switch (mode_)
+            {
+                case NEARESTPATCHFACEAMI:
+                {
+                    lst = AMI().interpolateToTarget(Field<Type>(lst.xfer()));
+                    break;
+                }
+                default:
+                {
+                    label cSize = patch_.size();
+                    map().reverseDistribute(cSize, lst);
+                }
+            }
+        }
+
+
         //- Return reference to the parallel distribution map
         const mapDistribute& map() const
         {
diff --git a/src/parallel/decompose/Allwmake b/src/parallel/decompose/Allwmake
index b620b27791e388a86f88b3b59474cc60769a7cf4..9d0acbd618a5b0fa9b7de804494e790f3d59f195 100755
--- a/src/parallel/decompose/Allwmake
+++ b/src/parallel/decompose/Allwmake
@@ -53,4 +53,6 @@ fi
 
 wmake $makeType decompositionMethods
 
+wmake $makeType decompose
+
 # ----------------------------------------------------------------- end-of-file
diff --git a/src/parallel/decompose/decompose/Make/files b/src/parallel/decompose/decompose/Make/files
new file mode 100644
index 0000000000000000000000000000000000000000..2d0f959eaed2fa913a61f4cdbaf873f4d465ece5
--- /dev/null
+++ b/src/parallel/decompose/decompose/Make/files
@@ -0,0 +1,3 @@
+fvFieldDecomposer.C
+
+LIB = $(FOAM_LIBBIN)/libdecompose
diff --git a/src/parallel/decompose/decompose/Make/options b/src/parallel/decompose/decompose/Make/options
new file mode 100644
index 0000000000000000000000000000000000000000..7a728f9dd7cf75800c9b44943a2964c781376576
--- /dev/null
+++ b/src/parallel/decompose/decompose/Make/options
@@ -0,0 +1,9 @@
+EXE_INC = \
+    -I$(LIB_SRC)/finiteVolume/lnInclude \
+    -I$(LIB_SRC)/meshTools/lnInclude \
+    -I$(LIB_SRC)/lagrangian/basic/lnInclude
+
+LIB_LIBS = \
+    -lfiniteVolume \
+    -lmeshTools \
+    -llagrangian
diff --git a/applications/utilities/parallelProcessing/decomposePar/fvFieldDecomposer.C b/src/parallel/decompose/decompose/fvFieldDecomposer.C
similarity index 100%
rename from applications/utilities/parallelProcessing/decomposePar/fvFieldDecomposer.C
rename to src/parallel/decompose/decompose/fvFieldDecomposer.C
diff --git a/applications/utilities/parallelProcessing/decomposePar/fvFieldDecomposer.H b/src/parallel/decompose/decompose/fvFieldDecomposer.H
similarity index 99%
rename from applications/utilities/parallelProcessing/decomposePar/fvFieldDecomposer.H
rename to src/parallel/decompose/decompose/fvFieldDecomposer.H
index ee87db59f41bf3e00d3ffbe17f5dac53656a4cdf..899b45b4b7550369f031279310f0456174cd9edc 100644
--- a/applications/utilities/parallelProcessing/decomposePar/fvFieldDecomposer.H
+++ b/src/parallel/decompose/decompose/fvFieldDecomposer.H
@@ -241,7 +241,8 @@ public:
         tmp<GeometricField<Type, fvPatchField, volMesh> >
         decomposeField
         (
-            const GeometricField<Type, fvPatchField, volMesh>& field
+            const GeometricField<Type, fvPatchField, volMesh>& field,
+            const bool allowUnknownPatchFields = false
         ) const;
 
         //- Decompose surface field
diff --git a/applications/utilities/parallelProcessing/decomposePar/fvFieldDecomposerDecomposeFields.C b/src/parallel/decompose/decompose/fvFieldDecomposerDecomposeFields.C
similarity index 94%
rename from applications/utilities/parallelProcessing/decomposePar/fvFieldDecomposerDecomposeFields.C
rename to src/parallel/decompose/decompose/fvFieldDecomposerDecomposeFields.C
index 0bce0023cc8b3c23e94e2213a79464351921ed08..ca9d0e31b5eaa8f2c361864c93e32ee5e6fd452c 100644
--- a/applications/utilities/parallelProcessing/decomposePar/fvFieldDecomposerDecomposeFields.C
+++ b/src/parallel/decompose/decompose/fvFieldDecomposerDecomposeFields.C
@@ -28,6 +28,7 @@ License
 #include "processorFvsPatchField.H"
 #include "processorCyclicFvPatchField.H"
 #include "processorCyclicFvsPatchField.H"
+#include "emptyFvPatchFields.H"
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
@@ -35,7 +36,8 @@ template<class Type>
 Foam::tmp<Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh> >
 Foam::fvFieldDecomposer::decomposeField
 (
-    const GeometricField<Type, fvPatchField, volMesh>& field
+    const GeometricField<Type, fvPatchField, volMesh>& field,
+    const bool allowUnknownPatchFields
 ) const
 {
     // Create and map the internal field values
@@ -94,6 +96,18 @@ Foam::fvFieldDecomposer::decomposeField
                 )
             );
         }
+        else if (allowUnknownPatchFields)
+        {
+            patchFields.set
+            (
+                patchi,
+                new emptyFvPatchField<Type>
+                (
+                    procMesh_.boundary()[patchi],
+                    DimensionedField<Type, volMesh>::null()
+                )
+            );
+        }
         else
         {
             FatalErrorIn("fvFieldDecomposer::decomposeField()")
diff --git a/src/parallel/decompose/ptscotchDecomp/Make/options b/src/parallel/decompose/ptscotchDecomp/Make/options
index ea5b0c3ad86980e25b0df4a363698d05c9a1fd65..1e34631aa1b218aa0ba7f2af1e1becd6a7bcdbd4 100644
--- a/src/parallel/decompose/ptscotchDecomp/Make/options
+++ b/src/parallel/decompose/ptscotchDecomp/Make/options
@@ -3,9 +3,10 @@ sinclude $(RULES)/mplib$(WM_MPLIB)
 
 EXE_INC = \
     $(PFLAGS) $(PINC) \
+    -I$(SCOTCH_ROOT)/include \
     -I$(SCOTCH_ARCH_PATH)/include/$(FOAM_MPI) \
     -I/usr/include/scotch \
     -I../decompositionMethods/lnInclude
 
 LIB_LIBS = \
-    -L$(FOAM_EXT_LIBBIN)/$(FOAM_MPI) -lptscotch -lptscotcherrexit -lrt
+    -L$(SCOTCH_ROOT)/lib -L$(FOAM_EXT_LIBBIN)/$(FOAM_MPI) -lptscotch -lptscotcherrexit -lrt
diff --git a/src/parallel/decompose/scotchDecomp/Make/options b/src/parallel/decompose/scotchDecomp/Make/options
index b2f7015e2468f922d206bb5aae2fd650906c85d7..3bb11fba5ceada224270469fee5b19db0901a8a4 100644
--- a/src/parallel/decompose/scotchDecomp/Make/options
+++ b/src/parallel/decompose/scotchDecomp/Make/options
@@ -7,9 +7,10 @@ sinclude $(RULES)/mplib$(WM_MPLIB)
 
 EXE_INC = \
     $(PFLAGS) $(PINC) \
+    -I$(SCOTCH_ROOT)/include \
     -I$(SCOTCH_ARCH_PATH)/include \
     -I/usr/include/scotch \
     -I../decompositionMethods/lnInclude
 
 LIB_LIBS = \
-    -L$(FOAM_EXT_LIBBIN) -lscotch -lscotcherrexit -lrt
+    -L$(SCOTCH_ROOT)/lib -L$(FOAM_EXT_LIBBIN) -lscotch -lscotcherrexit -lrt
diff --git a/src/parallel/reconstruct/reconstruct/fvFieldReconstructor.C b/src/parallel/reconstruct/reconstruct/fvFieldReconstructor.C
index 93fbb8bb995831528b07f879b15d8d77efe122e0..3c85d65c6eb68e97191d0a3e7210e2d42c9ae75f 100644
--- a/src/parallel/reconstruct/reconstruct/fvFieldReconstructor.C
+++ b/src/parallel/reconstruct/reconstruct/fvFieldReconstructor.C
@@ -42,7 +42,40 @@ Foam::fvFieldReconstructor::fvFieldReconstructor
     cellProcAddressing_(cellProcAddressing),
     boundaryProcAddressing_(boundaryProcAddressing),
     nReconstructed_(0)
-{}
+{
+    forAll(procMeshes_, procI)
+    {
+        const fvMesh& procMesh = procMeshes_[procI];
+        if
+        (
+            faceProcAddressing[procI].size() != procMesh.nFaces()
+         || cellProcAddressing[procI].size() != procMesh.nCells()
+         || boundaryProcAddressing[procI].size() != procMesh.boundary().size()
+        )
+        {
+            FatalErrorIn
+            (
+                "fvFieldReconstructor::fvFieldReconstructor\n"
+                "(\n"
+                "   fvMesh&,\n"
+                "   const PtrList<fvMesh>&,\n"
+                "   const PtrList<labelIOList>&,\n"
+                "   const PtrList<labelIOList>&,\n"
+                "   const PtrList<labelIOList>&\n"
+                ")"
+            )   << "Size of maps does not correspond to size of mesh"
+                << " for processor " << procI << endl
+                << "faceProcAddressing : " << faceProcAddressing[procI].size()
+                << " nFaces : " << procMesh.nFaces() << endl
+                << "cellProcAddressing : " << cellProcAddressing[procI].size()
+                << " nCell : " << procMesh.nCells() << endl
+                << "boundaryProcAddressing : "
+                << boundaryProcAddressing[procI].size()
+                << " nFaces : " << procMesh.boundary().size()
+                << exit(FatalError);
+        }
+    }
+}
 
 
 // ************************************************************************* //
diff --git a/src/parallel/reconstruct/reconstruct/fvFieldReconstructor.H b/src/parallel/reconstruct/reconstruct/fvFieldReconstructor.H
index 2aa3011195c8d23d20e8d63ea51ebf0c161af818..43469d24b4f0b6899b08833516ee84e44b3bd709 100644
--- a/src/parallel/reconstruct/reconstruct/fvFieldReconstructor.H
+++ b/src/parallel/reconstruct/reconstruct/fvFieldReconstructor.H
@@ -86,6 +86,7 @@ class fvFieldReconstructor
 
 public:
 
+        //- Mapper for sizing only - does not do any actual mapping.
         class fvPatchFieldReconstructor
         :
             public fvPatchFieldMapper
@@ -146,19 +147,48 @@ public:
         //- Reconstruct volume internal field
         template<class Type>
         tmp<DimensionedField<Type, volMesh> >
-        reconstructFvVolumeInternalField(const IOobject& fieldIoObject);
+        reconstructFvVolumeInternalField
+        (
+            const IOobject& fieldIoObject,
+            const PtrList<DimensionedField<Type, volMesh> >& procFields
+        ) const;
+
+        //- Read and reconstruct volume internal field
+        template<class Type>
+        tmp<DimensionedField<Type, volMesh> >
+        reconstructFvVolumeInternalField(const IOobject& fieldIoObject) const;
+
 
         //- Reconstruct volume field
         template<class Type>
         tmp<GeometricField<Type, fvPatchField, volMesh> >
-        reconstructFvVolumeField(const IOobject& fieldIoObject);
+        reconstructFvVolumeField
+        (
+            const IOobject& fieldIoObject,
+            const PtrList<GeometricField<Type, fvPatchField, volMesh> >&
+        ) const;
+
+        //- Read and reconstruct volume field
+        template<class Type>
+        tmp<GeometricField<Type, fvPatchField, volMesh> >
+        reconstructFvVolumeField(const IOobject& fieldIoObject) const;
+
 
         //- Reconstruct surface field
         template<class Type>
         tmp<GeometricField<Type, fvsPatchField, surfaceMesh> >
-        reconstructFvSurfaceField(const IOobject& fieldIoObject);
+        reconstructFvSurfaceField
+        (
+            const IOobject& fieldIoObject,
+            const PtrList<GeometricField<Type, fvsPatchField, surfaceMesh> >&
+        ) const;
+
+        //- Read and reconstruct surface field
+        template<class Type>
+        tmp<GeometricField<Type, fvsPatchField, surfaceMesh> >
+        reconstructFvSurfaceField(const IOobject& fieldIoObject) const;
 
-        //- Reconstruct and write all/selected volume internal fields
+        //- Read, reconstruct and write all/selected volume internal fields
         template<class Type>
         void reconstructFvVolumeInternalFields
         (
@@ -166,7 +196,7 @@ public:
             const HashSet<word>& selectedFields
         );
 
-        //- Reconstruct and write all/selected volume fields
+        //- Read, reconstruct and write all/selected volume fields
         template<class Type>
         void reconstructFvVolumeFields
         (
@@ -174,7 +204,7 @@ public:
             const HashSet<word>& selectedFields
         );
 
-        //- Reconstruct and write all/selected surface fields
+        //- Read, reconstruct and write all/selected surface fields
         template<class Type>
         void reconstructFvSurfaceFields
         (
diff --git a/src/parallel/reconstruct/reconstruct/fvFieldReconstructorReconstructFields.C b/src/parallel/reconstruct/reconstruct/fvFieldReconstructorReconstructFields.C
index 9a0dfb4b3cf3d519b45ea4dadb38b2fb5702189d..33105892ce685436b15d5364686cb0746558fac5 100644
--- a/src/parallel/reconstruct/reconstruct/fvFieldReconstructorReconstructFields.C
+++ b/src/parallel/reconstruct/reconstruct/fvFieldReconstructorReconstructFields.C
@@ -37,36 +37,10 @@ template<class Type>
 Foam::tmp<Foam::DimensionedField<Type, Foam::volMesh> >
 Foam::fvFieldReconstructor::reconstructFvVolumeInternalField
 (
-    const IOobject& fieldIoObject
-)
+    const IOobject& fieldIoObject,
+    const PtrList<DimensionedField<Type, volMesh> >& procFields
+) const
 {
-    // Read the field for all the processors
-    PtrList<DimensionedField<Type, volMesh> > procFields
-    (
-        procMeshes_.size()
-    );
-
-    forAll(procMeshes_, procI)
-    {
-        procFields.set
-        (
-            procI,
-            new DimensionedField<Type, volMesh>
-            (
-                IOobject
-                (
-                    fieldIoObject.name(),
-                    procMeshes_[procI].time().timeName(),
-                    procMeshes_[procI],
-                    IOobject::MUST_READ,
-                    IOobject::NO_WRITE
-                ),
-                procMeshes_[procI]
-            )
-        );
-    }
-
-
     // Create the internalField
     Field<Type> internalField(mesh_.nCells());
 
@@ -86,14 +60,7 @@ Foam::fvFieldReconstructor::reconstructFvVolumeInternalField
     (
         new DimensionedField<Type, volMesh>
         (
-            IOobject
-            (
-                fieldIoObject.name(),
-                mesh_.time().timeName(),
-                mesh_,
-                IOobject::NO_READ,
-                IOobject::NO_WRITE
-            ),
+            fieldIoObject,
             mesh_,
             procFields[0].dimensions(),
             internalField
@@ -103,14 +70,14 @@ Foam::fvFieldReconstructor::reconstructFvVolumeInternalField
 
 
 template<class Type>
-Foam::tmp<Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh> >
-Foam::fvFieldReconstructor::reconstructFvVolumeField
+Foam::tmp<Foam::DimensionedField<Type, Foam::volMesh> >
+Foam::fvFieldReconstructor::reconstructFvVolumeInternalField
 (
     const IOobject& fieldIoObject
-)
+) const
 {
     // Read the field for all the processors
-    PtrList<GeometricField<Type, fvPatchField, volMesh> > procFields
+    PtrList<DimensionedField<Type, volMesh> > procFields
     (
         procMeshes_.size()
     );
@@ -120,7 +87,7 @@ Foam::fvFieldReconstructor::reconstructFvVolumeField
         procFields.set
         (
             procI,
-            new GeometricField<Type, fvPatchField, volMesh>
+            new DimensionedField<Type, volMesh>
             (
                 IOobject
                 (
@@ -136,14 +103,36 @@ Foam::fvFieldReconstructor::reconstructFvVolumeField
     }
 
 
+    return reconstructFvVolumeInternalField
+    (
+        IOobject
+        (
+            fieldIoObject.name(),
+            mesh_.time().timeName(),
+            mesh_,
+            IOobject::NO_READ,
+            IOobject::NO_WRITE
+        ),
+        procFields
+    );
+}
+
+
+template<class Type>
+Foam::tmp<Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh> >
+Foam::fvFieldReconstructor::reconstructFvVolumeField
+(
+    const IOobject& fieldIoObject,
+    const PtrList<GeometricField<Type, fvPatchField, volMesh> >& procFields
+) const
+{
     // Create the internalField
     Field<Type> internalField(mesh_.nCells());
 
     // Create the patch fields
     PtrList<fvPatchField<Type> > patchFields(mesh_.boundary().size());
 
-
-    forAll(procMeshes_, procI)
+    forAll(procFields, procI)
     {
         const GeometricField<Type, fvPatchField, volMesh>& procField =
             procFields[procI];
@@ -163,7 +152,7 @@ Foam::fvFieldReconstructor::reconstructFvVolumeField
 
             // Get addressing slice for this patch
             const labelList::subList cp =
-                procMeshes_[procI].boundary()[patchI].patchSlice
+                procField.mesh().boundary()[patchI].patchSlice
                 (
                     faceProcAddressing_[procI]
                 );
@@ -198,11 +187,32 @@ Foam::fvFieldReconstructor::reconstructFvVolumeField
 
                 forAll(cp, faceI)
                 {
+                    // Check
+                    if (cp[faceI] <= 0)
+                    {
+                        FatalErrorIn
+                        (
+                            "fvFieldReconstructor::reconstructFvVolumeField\n"
+                            "(\n"
+                            "    const IOobject&,\n"
+                            "    const PtrList<GeometricField<Type,"
+                            " fvPatchField, volMesh> >&\n"
+                            ") const\n"
+                        )   << "Processor " << procI
+                            << " patch "
+                            << procField.mesh().boundary()[patchI].name()
+                            << " face " << faceI
+                            << " originates from reversed face since "
+                            << cp[faceI]
+                            << exit(FatalError);
+                    }
+
                     // Subtract one to take into account offsets for
                     // face direction.
                     reverseAddressing[faceI] = cp[faceI] - 1 - curPatchStart;
                 }
 
+
                 patchFields[curBPatch].rmap
                 (
                     procField.boundaryField()[patchI],
@@ -283,14 +293,7 @@ Foam::fvFieldReconstructor::reconstructFvVolumeField
     (
         new GeometricField<Type, fvPatchField, volMesh>
         (
-            IOobject
-            (
-                fieldIoObject.name(),
-                mesh_.time().timeName(),
-                mesh_,
-                IOobject::NO_READ,
-                IOobject::NO_WRITE
-            ),
+            fieldIoObject,
             mesh_,
             procFields[0].dimensions(),
             internalField,
@@ -301,14 +304,14 @@ Foam::fvFieldReconstructor::reconstructFvVolumeField
 
 
 template<class Type>
-Foam::tmp<Foam::GeometricField<Type, Foam::fvsPatchField, Foam::surfaceMesh> >
-Foam::fvFieldReconstructor::reconstructFvSurfaceField
+Foam::tmp<Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh> >
+Foam::fvFieldReconstructor::reconstructFvVolumeField
 (
     const IOobject& fieldIoObject
-)
+) const
 {
     // Read the field for all the processors
-    PtrList<GeometricField<Type, fvsPatchField, surfaceMesh> > procFields
+    PtrList<GeometricField<Type, fvPatchField, volMesh> > procFields
     (
         procMeshes_.size()
     );
@@ -318,7 +321,7 @@ Foam::fvFieldReconstructor::reconstructFvSurfaceField
         procFields.set
         (
             procI,
-            new GeometricField<Type, fvsPatchField, surfaceMesh>
+            new GeometricField<Type, fvPatchField, volMesh>
             (
                 IOobject
                 (
@@ -333,7 +336,29 @@ Foam::fvFieldReconstructor::reconstructFvSurfaceField
         );
     }
 
+    return reconstructFvVolumeField
+    (
+        IOobject
+        (
+            fieldIoObject.name(),
+            mesh_.time().timeName(),
+            mesh_,
+            IOobject::NO_READ,
+            IOobject::NO_WRITE
+        ),
+        procFields
+    );
+}
+
 
+template<class Type>
+Foam::tmp<Foam::GeometricField<Type, Foam::fvsPatchField, Foam::surfaceMesh> >
+Foam::fvFieldReconstructor::reconstructFvSurfaceField
+(
+    const IOobject& fieldIoObject,
+    const PtrList<GeometricField<Type, fvsPatchField, surfaceMesh> >& procFields
+) const
+{
     // Create the internalField
     Field<Type> internalField(mesh_.nInternalFaces());
 
@@ -503,14 +528,7 @@ Foam::fvFieldReconstructor::reconstructFvSurfaceField
     (
         new GeometricField<Type, fvsPatchField, surfaceMesh>
         (
-            IOobject
-            (
-                fieldIoObject.name(),
-                mesh_.time().timeName(),
-                mesh_,
-                IOobject::NO_READ,
-                IOobject::NO_WRITE
-            ),
+            fieldIoObject,
             mesh_,
             procFields[0].dimensions(),
             internalField,
@@ -520,6 +538,54 @@ Foam::fvFieldReconstructor::reconstructFvSurfaceField
 }
 
 
+template<class Type>
+Foam::tmp<Foam::GeometricField<Type, Foam::fvsPatchField, Foam::surfaceMesh> >
+Foam::fvFieldReconstructor::reconstructFvSurfaceField
+(
+    const IOobject& fieldIoObject
+) const
+{
+    // Read the field for all the processors
+    PtrList<GeometricField<Type, fvsPatchField, surfaceMesh> > procFields
+    (
+        procMeshes_.size()
+    );
+
+    forAll(procMeshes_, procI)
+    {
+        procFields.set
+        (
+            procI,
+            new GeometricField<Type, fvsPatchField, surfaceMesh>
+            (
+                IOobject
+                (
+                    fieldIoObject.name(),
+                    procMeshes_[procI].time().timeName(),
+                    procMeshes_[procI],
+                    IOobject::MUST_READ,
+                    IOobject::NO_WRITE
+                ),
+                procMeshes_[procI]
+            )
+        );
+    }
+
+    return reconstructFvSurfaceField
+    (
+        IOobject
+        (
+            fieldIoObject.name(),
+            mesh_.time().timeName(),
+            mesh_,
+            IOobject::NO_READ,
+            IOobject::NO_WRITE
+        ),
+        procFields
+    );
+}
+
+
 template<class Type>
 void Foam::fvFieldReconstructor::reconstructFvVolumeInternalFields
 (
diff --git a/src/postProcessing/functionObjects/forces/forces/forces.C b/src/postProcessing/functionObjects/forces/forces/forces.C
index d585569649e09ec581fd4f14e67da84dfcc2bad8..1dd26906b74487d46da744e23d9f1c2a68dc67cd 100644
--- a/src/postProcessing/functionObjects/forces/forces/forces.C
+++ b/src/postProcessing/functionObjects/forces/forces/forces.C
@@ -190,6 +190,7 @@ Foam::forces::forces
     rhoRef_(VGREAT),
     pRef_(0),
     coordSys_(),
+    localSystem_(false),
     forcesFilePtr_(NULL)
 {
     // Check if the available mesh is an fvMesh otherise deactivate
@@ -239,6 +240,7 @@ Foam::forces::forces
     rhoRef_(rhoInf),
     pRef_(pRef),
     coordSys_(coordSys),
+    localSystem_(false),
     forcesFilePtr_(NULL)
 {}
 
@@ -330,6 +332,7 @@ void Foam::forces::read(const dictionary& dict)
         if (!dict.readIfPresent<point>("CofR", coordSys_.origin()))
         {
             coordSys_ = coordinateSystem(dict, obr_);
+            localSystem_ = true;
         }
     }
 }
@@ -382,10 +385,17 @@ void Foam::forces::writeFileHeader()
     {
         forcesFilePtr_()
             << "# Time" << tab
-            << "forces(pressure, viscous) moment(pressure, viscous)"
-            << tab
-            << "local forces(pressure, viscous) local moment(pressure, viscous)"
-            << endl;
+            << "forces(pressure, viscous) moment(pressure, viscous)";
+
+        if (localSystem_)
+        {
+            forcesFilePtr_()
+                << tab
+                << "local forces(pressure, viscous) "
+                << "local moment(pressure, viscous)";
+        }
+
+        forcesFilePtr_()<< endl;
     }
 }
 
@@ -413,33 +423,49 @@ void Foam::forces::write()
 
         if (Pstream::master())
         {
-            forcesMoments fmLocal;
+            if (log_)
+            {
+                Info<< "forces output:" << nl
+                    << "    forces(pressure, viscous)" << fm.first() << nl
+                    << "    moment(pressure, viscous)" << fm.second() << nl;
+            }
+
+            forcesFilePtr_() << obr_.time().value() << tab << fm;
 
-            fmLocal.first().first() =
-                coordSys_.localVector(fm.first().first());
+            if (localSystem_)
+            {
+                forcesMoments fmLocal;
+
+                fmLocal.first().first() =
+                    coordSys_.localVector(fm.first().first());
+
+                fmLocal.first().second() =
+                    coordSys_.localVector(fm.first().second());
 
-            fmLocal.first().second() =
-                coordSys_.localVector(fm.first().second());
+                fmLocal.second().first() =
+                    coordSys_.localVector(fm.second().first());
 
-            fmLocal.second().first() =
-                coordSys_.localVector(fm.second().first());
+                fmLocal.second().second() =
+                    coordSys_.localVector(fm.second().second());
 
-            fmLocal.second().second() =
-                coordSys_.localVector(fm.second().second());
+                forcesFilePtr_() << tab << fmLocal;
 
-            forcesFilePtr_() << obr_.time().value()
-                << tab << fm
-                << tab << fmLocal << endl;
+                if (log_)
+                {
+                    Info<< "  local:" << nl
+                        << "    forces(pressure, viscous)" << fmLocal.first()
+                        << nl
+                        << "    moment(pressure, viscous)" << fmLocal.second()
+                        << nl;
+                }
+            }
+
+
+            forcesFilePtr_() << endl;
 
             if (log_)
             {
-                Info<< "forces output:" << nl
-                    << "    forces(pressure, viscous)" << fm.first() << nl
-                    << "    moment(pressure, viscous)" << fm.second() << nl
-                    << "  local:" << nl
-                    << "    forces(pressure, viscous)" << fmLocal.first() << nl
-                    << "    moment(pressure, viscous)" << fmLocal.second() << nl
-                    << endl;
+                Info<< endl;
             }
         }
     }
diff --git a/src/postProcessing/functionObjects/forces/forces/forces.H b/src/postProcessing/functionObjects/forces/forces/forces.H
index eb46c057d53503b42ca49b3dec52fe445ec7d2db..3d14768b2b8a7b2f8ac9f4a63fea6c48367d2cb8 100644
--- a/src/postProcessing/functionObjects/forces/forces/forces.H
+++ b/src/postProcessing/functionObjects/forces/forces/forces.H
@@ -165,6 +165,9 @@ protected:
             //- Coordinate system used when evaluting forces/moments
             coordinateSystem coordSys_;
 
+            //- Flag to indicate whether we are using a local co-ordinate sys
+            bool localSystem_;
+
 
         //- Forces/moment file ptr
         autoPtr<OFstream> forcesFilePtr_;
diff --git a/src/postProcessing/postCalc/postCalc.C b/src/postProcessing/postCalc/postCalc.C
index f477818a4ce0d9a13132ba88091d0bae591b83f8..ff2dd174e0781c46feeaddeab750da2bd0abab53 100644
--- a/src/postProcessing/postCalc/postCalc.C
+++ b/src/postProcessing/postCalc/postCalc.C
@@ -57,11 +57,17 @@ namespace Foam
 int main(int argc, char *argv[])
 {
     Foam::timeSelector::addOptions();
+#   include "addRegionOption.H"
     Foam::argList::addBoolOption
     (
         "noWrite",
         "suppress writing results"
     );
+    Foam::argList::addBoolOption
+    (
+        "noFlow",
+        "suppress creating flow models (execFlowFunctionObjects only)"
+    );
     Foam::argList::addOption
     (
         "dict",
@@ -72,7 +78,7 @@ int main(int argc, char *argv[])
     #include "setRootCase.H"
     #include "createTime.H"
     Foam::instantList timeDirs = Foam::timeSelector::select0(runTime, args);
-    #include "createMesh.H"
+    #include "createNamedMesh.H"
 
     forAll(timeDirs, timeI)
     {
diff --git a/src/regionModels/regionCoupling/derivedFvPatchFields/filmPyrolysisTemperatureCoupled/filmPyrolysisTemperatureCoupledFvPatchScalarField.C b/src/regionModels/regionCoupling/derivedFvPatchFields/filmPyrolysisTemperatureCoupled/filmPyrolysisTemperatureCoupledFvPatchScalarField.C
index 8351d49d2da3ecc1cc8b04df86ad661bffffff0b..b0f8d1629a919d008f1267e6dcb99cc5562aef3b 100644
--- a/src/regionModels/regionCoupling/derivedFvPatchFields/filmPyrolysisTemperatureCoupled/filmPyrolysisTemperatureCoupledFvPatchScalarField.C
+++ b/src/regionModels/regionCoupling/derivedFvPatchFields/filmPyrolysisTemperatureCoupled/filmPyrolysisTemperatureCoupledFvPatchScalarField.C
@@ -151,13 +151,11 @@ void Foam::filmPyrolysisTemperatureCoupledFvPatchScalarField::updateCoeffs()
 
     const label filmPatchI = filmModel.regionPatchID(patchI);
 
-    const mappedPatchBase& filmMap = filmModel.mappedPatches()[filmPatchI];
-
     scalarField deltaFilm = filmModel.delta().boundaryField()[filmPatchI];
-    filmMap.distribute(deltaFilm);
+    filmModel.toPrimary(filmPatchI, deltaFilm);
 
     scalarField TFilm = filmModel.Ts().boundaryField()[filmPatchI];
-    filmMap.distribute(TFilm);
+    filmModel.toPrimary(filmPatchI, TFilm);
 
 
     // Retrieve pyrolysis model
@@ -166,10 +164,8 @@ void Foam::filmPyrolysisTemperatureCoupledFvPatchScalarField::updateCoeffs()
 
     const label pyrPatchI = pyrModel.regionPatchID(patchI);
 
-    const mappedPatchBase& pyrMap = pyrModel.mappedPatches()[pyrPatchI];
-
     scalarField TPyr = pyrModel.T().boundaryField()[pyrPatchI];
-    pyrMap.distribute(TPyr);
+    pyrModel.toPrimary(pyrPatchI, TPyr);
 
 
     forAll(deltaFilm, i)
diff --git a/src/regionModels/regionCoupling/derivedFvPatchFields/filmPyrolysisVelocityCoupled/filmPyrolysisVelocityCoupledFvPatchVectorField.C b/src/regionModels/regionCoupling/derivedFvPatchFields/filmPyrolysisVelocityCoupled/filmPyrolysisVelocityCoupledFvPatchVectorField.C
index a516534fa81d8b88fa72f28159f6175a893169ed..29b3e345868bcc112d33535b76bb42e1f89448f6 100644
--- a/src/regionModels/regionCoupling/derivedFvPatchFields/filmPyrolysisVelocityCoupled/filmPyrolysisVelocityCoupledFvPatchVectorField.C
+++ b/src/regionModels/regionCoupling/derivedFvPatchFields/filmPyrolysisVelocityCoupled/filmPyrolysisVelocityCoupledFvPatchVectorField.C
@@ -154,13 +154,11 @@ void Foam::filmPyrolysisVelocityCoupledFvPatchVectorField::updateCoeffs()
 
     const label filmPatchI = filmModel.regionPatchID(patchI);
 
-    const mappedPatchBase& filmMap = filmModel.mappedPatches()[filmPatchI];
-
     scalarField deltaFilm = filmModel.delta().boundaryField()[filmPatchI];
-    filmMap.distribute(deltaFilm);
+    filmModel.toPrimary(filmPatchI, deltaFilm);
 
     vectorField UFilm = filmModel.Us().boundaryField()[filmPatchI];
-    filmMap.distribute(UFilm);
+    filmModel.toPrimary(filmPatchI, UFilm);
 
 
     // Retrieve pyrolysis model
@@ -172,10 +170,8 @@ void Foam::filmPyrolysisVelocityCoupledFvPatchVectorField::updateCoeffs()
 
     const label pyrPatchI = pyrModel.regionPatchID(patchI);
 
-    const mappedPatchBase& pyrMap = pyrModel.mappedPatches()[pyrPatchI];
-
     scalarField phiPyr = pyrModel.phiGas().boundaryField()[pyrPatchI];
-    pyrMap.distribute(phiPyr);
+    pyrModel.toPrimary(pyrPatchI, phiPyr);
 
 
     const surfaceScalarField& phi =
diff --git a/src/regionModels/regionModel/regionModel/regionModel.C b/src/regionModels/regionModel/regionModel/regionModel.C
index 1d74a9c6465fd62809fb415218797839a51b5f6d..f7f630147eb734424cf6ea8cab833d636df100c6 100644
--- a/src/regionModels/regionModel/regionModel/regionModel.C
+++ b/src/regionModels/regionModel/regionModel/regionModel.C
@@ -93,8 +93,6 @@ void Foam::regionModels::regionModel::initialise()
     DynamicList<label> primaryPatchIDs;
     DynamicList<label> intCoupledPatchIDs;
     const polyBoundaryMesh& rbm = regionMesh().boundaryMesh();
-    const polyBoundaryMesh& pbm = primaryMesh().boundaryMesh();
-    mappedPatches_.setSize(rbm.size());
 
     forAll(rbm, patchI)
     {
@@ -116,19 +114,6 @@ void Foam::regionModels::regionModel::initialise()
 
             const label primaryPatchI = mapPatch.samplePolyPatch().index();
             primaryPatchIDs.append(primaryPatchI);
-
-            mappedPatches_.set
-            (
-                patchI,
-                new mappedPatchBase
-                (
-                    pbm[primaryPatchI],
-                    regionMesh().name(),
-                    mapPatch.mode(),
-                    regionPatch.name(),
-                    vector::zero
-                )
-            );
         }
     }
 
@@ -212,8 +197,7 @@ Foam::regionModels::regionModel::regionModel(const fvMesh& mesh)
     regionMeshPtr_(NULL),
     coeffs_(dictionary::null),
     primaryPatchIDs_(),
-    intCoupledPatchIDs_(),
-    mappedPatches_()
+    intCoupledPatchIDs_()
 {}
 
 
@@ -244,8 +228,7 @@ Foam::regionModels::regionModel::regionModel
     regionMeshPtr_(NULL),
     coeffs_(subOrEmptyDict(modelName + "Coeffs")),
     primaryPatchIDs_(),
-    intCoupledPatchIDs_(),
-    mappedPatches_()
+    intCoupledPatchIDs_()
 {
     if (active_)
     {
@@ -290,8 +273,7 @@ Foam::regionModels::regionModel::regionModel
     regionMeshPtr_(NULL),
     coeffs_(dict.subOrEmptyDict(modelName + "Coeffs")),
     primaryPatchIDs_(),
-    intCoupledPatchIDs_(),
-    mappedPatches_()
+    intCoupledPatchIDs_()
 {
     if (active_)
     {
diff --git a/src/regionModels/regionModel/regionModel/regionModel.H b/src/regionModels/regionModel/regionModel/regionModel.H
index bc9fb54a335335be346beefd7807d3784dd7090a..2af98421d108216d76b5606f0ff7d3bf4abc28cc 100644
--- a/src/regionModels/regionModel/regionModel/regionModel.H
+++ b/src/regionModels/regionModel/regionModel/regionModel.H
@@ -117,9 +117,6 @@ protected:
             //- List of patch IDs internally coupled with the primary region
             labelList intCoupledPatchIDs_;
 
-            //- List of patch map info
-            PtrList<mappedPatchBase> mappedPatches_;
-
 
     // Protected member functions
 
@@ -212,13 +209,29 @@ public:
                 //  primary region
                 inline const labelList& intCoupledPatchIDs() const;
 
-                //- Return the list of patch map info
-                inline const PtrList<mappedPatchBase>& mappedPatches() const;
-
                 //- Return region ID corresponding to primaryPatchID
                 inline label regionPatchID(const label primaryPatchID) const;
 
 
+        // Helper
+
+            //- Convert a local region field to the primary region
+            template<class Type>
+            void toPrimary
+            (
+                const label regionPatchI,
+                List<Type>& regionField
+            ) const;
+
+            //- Convert a primary region field to the local region
+            template<class Type>
+            void toRegion
+            (
+                const label regionPatchI,
+                List<Type>& primaryFieldField
+            ) const;
+
+
         // Evolution
 
             //- Pre-evolve region
@@ -249,6 +262,12 @@ public:
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
+#ifdef NoRepository
+    #include "regionModelTemplates.C"
+#endif
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
 #endif
 
 // ************************************************************************* //
diff --git a/src/regionModels/regionModel/regionModel/regionModelI.H b/src/regionModels/regionModel/regionModel/regionModelI.H
index 197e663d503e2a5dd72eaab257018a5184cebe99..a0e43403f7021bed6682847a1d1d82337304ca5f 100644
--- a/src/regionModels/regionModel/regionModel/regionModelI.H
+++ b/src/regionModels/regionModel/regionModel/regionModelI.H
@@ -132,13 +132,6 @@ Foam::regionModels::regionModel::intCoupledPatchIDs() const
 }
 
 
-inline const Foam::PtrList<Foam::mappedPatchBase>&
-Foam::regionModels::regionModel::mappedPatches() const
-{
-    return mappedPatches_;
-}
-
-
 inline Foam::label Foam::regionModels::regionModel::regionPatchID
 (
     const label primaryPatchID
diff --git a/src/regionModels/regionModel/regionModel/regionModelTemplates.C b/src/regionModels/regionModel/regionModel/regionModelTemplates.C
new file mode 100644
index 0000000000000000000000000000000000000000..977da7dd8167df5a3b5acf703cc09f434602c5b6
--- /dev/null
+++ b/src/regionModels/regionModel/regionModel/regionModelTemplates.C
@@ -0,0 +1,80 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+\*---------------------------------------------------------------------------*/
+
+template<class Type>
+void Foam::regionModels::regionModel::toPrimary
+(
+    const label regionPatchI,
+    List<Type>& regionField
+) const
+{
+    forAll(intCoupledPatchIDs_, i)
+    {
+        if (intCoupledPatchIDs_[i] == regionPatchI)
+        {
+            const mappedPatchBase& mpb =
+                refCast<const mappedPatchBase>
+                (
+                    regionMesh().boundaryMesh()[regionPatchI]
+                );
+            mpb.reverseDistribute(regionField);
+            return;
+        }
+    }
+
+    FatalErrorIn("const void toPrimary(const label, List<Type>&) const")
+        << "Region patch ID " << regionPatchI << " not found in region mesh"
+        << abort(FatalError);
+}
+
+
+template<class Type>
+void Foam::regionModels::regionModel::toRegion
+(
+    const label regionPatchI,
+    List<Type>& primaryField
+) const
+{
+    forAll(intCoupledPatchIDs_, i)
+    {
+        if (intCoupledPatchIDs_[i] == regionPatchI)
+        {
+            const mappedPatchBase& mpb =
+                refCast<const mappedPatchBase>
+                (
+                    regionMesh().boundaryMesh()[regionPatchI]
+                );
+            mpb.distribute(primaryField);
+            return;
+        }
+    }
+
+    FatalErrorIn("const void toRegion(const label, List<Type>&) const")
+        << "Region patch ID " << regionPatchI << " not found in region mesh"
+        << abort(FatalError);
+}
+
+
+// ************************************************************************* //
diff --git a/src/regionModels/surfaceFilmModels/derivedFvPatchFields/wallFunctions/alphatFilmWallFunction/alphatFilmWallFunctionFvPatchScalarField.C b/src/regionModels/surfaceFilmModels/derivedFvPatchFields/wallFunctions/alphatFilmWallFunction/alphatFilmWallFunctionFvPatchScalarField.C
index 8b8ef3be1fbbb1001e5188696705ad0ce5de078f..fd3be5ac38564d18c5fb6e02478b04c3d0d65822 100644
--- a/src/regionModels/surfaceFilmModels/derivedFvPatchFields/wallFunctions/alphatFilmWallFunction/alphatFilmWallFunctionFvPatchScalarField.C
+++ b/src/regionModels/surfaceFilmModels/derivedFvPatchFields/wallFunctions/alphatFilmWallFunction/alphatFilmWallFunctionFvPatchScalarField.C
@@ -158,11 +158,9 @@ void alphatFilmWallFunctionFvPatchScalarField::updateCoeffs()
 
     const label filmPatchI = filmModel.regionPatchID(patchI);
 
-    const mappedPatchBase& filmMap = filmModel.mappedPatches()[filmPatchI];
-
     tmp<volScalarField> mDotFilm(filmModel.primaryMassTrans());
     scalarField mDotFilmp = mDotFilm().boundaryField()[filmPatchI];
-    filmMap.distribute(mDotFilmp);
+    filmModel.toPrimary(filmPatchI, mDotFilmp);
 
     // Retrieve RAS turbulence model
     const RASModel& rasModel = db().lookupObject<RASModel>("RASProperties");
diff --git a/src/regionModels/surfaceFilmModels/derivedFvPatchFields/wallFunctions/mutkFilmWallFunction/mutkFilmWallFunctionFvPatchScalarField.C b/src/regionModels/surfaceFilmModels/derivedFvPatchFields/wallFunctions/mutkFilmWallFunction/mutkFilmWallFunctionFvPatchScalarField.C
index 8cd0aaf5aa455cf2374442535a03457fc8ef16b9..7374f80e034b2191b6dceeb2500308642c87d1a8 100644
--- a/src/regionModels/surfaceFilmModels/derivedFvPatchFields/wallFunctions/mutkFilmWallFunction/mutkFilmWallFunctionFvPatchScalarField.C
+++ b/src/regionModels/surfaceFilmModels/derivedFvPatchFields/wallFunctions/mutkFilmWallFunction/mutkFilmWallFunctionFvPatchScalarField.C
@@ -70,11 +70,9 @@ tmp<scalarField> mutkFilmWallFunctionFvPatchScalarField::calcUTau
 
     const label filmPatchI = filmModel.regionPatchID(patchI);
 
-    const mappedPatchBase& filmMap = filmModel.mappedPatches()[filmPatchI];
-
     tmp<volScalarField> mDotFilm(filmModel.primaryMassTrans());
     scalarField mDotFilmp = mDotFilm().boundaryField()[filmPatchI];
-    filmMap.distribute(mDotFilmp);
+    filmModel.toPrimary(filmPatchI, mDotFilmp);
 
 
     // Retrieve RAS turbulence model
diff --git a/src/regionModels/surfaceFilmModels/kinematicSingleLayer/kinematicSingleLayer.C b/src/regionModels/surfaceFilmModels/kinematicSingleLayer/kinematicSingleLayer.C
index 461fbd10ae9da1509c56a4474a207959bfcc1cd2..a448083f997ce136619e8e4bfab473af3ef6629d 100644
--- a/src/regionModels/surfaceFilmModels/kinematicSingleLayer/kinematicSingleLayer.C
+++ b/src/regionModels/surfaceFilmModels/kinematicSingleLayer/kinematicSingleLayer.C
@@ -827,7 +827,7 @@ void kinematicSingleLayer::preEvolveRegion()
 //    availableMass_ = mass();
     availableMass_ = netMass();
     cloudMassTrans_ == dimensionedScalar("zero", dimMass, 0.0);
-    cloudDiameterTrans_ == dimensionedScalar("zero", dimLength, -1.0);
+    cloudDiameterTrans_ == dimensionedScalar("zero", dimLength, 0.0);
 }
 
 
diff --git a/src/regionModels/surfaceFilmModels/kinematicSingleLayer/kinematicSingleLayerTemplates.C b/src/regionModels/surfaceFilmModels/kinematicSingleLayer/kinematicSingleLayerTemplates.C
index d2bf7306d16021141b67b8ae9f6777437b0cca80..4076a8494a3a6b64ec4b752492c6e9da60205b72 100644
--- a/src/regionModels/surfaceFilmModels/kinematicSingleLayer/kinematicSingleLayerTemplates.C
+++ b/src/regionModels/surfaceFilmModels/kinematicSingleLayer/kinematicSingleLayerTemplates.C
@@ -1,77 +1,77 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
-     \\/     M anipulation  |
--------------------------------------------------------------------------------
-License
-    This file is part of OpenFOAM.
-
-    OpenFOAM is free software: you can redistribute it and/or modify it
-    under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
-    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-    for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
-
-\*---------------------------------------------------------------------------*/
-
-#include "kinematicSingleLayer.H"
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-namespace Foam
-{
-namespace regionModels
-{
-namespace surfaceFilmModels
-{
-
-// * * * * * * * * * * * * Protected Member Functions  * * * * * * * * * * * //
-
-template<class Type>
-void kinematicSingleLayer::constrainFilmField
-(
-    Type& field,
-    const typename Type::cmptType& value
-)
-{
-    forAll(intCoupledPatchIDs_, i)
-    {
-        label patchI = intCoupledPatchIDs_[i];
-        field.boundaryField()[patchI] = value;
-        if (debug)
-        {
-            Info<< "Constraining " << field.name()
-                << " boundary " << field.boundaryField()[patchI].patch().name()
-                << " to " << value << endl;
-        }
-    }
-    forAll(passivePatchIDs_, i)
-    {
-        label patchI = passivePatchIDs_[i];
-        field.boundaryField()[patchI] = value;
-        if (debug)
-        {
-            Info<< "Constraining " << field.name()
-                << " boundary " << field.boundaryField()[patchI].patch().name()
-                << " to " << value << endl;
-        }
-    }
-}
-
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-} // end namespace Foam
-} // end namespace regionModels
-} // end namespace surfaceFilmModels
-
-// ************************************************************************* //
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+\*---------------------------------------------------------------------------*/
+
+#include "kinematicSingleLayer.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+namespace regionModels
+{
+namespace surfaceFilmModels
+{
+
+// * * * * * * * * * * * * Protected Member Functions  * * * * * * * * * * * //
+
+template<class Type>
+void kinematicSingleLayer::constrainFilmField
+(
+    Type& field,
+    const typename Type::cmptType& value
+)
+{
+    forAll(intCoupledPatchIDs_, i)
+    {
+        label patchI = intCoupledPatchIDs_[i];
+        field.boundaryField()[patchI] = value;
+        if (debug)
+        {
+            Info<< "Constraining " << field.name()
+                << " boundary " << field.boundaryField()[patchI].patch().name()
+                << " to " << value << endl;
+        }
+    }
+    forAll(passivePatchIDs_, i)
+    {
+        label patchI = passivePatchIDs_[i];
+        field.boundaryField()[patchI] = value;
+        if (debug)
+        {
+            Info<< "Constraining " << field.name()
+                << " boundary " << field.boundaryField()[patchI].patch().name()
+                << " to " << value << endl;
+        }
+    }
+}
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // end namespace Foam
+} // end namespace regionModels
+} // end namespace surfaceFilmModels
+
+// ************************************************************************* //
diff --git a/src/regionModels/surfaceFilmModels/submodels/kinematic/injectionModel/drippingInjection/drippingInjection.C b/src/regionModels/surfaceFilmModels/submodels/kinematic/injectionModel/drippingInjection/drippingInjection.C
index 076e6abb231a74b092748953034069ac39ac7c8c..e271674b10d551e594e5752a71427aca98eae0ba 100644
--- a/src/regionModels/surfaceFilmModels/submodels/kinematic/injectionModel/drippingInjection/drippingInjection.C
+++ b/src/regionModels/surfaceFilmModels/submodels/kinematic/injectionModel/drippingInjection/drippingInjection.C
@@ -139,7 +139,7 @@ void drippingInjection::correct
         {
             // Mass below minimum threshold - cannot be injected
             massToInject[cellI] = 0.0;
-            diameterToInject[cellI] = -1.0;
+            diameterToInject[cellI] = 0.0;
         }
     }
 }
diff --git a/src/regionModels/surfaceFilmModels/thermoSingleLayer/thermoSingleLayer.C b/src/regionModels/surfaceFilmModels/thermoSingleLayer/thermoSingleLayer.C
index c6c373500f5848da211c4df8f04527ca2d4cdbb5..c405d98fa9fc20206f80cf1ad33f7cca8289f4f8 100644
--- a/src/regionModels/surfaceFilmModels/thermoSingleLayer/thermoSingleLayer.C
+++ b/src/regionModels/surfaceFilmModels/thermoSingleLayer/thermoSingleLayer.C
@@ -705,12 +705,11 @@ tmp<DimensionedField<scalar, volMesh> > thermoSingleLayer::Srho() const
     forAll(intCoupledPatchIDs(), i)
     {
         const label filmPatchI = intCoupledPatchIDs()[i];
-        const mappedPatchBase& filmMap = mappedPatches_[filmPatchI];
 
         scalarField patchMass =
             primaryMassPCTrans_.boundaryField()[filmPatchI];
 
-        filmMap.distribute(patchMass);
+        toPrimary(filmPatchI, patchMass);
 
         const label primaryPatchI = primaryPatchIDs()[i];
         const unallocLabelList& cells =
@@ -761,12 +760,11 @@ tmp<DimensionedField<scalar, volMesh> > thermoSingleLayer::Srho
         forAll(intCoupledPatchIDs_, i)
         {
             const label filmPatchI = intCoupledPatchIDs_[i];
-            const mappedPatchBase& filmMap = mappedPatches_[filmPatchI];
 
             scalarField patchMass =
                 primaryMassPCTrans_.boundaryField()[filmPatchI];
 
-            filmMap.distribute(patchMass);
+            toPrimary(filmPatchI, patchMass);
 
             const label primaryPatchI = primaryPatchIDs()[i];
             const unallocLabelList& cells =
@@ -812,12 +810,11 @@ tmp<DimensionedField<scalar, volMesh> > thermoSingleLayer::Sh() const
     forAll(intCoupledPatchIDs_, i)
     {
         const label filmPatchI = intCoupledPatchIDs_[i];
-        const mappedPatchBase& filmMap = mappedPatches_[filmPatchI];
 
         scalarField patchEnergy =
             primaryEnergyPCTrans_.boundaryField()[filmPatchI];
 
-        filmMap.distribute(patchEnergy);
+        toPrimary(filmPatchI, patchEnergy);
 
         const label primaryPatchI = primaryPatchIDs()[i];
         const unallocLabelList& cells =
diff --git a/src/sampling/sampledSurface/isoSurface/isoSurfaceCell.C b/src/sampling/sampledSurface/isoSurface/isoSurfaceCell.C
index baa36b8e24e815c336a99b9f9142ae85d05ff3c0..53f99b67c03569c11ebe2e46d00b401b6581c2b1 100644
--- a/src/sampling/sampledSurface/isoSurface/isoSurfaceCell.C
+++ b/src/sampling/sampledSurface/isoSurface/isoSurfaceCell.C
@@ -287,16 +287,16 @@ Foam::pointIndexHit Foam::isoSurfaceCell::collapseSurface
 
         if (shared[0] != -1)
         {
-            //vector n0 = tri0.normal(localPoints);
-            //n0 /= mag(n0);
-            //vector n1 = tri1.normal(localPoints);
-            //n1 /= mag(n1);
-            //
-            //if ((n0 & n1) < 0)
-            //{
-            //    // Too big an angle. Do not simplify.
-            //}
-            //else
+            vector n0 = tri0.normal(localPoints);
+            n0 /= mag(n0);
+            vector n1 = tri1.normal(localPoints);
+            n1 /= mag(n1);
+
+            if ((n0 & n1) < 0)
+            {
+                // Too big an angle. Do not simplify.
+            }
+            else
             {
                 info.setPoint
                 (
@@ -332,18 +332,18 @@ Foam::pointIndexHit Foam::isoSurfaceCell::collapseSurface
         if (nZones == 1)
         {
             // Check that all normals make a decent angle
-            //scalar minCos = GREAT;
-            //const vector& n0 = surf.faceNormals()[0];
-            //for (label i = 1; i < surf.size(); i++)
-            //{
-            //    scalar cosAngle = (n0 & surf.faceNormals()[i]);
-            //    if (cosAngle < minCos)
-            //    {
-            //        minCos = cosAngle;
-            //    }
-            //}
-            //
-            //if (minCos > 0)
+            scalar minCos = GREAT;
+            const vector& n0 = surf.faceNormals()[0];
+            for (label i = 1; i < surf.size(); i++)
+            {
+                scalar cosAngle = (n0 & surf.faceNormals()[i]);
+                if (cosAngle < minCos)
+                {
+                    minCos = cosAngle;
+                }
+            }
+
+            if (minCos > 0)
             {
                 info.setPoint(calcCentre(surf));
                 info.setHit();
@@ -443,7 +443,7 @@ void Foam::isoSurfaceCell::calcSnappedCc
                     label faceI = cFaces[cFaceI];
                     const face& f = mesh_.faces()[faceI];
 
-                    // Do a tetrahedrisation. Each face to cc becomes pyr.
+                    // Do a tetrahedralisation. Each face to cc becomes pyr.
                     // Each pyr gets split into tets by diagonalisation
                     // of face.
 
@@ -467,14 +467,18 @@ void Foam::isoSurfaceCell::calcSnappedCc
                          && (s[2] >= 0.0 && s[2] <= 0.5)
                         )
                         {
-                            if (mesh_.faceOwner()[faceI] == cellI)
+                            if
+                            (
+                                (mesh_.faceOwner()[faceI] == cellI)
+                             == (cVal >= pVals[tri[0]])
+                            )
                             {
                                 localTris.append
                                 (
                                     labelledTri
                                     (
-                                        pointToLocal[tri[0]],
                                         pointToLocal[tri[1]],
+                                        pointToLocal[tri[0]],
                                         pointToLocal[tri[2]],
                                         0
                                     )
@@ -486,8 +490,8 @@ void Foam::isoSurfaceCell::calcSnappedCc
                                 (
                                     labelledTri
                                     (
-                                        pointToLocal[tri[1]],
                                         pointToLocal[tri[0]],
+                                        pointToLocal[tri[1]],
                                         pointToLocal[tri[2]],
                                         0
                                     )
@@ -575,7 +579,11 @@ void Foam::isoSurfaceCell::genPointTris
             point p1 = (1.0-s[1])*pts[pointI] + s[1]*pts[c];
             point p2 = (1.0-s[2])*pts[pointI] + s[2]*cc[cellI];
 
-            if (mesh_.faceOwner()[faceI] == cellI)
+            if
+            (
+                (mesh_.faceOwner()[faceI] == cellI)
+             == (pointValues[pointI] > cellValues[cellI])
+            )
             {
                 localTriPoints.append(p0);
                 localTriPoints.append(p1);
@@ -754,7 +762,7 @@ void Foam::isoSurfaceCell::calcSnappedPoint
         }
 
 
-        // Loop over all pointCells (by using pointFaces)
+        // Do a pointCells walk (by using pointFaces)
 
         localPointCells.clear();
         localTriPoints.clear();
@@ -766,6 +774,8 @@ void Foam::isoSurfaceCell::calcSnappedPoint
 
             if (isTet.get(own) == 1)
             {
+                // Since tets have no cell centre to include make sure
+                // we only generate a triangle once per point.
                 if (localPointCells.insert(own))
                 {
                     genPointTris(pVals, pointI, faceI, own, localTriPoints);
@@ -848,20 +858,19 @@ void Foam::isoSurfaceCell::calcSnappedPoint
 
             if (nZones == 1)
             {
-                //// Check that all normals make a decent angle
-                //scalar minCos = GREAT;
-                //const vector& n0 = surf.faceNormals()[0];
-                //for (label i = 1; i < surf.size(); i++)
-                //{
-                //    const vector& n = surf.faceNormals()[i];
-                //    scalar cosAngle = (n0 & n);
-                //    if (cosAngle < minCos)
-                //    {
-                //        minCos = cosAngle;
-                //    }
-                //}
-                //
-                //if (minCos > 0)
+                // Check that all normals make a decent angle
+                scalar minCos = GREAT;
+                const vector& n0 = surf.faceNormals()[0];
+                for (label i = 1; i < surf.size(); i++)
+                {
+                    const vector& n = surf.faceNormals()[i];
+                    scalar cosAngle = (n0 & n);
+                    if (cosAngle < minCos)
+                    {
+                        minCos = cosAngle;
+                    }
+                }
+                if (minCos > 0)
                 {
                     collapsedPoint[pointI] = calcCentre(surf);
                 }
@@ -882,7 +891,9 @@ void Foam::isoSurfaceCell::calcSnappedPoint
 
     forAll(collapsedPoint, pointI)
     {
-        if (collapsedPoint[pointI] != greatPoint)
+        // Cannot do == comparison since might be transformed so have
+        // truncation errors.
+        if (magSqr(collapsedPoint[pointI]) < 0.5*magSqr(greatPoint))
         {
             snappedPoint[pointI] = snappedPoints.size();
             snappedPoints.append(collapsedPoint[pointI]);
@@ -1208,142 +1219,142 @@ void Foam::isoSurfaceCell::calcAddressing
 }
 
 
-void Foam::isoSurfaceCell::walkOrientation
-(
-    const triSurface& surf,
-    const List<FixedList<label, 3> >& faceEdges,
-    const labelList& edgeFace0,
-    const labelList& edgeFace1,
-    const label seedTriI,
-    labelList& flipState
-)
-{
-    // Do walk for consistent orientation.
-    DynamicList<label> changedFaces(surf.size());
-
-    changedFaces.append(seedTriI);
-
-    while (changedFaces.size())
-    {
-        DynamicList<label> newChangedFaces(changedFaces.size());
-
-        forAll(changedFaces, i)
-        {
-            label triI = changedFaces[i];
-            const labelledTri& tri = surf[triI];
-            const FixedList<label, 3>& fEdges = faceEdges[triI];
-
-            forAll(fEdges, fp)
-            {
-                label edgeI = fEdges[fp];
-
-                // my points:
-                label p0 = tri[fp];
-                label p1 = tri[tri.fcIndex(fp)];
-
-                label nbrI =
-                (
-                    edgeFace0[edgeI] != triI
-                  ? edgeFace0[edgeI]
-                  : edgeFace1[edgeI]
-                );
-
-                if (nbrI != -1 && flipState[nbrI] == -1)
-                {
-                    const labelledTri& nbrTri = surf[nbrI];
-
-                    // nbr points
-                    label nbrFp = findIndex(nbrTri, p0);
-                    label nbrP1 = nbrTri[nbrTri.rcIndex(nbrFp)];
-
-                    bool sameOrientation = (p1 == nbrP1);
-
-                    if (flipState[triI] == 0)
-                    {
-                        flipState[nbrI] = (sameOrientation ? 0 : 1);
-                    }
-                    else
-                    {
-                        flipState[nbrI] = (sameOrientation ? 1 : 0);
-                    }
-                    newChangedFaces.append(nbrI);
-                }
-            }
-        }
-
-        changedFaces.transfer(newChangedFaces);
-    }
-}
-
-
-void Foam::isoSurfaceCell::orientSurface
-(
-    triSurface& surf,
-    const List<FixedList<label, 3> >& faceEdges,
-    const labelList& edgeFace0,
-    const labelList& edgeFace1,
-    const Map<labelList>& edgeFacesRest
-)
-{
-    // -1 : unvisited
-    //  0 : leave as is
-    //  1 : flip
-    labelList flipState(surf.size(), -1);
-
-    label seedTriI = 0;
-
-    while (true)
-    {
-        // Find first unvisited triangle
-        for
-        (
-            ;
-            seedTriI < surf.size() && flipState[seedTriI] != -1;
-            seedTriI++
-        )
-        {}
-
-        if (seedTriI == surf.size())
-        {
-            break;
-        }
-
-        // Note: Determine orientation of seedTriI?
-        // for now assume it is ok
-        flipState[seedTriI] = 0;
-
-        walkOrientation
-        (
-            surf,
-            faceEdges,
-            edgeFace0,
-            edgeFace1,
-            seedTriI,
-            flipState
-        );
-    }
-
-    // Do actual flipping
-    surf.clearOut();
-    forAll(surf, triI)
-    {
-        if (flipState[triI] == 1)
-        {
-            labelledTri tri(surf[triI]);
-
-            surf[triI][0] = tri[0];
-            surf[triI][1] = tri[2];
-            surf[triI][2] = tri[1];
-        }
-        else if (flipState[triI] == -1)
-        {
-            FatalErrorIn
-            (
-                "isoSurfaceCell::orientSurface(triSurface&, const label)"
-            )   << "problem" << abort(FatalError);
-        }
-    }
-}
+//void Foam::isoSurfaceCell::walkOrientation
+//(
+//    const triSurface& surf,
+//    const List<FixedList<label, 3> >& faceEdges,
+//    const labelList& edgeFace0,
+//    const labelList& edgeFace1,
+//    const label seedTriI,
+//    labelList& flipState
+//)
+//{
+//    // Do walk for consistent orientation.
+//    DynamicList<label> changedFaces(surf.size());
+//
+//    changedFaces.append(seedTriI);
+//
+//    while (changedFaces.size())
+//    {
+//        DynamicList<label> newChangedFaces(changedFaces.size());
+//
+//        forAll(changedFaces, i)
+//        {
+//            label triI = changedFaces[i];
+//            const labelledTri& tri = surf[triI];
+//            const FixedList<label, 3>& fEdges = faceEdges[triI];
+//
+//            forAll(fEdges, fp)
+//            {
+//                label edgeI = fEdges[fp];
+//
+//                // my points:
+//                label p0 = tri[fp];
+//                label p1 = tri[tri.fcIndex(fp)];
+//
+//                label nbrI =
+//                (
+//                    edgeFace0[edgeI] != triI
+//                  ? edgeFace0[edgeI]
+//                  : edgeFace1[edgeI]
+//                );
+//
+//                if (nbrI != -1 && flipState[nbrI] == -1)
+//                {
+//                    const labelledTri& nbrTri = surf[nbrI];
+//
+//                    // nbr points
+//                    label nbrFp = findIndex(nbrTri, p0);
+//                    label nbrP1 = nbrTri[nbrTri.rcIndex(nbrFp)];
+//
+//                    bool sameOrientation = (p1 == nbrP1);
+//
+//                    if (flipState[triI] == 0)
+//                    {
+//                        flipState[nbrI] = (sameOrientation ? 0 : 1);
+//                    }
+//                    else
+//                    {
+//                        flipState[nbrI] = (sameOrientation ? 1 : 0);
+//                    }
+//                    newChangedFaces.append(nbrI);
+//                }
+//            }
+//        }
+//
+//        changedFaces.transfer(newChangedFaces);
+//    }
+//}
+//
+//
+//void Foam::isoSurfaceCell::orientSurface
+//(
+//    triSurface& surf,
+//    const List<FixedList<label, 3> >& faceEdges,
+//    const labelList& edgeFace0,
+//    const labelList& edgeFace1,
+//    const Map<labelList>& edgeFacesRest
+//)
+//{
+//    // -1 : unvisited
+//    //  0 : leave as is
+//    //  1 : flip
+//    labelList flipState(surf.size(), -1);
+//
+//    label seedTriI = 0;
+//
+//    while (true)
+//    {
+//        // Find first unvisited triangle
+//        for
+//        (
+//            ;
+//            seedTriI < surf.size() && flipState[seedTriI] != -1;
+//            seedTriI++
+//        )
+//        {}
+//
+//        if (seedTriI == surf.size())
+//        {
+//            break;
+//        }
+//
+//        // Note: Determine orientation of seedTriI?
+//        // for now assume it is ok
+//        flipState[seedTriI] = 0;
+//
+//        walkOrientation
+//        (
+//            surf,
+//            faceEdges,
+//            edgeFace0,
+//            edgeFace1,
+//            seedTriI,
+//            flipState
+//        );
+//    }
+//
+//    // Do actual flipping
+//    surf.clearOut();
+//    forAll(surf, triI)
+//    {
+//        if (flipState[triI] == 1)
+//        {
+//            labelledTri tri(surf[triI]);
+//
+//            surf[triI][0] = tri[0];
+//            surf[triI][1] = tri[2];
+//            surf[triI][2] = tri[1];
+//        }
+//        else if (flipState[triI] == -1)
+//        {
+//            FatalErrorIn
+//            (
+//                "isoSurfaceCell::orientSurface(triSurface&, const label)"
+//            )   << "problem" << abort(FatalError);
+//        }
+//    }
+//}
 
 
 // Checks if triangle is connected through edgeI only.
@@ -1625,7 +1636,7 @@ Foam::isoSurfaceCell::isoSurfaceCell
     (
         stitchTriPoints
         (
-            true,               // check for duplicate tris
+            regularise,         // check for duplicate tris
             triPoints,
             triPointMergeMap_,  // unmerged to merged point
             triMap
@@ -1657,7 +1668,7 @@ Foam::isoSurfaceCell::isoSurfaceCell
     }
 
 
-    if (false)
+    if (regularise)
     {
         List<FixedList<label, 3> > faceEdges;
         labelList edgeFace0, edgeFace1;
@@ -1717,7 +1728,7 @@ Foam::isoSurfaceCell::isoSurfaceCell
             inplaceRenumber(reversePointMap, triPointMergeMap_);
         }
 
-        orientSurface(*this, faceEdges, edgeFace0, edgeFace1, edgeFacesRest);
+        //orientSurface(*this, faceEdges, edgeFace0, edgeFace1, edgeFacesRest);
     }
 }
 
diff --git a/src/sampling/sampledSurface/isoSurface/isoSurfaceCell.H b/src/sampling/sampledSurface/isoSurface/isoSurfaceCell.H
index fa157a517cadb841c0891ec3473ff79c8dbcdbe4..9c3c2990c844dc28d3e5b7d24106924d8376da9d 100644
--- a/src/sampling/sampledSurface/isoSurface/isoSurfaceCell.H
+++ b/src/sampling/sampledSurface/isoSurface/isoSurfaceCell.H
@@ -214,15 +214,19 @@ class isoSurfaceCell
         void generateTriPoints
         (
             const DynamicList<Type>& snapped,
+            const scalar isoVal0,
             const scalar s0,
             const Type& p0,
             const label p0Index,
+            const scalar isoVal1,
             const scalar s1,
             const Type& p1,
             const label p1Index,
+            const scalar isoVal2,
             const scalar s2,
             const Type& p2,
             const label p2Index,
+            const scalar isoVal3,
             const scalar s3,
             const Type& p3,
             const label p3Index,
@@ -267,26 +271,26 @@ class isoSurfaceCell
             Map<labelList>& edgeFacesRest
         ) const;
 
-        //- Determine orientation
-        static void walkOrientation
-        (
-            const triSurface& surf,
-            const List<FixedList<label, 3> >& faceEdges,
-            const labelList& edgeFace0,
-            const labelList& edgeFace1,
-            const label seedTriI,
-            labelList& flipState
-        );
-
-        //- Orient surface
-        static void orientSurface
-        (
-            triSurface&,
-            const List<FixedList<label, 3> >& faceEdges,
-            const labelList& edgeFace0,
-            const labelList& edgeFace1,
-            const Map<labelList>& edgeFacesRest
-        );
+        ////- Determine orientation
+        //static void walkOrientation
+        //(
+        //    const triSurface& surf,
+        //    const List<FixedList<label, 3> >& faceEdges,
+        //    const labelList& edgeFace0,
+        //    const labelList& edgeFace1,
+        //    const label seedTriI,
+        //    labelList& flipState
+        //);
+
+        ////- Orient surface
+        //static void orientSurface
+        //(
+        //    triSurface&,
+        //    const List<FixedList<label, 3> >& faceEdges,
+        //    const labelList& edgeFace0,
+        //    const labelList& edgeFace1,
+        //    const Map<labelList>& edgeFacesRest
+        //);
 
         //- Is triangle (given by 3 edges) not fully connected?
         static bool danglingTriangle
diff --git a/src/sampling/sampledSurface/isoSurface/isoSurfaceCellTemplates.C b/src/sampling/sampledSurface/isoSurface/isoSurfaceCellTemplates.C
index 9c476d62cd5b5d4069e46c3b0981a0bc4558f9c6..8b933f5aab0bac2c78f836a6f7224cfc00c3e680 100644
--- a/src/sampling/sampledSurface/isoSurface/isoSurfaceCellTemplates.C
+++ b/src/sampling/sampledSurface/isoSurface/isoSurfaceCellTemplates.C
@@ -76,23 +76,27 @@ void Foam::isoSurfaceCell::generateTriPoints
 (
     const DynamicList<Type>& snapped,
 
+    const scalar isoVal0,
     const scalar s0,
     const Type& p0,
     const label p0Index,
 
+    const scalar isoVal1,
     const scalar s1,
     const Type& p1,
     const label p1Index,
 
+    const scalar isoVal2,
     const scalar s2,
     const Type& p2,
     const label p2Index,
 
+    const scalar isoVal3,
     const scalar s3,
     const Type& p3,
     const label p3Index,
 
-    DynamicList<Type>& points
+    DynamicList<Type>& pts
 ) const
 {
     int triIndex = 0;
@@ -122,77 +126,160 @@ void Foam::isoSurfaceCell::generateTriPoints
 
         case 0x0E:
         case 0x01:
-            points.append(generatePoint(snapped,s0,p0,p0Index,s1,p1,p1Index));
-            points.append(generatePoint(snapped,s0,p0,p0Index,s2,p2,p2Index));
-            points.append(generatePoint(snapped,s0,p0,p0Index,s3,p3,p3Index));
+        {
+            // 0 is common point. Orient such that normal points in positive
+            // gradient direction
+            if (isoVal0 >= isoVal1)
+            {
+                pts.append(generatePoint(snapped,s0,p0,p0Index,s1,p1,p1Index));
+                pts.append(generatePoint(snapped,s0,p0,p0Index,s2,p2,p2Index));
+                pts.append(generatePoint(snapped,s0,p0,p0Index,s3,p3,p3Index));
+            }
+            else
+            {
+                pts.append(generatePoint(snapped,s0,p0,p0Index,s2,p2,p2Index));
+                pts.append(generatePoint(snapped,s0,p0,p0Index,s1,p1,p1Index));
+                pts.append(generatePoint(snapped,s0,p0,p0Index,s3,p3,p3Index));
+            }
+        }
         break;
 
         case 0x0D:
         case 0x02:
-            points.append(generatePoint(snapped,s1,p1,p1Index,s0,p0,p0Index));
-            points.append(generatePoint(snapped,s1,p1,p1Index,s3,p3,p3Index));
-            points.append(generatePoint(snapped,s1,p1,p1Index,s2,p2,p2Index));
+        {
+            // 1 is common point
+            if (isoVal1 >= isoVal0)
+            {
+                pts.append(generatePoint(snapped,s1,p1,p1Index,s0,p0,p0Index));
+                pts.append(generatePoint(snapped,s1,p1,p1Index,s3,p3,p3Index));
+                pts.append(generatePoint(snapped,s1,p1,p1Index,s2,p2,p2Index));
+            }
+            else
+            {
+                pts.append(generatePoint(snapped,s1,p1,p1Index,s3,p3,p3Index));
+                pts.append(generatePoint(snapped,s1,p1,p1Index,s0,p0,p0Index));
+                pts.append(generatePoint(snapped,s1,p1,p1Index,s2,p2,p2Index));
+            }
+        }
         break;
 
         case 0x0C:
         case 0x03:
         {
-            Type tp1 = generatePoint(snapped,s0,p0,p0Index,s2,p2,p2Index);
-            Type tp2 = generatePoint(snapped,s1,p1,p1Index,s3,p3,p3Index);
-
-            points.append(generatePoint(snapped,s0,p0,p0Index,s3,p3,p3Index));
-            points.append(tp1);
-            points.append(tp2);
-            points.append(tp2);
-            points.append(generatePoint(snapped,s1,p1,p1Index,s2,p2,p2Index));
-            points.append(tp1);
+            Type s02 = generatePoint(snapped,s0,p0,p0Index,s2,p2,p2Index);
+            Type s13 = generatePoint(snapped,s1,p1,p1Index,s3,p3,p3Index);
+
+            if (isoVal0 >= isoVal3)
+            {
+                pts.append(generatePoint(snapped,s0,p0,p0Index,s3,p3,p3Index));
+                pts.append(s02);
+                pts.append(s13);
+                pts.append(s13);
+                pts.append(generatePoint(snapped,s1,p1,p1Index,s2,p2,p2Index));
+                pts.append(s02);
+            }
+            else
+            {
+                pts.append(s02);
+                pts.append(generatePoint(snapped,s0,p0,p0Index,s3,p3,p3Index));
+                pts.append(s13);
+                pts.append(generatePoint(snapped,s1,p1,p1Index,s2,p2,p2Index));
+                pts.append(s13);
+                pts.append(s02);
+            }
         }
         break;
 
         case 0x0B:
         case 0x04:
         {
-            points.append(generatePoint(snapped,s2,p2,p2Index,s0,p0,p0Index));
-            points.append(generatePoint(snapped,s2,p2,p2Index,s1,p1,p1Index));
-            points.append(generatePoint(snapped,s2,p2,p2Index,s3,p3,p3Index));
+            // 2 is common point
+            if (isoVal2 >= isoVal0)
+            {
+                pts.append(generatePoint(snapped,s2,p2,p2Index,s0,p0,p0Index));
+                pts.append(generatePoint(snapped,s2,p2,p2Index,s1,p1,p1Index));
+                pts.append(generatePoint(snapped,s2,p2,p2Index,s3,p3,p3Index));
+            }
+            else
+            {
+                pts.append(generatePoint(snapped,s2,p2,p2Index,s1,p1,p1Index));
+                pts.append(generatePoint(snapped,s2,p2,p2Index,s0,p0,p0Index));
+                pts.append(generatePoint(snapped,s2,p2,p2Index,s3,p3,p3Index));
+            }
         }
         break;
 
         case 0x0A:
         case 0x05:
         {
-            Type tp0 = generatePoint(snapped,s0,p0,p0Index,s1,p1,p1Index);
-            Type tp1 = generatePoint(snapped,s2,p2,p2Index,s3,p3,p3Index);
-
-            points.append(tp0);
-            points.append(tp1);
-            points.append(generatePoint(snapped,s0,p0,p0Index,s3,p3,p3Index));
-            points.append(tp0);
-            points.append(generatePoint(snapped,s1,p1,p1Index,s2,p2,p2Index));
-            points.append(tp1);
+            Type s01 = generatePoint(snapped,s0,p0,p0Index,s1,p1,p1Index);
+            Type s23 = generatePoint(snapped,s2,p2,p2Index,s3,p3,p3Index);
+
+            if (isoVal3 >= isoVal0)
+            {
+                pts.append(s01);
+                pts.append(s23);
+                pts.append(generatePoint(snapped,s0,p0,p0Index,s3,p3,p3Index));
+                pts.append(s01);
+                pts.append(generatePoint(snapped,s1,p1,p1Index,s2,p2,p2Index));
+                pts.append(s23);
+            }
+            else
+            {
+                pts.append(s23);
+                pts.append(s01);
+                pts.append(generatePoint(snapped,s0,p0,p0Index,s3,p3,p3Index));
+                pts.append(generatePoint(snapped,s1,p1,p1Index,s2,p2,p2Index));
+                pts.append(s01);
+                pts.append(s23);
+            }
         }
         break;
 
         case 0x09:
         case 0x06:
         {
-            Type tp0 = generatePoint(snapped,s0,p0,p0Index,s1,p1,p1Index);
-            Type tp1 = generatePoint(snapped,s2,p2,p2Index,s3,p3,p3Index);
-
-            points.append(tp0);
-            points.append(generatePoint(snapped,s1,p1,p1Index,s3,p3,p3Index));
-            points.append(tp1);
-            points.append(tp0);
-            points.append(generatePoint(snapped,s0,p0,p0Index,s2,p2,p2Index));
-            points.append(tp1);
+            Type s01 = generatePoint(snapped,s0,p0,p0Index,s1,p1,p1Index);
+            Type s23 = generatePoint(snapped,s2,p2,p2Index,s3,p3,p3Index);
+
+            if (isoVal3 >= isoVal1)
+            {
+                pts.append(s01);
+                pts.append(generatePoint(snapped,s1,p1,p1Index,s3,p3,p3Index));
+                pts.append(s23);
+                pts.append(s01);
+                pts.append(generatePoint(snapped,s0,p0,p0Index,s2,p2,p2Index));
+                pts.append(s23);
+            }
+            else
+            {
+                pts.append(generatePoint(snapped,s1,p1,p1Index,s3,p3,p3Index));
+                pts.append(s01);
+                pts.append(s23);
+                pts.append(generatePoint(snapped,s0,p0,p0Index,s2,p2,p2Index));
+                pts.append(s01);
+                pts.append(s23);
+            }
         }
         break;
 
         case 0x07:
         case 0x08:
-            points.append(generatePoint(snapped,s3,p3,p3Index,s0,p0,p0Index));
-            points.append(generatePoint(snapped,s3,p3,p3Index,s2,p2,p2Index));
-            points.append(generatePoint(snapped,s3,p3,p3Index,s1,p1,p1Index));
+        {
+            // 3 is common point
+            if (isoVal3 >= isoVal0)
+            {
+                pts.append(generatePoint(snapped,s3,p3,p3Index,s0,p0,p0Index));
+                pts.append(generatePoint(snapped,s3,p3,p3Index,s2,p2,p2Index));
+                pts.append(generatePoint(snapped,s3,p3,p3Index,s1,p1,p1Index));
+            }
+            else
+            {
+                pts.append(generatePoint(snapped,s3,p3,p3Index,s2,p2,p2Index));
+                pts.append(generatePoint(snapped,s3,p3,p3Index,s0,p0,p0Index));
+                pts.append(generatePoint(snapped,s3,p3,p3Index,s1,p1,p1Index));
+            }
+        }
         break;
     }
 }
@@ -252,18 +339,23 @@ void Foam::isoSurfaceCell::generateTriPoints
                     generateTriPoints
                     (
                         snappedPoints,
+
+                        pVals_[f0[1]],
                         pVals[f0[1]],
                         pCoords[f0[1]],
                         snappedPoint[f0[1]],
 
+                        pVals_[f0[0]],
                         pVals[f0[0]],
                         pCoords[f0[0]],
                         snappedPoint[f0[0]],
 
+                        pVals_[f0[2]],
                         pVals[f0[2]],
                         pCoords[f0[2]],
                         snappedPoint[f0[2]],
 
+                        pVals_[oppositeI],
                         pVals[oppositeI],
                         pCoords[oppositeI],
                         snappedPoint[oppositeI],
@@ -276,18 +368,23 @@ void Foam::isoSurfaceCell::generateTriPoints
                     generateTriPoints
                     (
                         snappedPoints,
+
+                        pVals_[f0[0]],
                         pVals[f0[0]],
                         pCoords[f0[0]],
                         snappedPoint[f0[0]],
 
+                        pVals_[f0[1]],
                         pVals[f0[1]],
                         pCoords[f0[1]],
                         snappedPoint[f0[1]],
 
+                        pVals_[f0[2]],
                         pVals[f0[2]],
                         pCoords[f0[2]],
                         snappedPoint[f0[2]],
 
+                        pVals_[oppositeI],
                         pVals[oppositeI],
                         pCoords[oppositeI],
                         snappedPoint[oppositeI],
@@ -321,18 +418,22 @@ void Foam::isoSurfaceCell::generateTriPoints
                             (
                                 snappedPoints,
 
+                                pVals_[tri[1]],
                                 pVals[tri[1]],
                                 pCoords[tri[1]],
                                 snappedPoint[tri[1]],
 
+                                pVals_[tri[0]],
                                 pVals[tri[0]],
                                 pCoords[tri[0]],
                                 snappedPoint[tri[0]],
 
+                                pVals_[tri[2]],
                                 pVals[tri[2]],
                                 pCoords[tri[2]],
                                 snappedPoint[tri[2]],
 
+                                cVals_[cellI],
                                 cVals[cellI],
                                 cCoords[cellI],
                                 snappedCc[cellI],
@@ -346,18 +447,22 @@ void Foam::isoSurfaceCell::generateTriPoints
                             (
                                 snappedPoints,
 
+                                pVals_[tri[0]],
                                 pVals[tri[0]],
                                 pCoords[tri[0]],
                                 snappedPoint[tri[0]],
 
+                                pVals_[tri[1]],
                                 pVals[tri[1]],
                                 pCoords[tri[1]],
                                 snappedPoint[tri[1]],
 
+                                pVals_[tri[2]],
                                 pVals[tri[2]],
                                 pCoords[tri[2]],
                                 snappedPoint[tri[2]],
 
+                                cVals_[cellI],
                                 cVals[cellI],
                                 cCoords[cellI],
                                 snappedCc[cellI],
diff --git a/src/sampling/sampledSurface/sampledPatchInternalField/sampledPatchInternalField.C b/src/sampling/sampledSurface/sampledPatchInternalField/sampledPatchInternalField.C
index b9618f866a617ec42ebc0b808fd020a48975b5e8..4f16bbed599c089df6ba2f46789ed59f5d8e7888 100644
--- a/src/sampling/sampledSurface/sampledPatchInternalField/sampledPatchInternalField.C
+++ b/src/sampling/sampledSurface/sampledPatchInternalField/sampledPatchInternalField.C
@@ -58,24 +58,80 @@ Foam::sampledPatchInternalField::sampledPatchInternalField
     sampledPatch(name, mesh, dict),
     mappers_(patchIDs().size())
 {
-    const scalar distance = readScalar(dict.lookup("distance"));
-
-    forAll(patchIDs(), i)
+    mappedPatchBase::offsetMode mode = mappedPatchBase::NORMAL;
+    if (dict.found("offsetMode"))
     {
-        label patchI = patchIDs()[i];
-        mappers_.set
+        mode = mappedPatchBase::offsetModeNames_.read
         (
-            i,
-            new mappedPatchBase
-            (
-                mesh.boundaryMesh()[patchI],
-                mesh.name(),                        // sampleRegion
-                mappedPatchBase::NEARESTCELL, // sampleMode
-                word::null,                         // samplePatch
-                -distance                           // sample inside my domain
-            )
+            dict.lookup("offsetMode")
         );
     }
+
+    switch (mode)
+    {
+        case mappedPatchBase::NORMAL:
+        {
+            const scalar distance = readScalar(dict.lookup("distance"));
+            forAll(patchIDs(), i)
+            {
+                mappers_.set
+                (
+                    i,
+                    new mappedPatchBase
+                    (
+                        mesh.boundaryMesh()[patchIDs()[i]],
+                        mesh.name(),                        // sampleRegion
+                        mappedPatchBase::NEARESTCELL,       // sampleMode
+                        word::null,                         // samplePatch
+                        -distance                  // sample inside my domain
+                    )
+                );
+            }
+        }
+        break;
+
+        case mappedPatchBase::UNIFORM:
+        {
+            const point offset(dict.lookup("offset"));
+            forAll(patchIDs(), i)
+            {
+                mappers_.set
+                (
+                    i,
+                    new mappedPatchBase
+                    (
+                        mesh.boundaryMesh()[patchIDs()[i]],
+                        mesh.name(),                        // sampleRegion
+                        mappedPatchBase::NEARESTCELL,       // sampleMode
+                        word::null,                         // samplePatch
+                        offset                  // sample inside my domain
+                    )
+                );
+            }
+        }
+        break;
+
+        case mappedPatchBase::NONUNIFORM:
+        {
+            const pointField offsets(dict.lookup("offsets"));
+            forAll(patchIDs(), i)
+            {
+                mappers_.set
+                (
+                    i,
+                    new mappedPatchBase
+                    (
+                        mesh.boundaryMesh()[patchIDs()[i]],
+                        mesh.name(),                        // sampleRegion
+                        mappedPatchBase::NEARESTCELL,       // sampleMode
+                        word::null,                         // samplePatch
+                        offsets                  // sample inside my domain
+                    )
+                );
+            }
+        }
+        break;
+    }
 }
 
 
diff --git a/src/turbulenceModels/compressible/turbulenceModel/derivedFvPatchFields/temperatureThermoBaffle1D/temperatureThermoBaffle1DFvPatchScalarField.H b/src/turbulenceModels/compressible/turbulenceModel/derivedFvPatchFields/temperatureThermoBaffle1D/temperatureThermoBaffle1DFvPatchScalarField.H
index e3c785fb4de8ffae3766613ee7f9b3bae2017be7..8ee1b01b9cfa8c69d9e004271b6c23e9294de6a1 100644
--- a/src/turbulenceModels/compressible/turbulenceModel/derivedFvPatchFields/temperatureThermoBaffle1D/temperatureThermoBaffle1DFvPatchScalarField.H
+++ b/src/turbulenceModels/compressible/turbulenceModel/derivedFvPatchFields/temperatureThermoBaffle1D/temperatureThermoBaffle1DFvPatchScalarField.H
@@ -25,7 +25,7 @@ Class
     Foam::temperatureThermoBaffle1DFvPatchScalarField
 
 Description
-    Bounday which solves the 1D steady state heat transfer equation
+    Boundary which solves the 1D steady state heat transfer equation
     through a baffle.
 
 SourceFiles
diff --git a/src/turbulenceModels/incompressible/LES/derivedFvPatchFields/wallFunctions/nuSgsWallFunctions/nuSgsUSpaldingWallFunction/nuSgsUSpaldingWallFunctionFvPatchScalarField.C b/src/turbulenceModels/incompressible/LES/derivedFvPatchFields/wallFunctions/nuSgsWallFunctions/nuSgsUSpaldingWallFunction/nuSgsUSpaldingWallFunctionFvPatchScalarField.C
index 5f28777553f4786c6bd80d1606af72d31aeea48e..73b89be91da5510c941bf1baf5cfd51941ce9eee 100644
--- a/src/turbulenceModels/incompressible/LES/derivedFvPatchFields/wallFunctions/nuSgsWallFunctions/nuSgsUSpaldingWallFunction/nuSgsUSpaldingWallFunctionFvPatchScalarField.C
+++ b/src/turbulenceModels/incompressible/LES/derivedFvPatchFields/wallFunctions/nuSgsWallFunctions/nuSgsUSpaldingWallFunction/nuSgsUSpaldingWallFunctionFvPatchScalarField.C
@@ -24,6 +24,7 @@ License
 \*---------------------------------------------------------------------------*/
 
 #include "nuSgsUSpaldingWallFunctionFvPatchScalarField.H"
+#include "LESModel.H"
 #include "fvPatchFieldMapper.H"
 #include "volFields.H"
 #include "addToRunTimeSelectionTable.H"
@@ -47,8 +48,6 @@ nuSgsUSpaldingWallFunctionFvPatchScalarField
 )
 :
     fixedValueFvPatchScalarField(p, iF),
-    UName_("U"),
-    nuName_("nu"),
     kappa_(0.41),
     E_(9.8)
 {}
@@ -64,8 +63,6 @@ nuSgsUSpaldingWallFunctionFvPatchScalarField
 )
 :
     fixedValueFvPatchScalarField(ptf, p, iF, mapper),
-    UName_(ptf.UName_),
-    nuName_(ptf.nuName_),
     kappa_(ptf.kappa_),
     E_(ptf.E_)
 {}
@@ -80,8 +77,6 @@ nuSgsUSpaldingWallFunctionFvPatchScalarField
 )
 :
     fixedValueFvPatchScalarField(p, iF, dict),
-    UName_(dict.lookupOrDefault<word>("U", "U")),
-    nuName_(dict.lookupOrDefault<word>("nu", "nu")),
     kappa_(dict.lookupOrDefault<scalar>("kappa", 0.41)),
     E_(dict.lookupOrDefault<scalar>("E", 9.8))
 {}
@@ -94,8 +89,6 @@ nuSgsUSpaldingWallFunctionFvPatchScalarField
 )
 :
     fixedValueFvPatchScalarField(nwfpsf),
-    UName_(nwfpsf.UName_),
-    nuName_(nwfpsf.nuName_),
     kappa_(nwfpsf.kappa_),
     E_(nwfpsf.E_)
 {}
@@ -109,8 +102,6 @@ nuSgsUSpaldingWallFunctionFvPatchScalarField
 )
 :
     fixedValueFvPatchScalarField(nwfpsf, iF),
-    UName_(nwfpsf.UName_),
-    nuName_(nwfpsf.nuName_),
     kappa_(nwfpsf.kappa_),
     E_(nwfpsf.E_)
 {}
@@ -123,16 +114,15 @@ void nuSgsUSpaldingWallFunctionFvPatchScalarField::evaluate
     const Pstream::commsTypes
 )
 {
-    const scalarField& ry = patch().deltaCoeffs();
+    const LESModel& lesModel = db().lookupObject<LESModel>("LESProperties");
+    const label patchi = patch().index();
+    const fvPatchVectorField& U = lesModel.U().boundaryField()[patchi];
+    const scalarField nuw = lesModel.nu()().boundaryField()[patchi];
 
-    const fvPatchVectorField& U =
-        patch().lookupPatchField<volVectorField, vector>(UName_);
+    const scalarField& ry = patch().deltaCoeffs();
 
     const scalarField magUp(mag(U.patchInternalField() - U));
 
-    const scalarField& nuw =
-        patch().lookupPatchField<volScalarField, scalar>(nuName_);
-
     scalarField& nuSgsw = *this;
 
     const scalarField magFaceGradU(mag(U.snGrad()));
@@ -185,8 +175,6 @@ void nuSgsUSpaldingWallFunctionFvPatchScalarField::evaluate
 void nuSgsUSpaldingWallFunctionFvPatchScalarField::write(Ostream& os) const
 {
     fvPatchField<scalar>::write(os);
-    writeEntryIfDifferent<word>(os, "U", "U", UName_);
-    writeEntryIfDifferent<word>(os, "nu", "nu", nuName_);
     os.writeKeyword("kappa") << kappa_ << token::END_STATEMENT << nl;
     os.writeKeyword("E") << E_ << token::END_STATEMENT << nl;
     writeEntry("value", os);
@@ -201,6 +189,7 @@ makePatchTypeField
     nuSgsUSpaldingWallFunctionFvPatchScalarField
 );
 
+
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 } // End namespace LESModels
diff --git a/src/turbulenceModels/incompressible/LES/derivedFvPatchFields/wallFunctions/nuSgsWallFunctions/nuSgsUSpaldingWallFunction/nuSgsUSpaldingWallFunctionFvPatchScalarField.H b/src/turbulenceModels/incompressible/LES/derivedFvPatchFields/wallFunctions/nuSgsWallFunctions/nuSgsUSpaldingWallFunction/nuSgsUSpaldingWallFunctionFvPatchScalarField.H
index 1ebccdc8ca10b2ce12ebffaba571e5bd89f62cf5..11de1fb06f3e72d2cfdb347f7e2aa346b05900a3 100644
--- a/src/turbulenceModels/incompressible/LES/derivedFvPatchFields/wallFunctions/nuSgsWallFunctions/nuSgsUSpaldingWallFunction/nuSgsUSpaldingWallFunctionFvPatchScalarField.H
+++ b/src/turbulenceModels/incompressible/LES/derivedFvPatchFields/wallFunctions/nuSgsWallFunctions/nuSgsUSpaldingWallFunction/nuSgsUSpaldingWallFunctionFvPatchScalarField.H
@@ -58,12 +58,6 @@ class nuSgsUSpaldingWallFunctionFvPatchScalarField
 {
     // Private data
 
-        //- Name of velocity field
-        word UName_;
-
-        //- Name of laminar viscosity field
-        word nuName_;
-
         //- Von Karman constant
         scalar kappa_;
 
diff --git a/tutorials/combustion/fireFoam/les/oppositeBurningPanels/system/extrudeToRegionMeshDict b/tutorials/combustion/fireFoam/les/oppositeBurningPanels/system/extrudeToRegionMeshDict
index da254a0470a840676b62db00f13e269b89db974e..424d9deb692596b00e0766a02629453d30945106 100644
--- a/tutorials/combustion/fireFoam/les/oppositeBurningPanels/system/extrudeToRegionMeshDict
+++ b/tutorials/combustion/fireFoam/les/oppositeBurningPanels/system/extrudeToRegionMeshDict
@@ -20,6 +20,8 @@ faceZones       (fRight_zone fLeft_zone);
 
 oneD            true;
 
+sampleMode      nearestPatchFace;
+
 oneDPolyPatchType emptyPolyPatch; //wedgePolyPatch
 
 extrudeModel    linearNormal;
diff --git a/tutorials/heatTransfer/buoyantBoussinesqSimpleFoam/iglooWithFridges/system/snappyHexMeshDict b/tutorials/heatTransfer/buoyantBoussinesqSimpleFoam/iglooWithFridges/system/snappyHexMeshDict
index 69f7412ef5afe448d6dccc8263475a967a8cbd48..0bbb485782f79129497068ed0643a8c7d1047a4e 100644
--- a/tutorials/heatTransfer/buoyantBoussinesqSimpleFoam/iglooWithFridges/system/snappyHexMeshDict
+++ b/tutorials/heatTransfer/buoyantBoussinesqSimpleFoam/iglooWithFridges/system/snappyHexMeshDict
@@ -119,7 +119,7 @@ castellatedMeshControls
     // If local number of cells is >= maxLocalCells on any processor
     // switches from from refinement followed by balancing
     // (current method) to (weighted) balancing before refinement.
-    maxLocalCells 1000000;
+    maxLocalCells 100000;
 
     // Overall cell limit (approximately). Refinement will stop immediately
     // upon reaching this number so a refinement level might not complete.
diff --git a/tutorials/heatTransfer/chtMultiRegionFoam/snappyMultiRegionHeater/system/snappyHexMeshDict b/tutorials/heatTransfer/chtMultiRegionFoam/snappyMultiRegionHeater/system/snappyHexMeshDict
index e43a518fb3b2f02e0ad37af46248bb45699d1112..82b6381b1b4c594362bec8c764549d9acf5ce4eb 100644
--- a/tutorials/heatTransfer/chtMultiRegionFoam/snappyMultiRegionHeater/system/snappyHexMeshDict
+++ b/tutorials/heatTransfer/chtMultiRegionFoam/snappyMultiRegionHeater/system/snappyHexMeshDict
@@ -76,10 +76,10 @@ castellatedMeshControls
     // Refinement parameters
     // ~~~~~~~~~~~~~~~~~~~~~
 
-    // While refining maximum number of cells per processor. This is basically
-    // the number of cells that fit on a processor. If you choose this too small
-    // it will do just more refinement iterations to obtain a similar mesh.
-    maxLocalCells 1000000;
+    // If local number of cells is >= maxLocalCells on any processor
+    // switches from from refinement followed by balancing
+    // (current method) to (weighted) balancing before refinement.
+    maxLocalCells 100000;
 
     // Overall cell limit (approximately). Refinement will stop immediately
     // upon reaching this number so a refinement level might not complete.
diff --git a/tutorials/incompressible/pimpleDyMFoam/mixerVesselAMI2D/constant/polyMesh/boundary b/tutorials/incompressible/pimpleDyMFoam/mixerVesselAMI2D/constant/polyMesh/boundary
deleted file mode 100644
index 34ba2b59dd5841f843205bd97931f7146bde317d..0000000000000000000000000000000000000000
--- a/tutorials/incompressible/pimpleDyMFoam/mixerVesselAMI2D/constant/polyMesh/boundary
+++ /dev/null
@@ -1,78 +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       polyBoundaryMesh;
-    location    "constant/polyMesh";
-    object      boundary;
-}
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-6
-(
-    rotor
-    {
-        type            wall;
-        nFaces          192;
-        startFace       5856;
-    }
-    stator
-    {
-        type            wall;
-        nFaces          192;
-        startFace       6048;
-    }
-    AMI1
-    {
-        type            cyclicAMI;
-        nFaces          96;
-        startFace       6240;
-        matchTolerance  0.0001;
-        neighbourPatch  AMI2;
-        transform       noOrdering;
-        surface
-        {
-            type            searchableCylinder;
-            point1          ( 0 0 -1 );
-            point2          ( 0 0 1 );
-            radius          0.5;
-        }
-    }
-    AMI2
-    {
-        type            cyclicAMI;
-        nFaces          96;
-        startFace       6336;
-        matchTolerance  0.0001;
-        neighbourPatch  AMI1;
-        transform       noOrdering;
-        surface
-        {
-            type            searchableCylinder;
-            point1          ( 0 0 -1 );
-            point2          ( 0 0 1 );
-            radius          0.5;
-        }
-    }
-    front
-    {
-        type            empty;
-        nFaces          3072;
-        startFace       6432;
-    }
-    back
-    {
-        type            empty;
-        nFaces          3072;
-        startFace       9504;
-    }
-)
-
-// ************************************************************************* //
diff --git a/tutorials/incompressible/pimpleDyMFoam/wingMotion/wingMotion_snappyHexMesh/system/snappyHexMeshDict b/tutorials/incompressible/pimpleDyMFoam/wingMotion/wingMotion_snappyHexMesh/system/snappyHexMeshDict
index 21553bc0d1c09c6f12aff6ed0f1a7d0c6dba32b1..b4c3ed8f64c234a2fa7ea9e71484da7d363427f9 100644
--- a/tutorials/incompressible/pimpleDyMFoam/wingMotion/wingMotion_snappyHexMesh/system/snappyHexMeshDict
+++ b/tutorials/incompressible/pimpleDyMFoam/wingMotion/wingMotion_snappyHexMesh/system/snappyHexMeshDict
@@ -53,7 +53,7 @@ castellatedMeshControls
     // If local number of cells is >= maxLocalCells on any processor
     // switches from from refinement followed by balancing
     // (current method) to (weighted) balancing before refinement.
-    maxLocalCells 1000000;
+    maxLocalCells 100000;
 
     // Overall cell limit (approximately). Refinement will stop immediately
     // upon reaching this number so a refinement level might not complete.
diff --git a/tutorials/incompressible/simpleFoam/motorBike/system/snappyHexMeshDict b/tutorials/incompressible/simpleFoam/motorBike/system/snappyHexMeshDict
index ffc577007b3498f82018640c21f5d2e7ad5001f0..153726a3acbf97ebc6893992fd76df5b444f5507 100644
--- a/tutorials/incompressible/simpleFoam/motorBike/system/snappyHexMeshDict
+++ b/tutorials/incompressible/simpleFoam/motorBike/system/snappyHexMeshDict
@@ -54,7 +54,7 @@ castellatedMeshControls
     // If local number of cells is >= maxLocalCells on any processor
     // switches from from refinement followed by balancing
     // (current method) to (weighted) balancing before refinement.
-    maxLocalCells 1000000;
+    maxLocalCells 100000;
 
     // Overall cell limit (approximately). Refinement will stop immediately
     // upon reaching this number so a refinement level might not complete.
diff --git a/tutorials/incompressible/windSimpleFoam/turbineSiting/system/snappyHexMeshDict b/tutorials/incompressible/windSimpleFoam/turbineSiting/system/snappyHexMeshDict
index d0e899232df13b822a1cdaeb8cc406a017191360..1e6f477fc4a9c45f6416d31290a9e177f7433920 100644
--- a/tutorials/incompressible/windSimpleFoam/turbineSiting/system/snappyHexMeshDict
+++ b/tutorials/incompressible/windSimpleFoam/turbineSiting/system/snappyHexMeshDict
@@ -86,7 +86,7 @@ castellatedMeshControls
     // If local number of cells is >= maxLocalCells on any processor
     // switches from from refinement followed by balancing
     // (current method) to (weighted) balancing before refinement.
-    maxLocalCells 1000000;
+    maxLocalCells 100000;
 
     // Overall cell limit (approximately). Refinement will stop immediately
     // upon reaching this number so a refinement level might not complete.
diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/cylinder/system/extrudeToRegionMeshDict b/tutorials/lagrangian/reactingParcelFilmFoam/cylinder/system/extrudeToRegionMeshDict
index 92b3f984e1a8d487823ea07dfcdd68f985bd367e..8917dc60190e393a72dcf9db892604e321353b3f 100644
--- a/tutorials/lagrangian/reactingParcelFilmFoam/cylinder/system/extrudeToRegionMeshDict
+++ b/tutorials/lagrangian/reactingParcelFilmFoam/cylinder/system/extrudeToRegionMeshDict
@@ -18,6 +18,8 @@ region          wallFilmRegion;
 
 faceZones       (wallFilmFaces);
 
+sampleMode      nearestPatchFace;
+
 oneD            false;
 
 extrudeModel    linearNormal;
diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/hotBoxes/system/extrudeToRegionMeshDict b/tutorials/lagrangian/reactingParcelFilmFoam/hotBoxes/system/extrudeToRegionMeshDict
index 35ce583303d065812d59e48c63b26ac1f82bbf88..6cfa8d6cb03d4d7cea3875b90e6eb29923ac5f8b 100644
--- a/tutorials/lagrangian/reactingParcelFilmFoam/hotBoxes/system/extrudeToRegionMeshDict
+++ b/tutorials/lagrangian/reactingParcelFilmFoam/hotBoxes/system/extrudeToRegionMeshDict
@@ -24,6 +24,8 @@ faceZones
 
 oneD            false;
 
+sampleMode      nearestPatchFace;
+
 extrudeModel    linearNormal;
 
 nLayers         1;
diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/rivuletPanel/system/extrudeToRegionMeshDict b/tutorials/lagrangian/reactingParcelFilmFoam/rivuletPanel/system/extrudeToRegionMeshDict
index 92b3f984e1a8d487823ea07dfcdd68f985bd367e..c20761906087c72fb248a2d8e2e2e173c98cc768 100644
--- a/tutorials/lagrangian/reactingParcelFilmFoam/rivuletPanel/system/extrudeToRegionMeshDict
+++ b/tutorials/lagrangian/reactingParcelFilmFoam/rivuletPanel/system/extrudeToRegionMeshDict
@@ -20,6 +20,8 @@ faceZones       (wallFilmFaces);
 
 oneD            false;
 
+sampleMode      nearestPatchFace;
+
 extrudeModel    linearNormal;
 
 nLayers         1;
diff --git a/tutorials/lagrangian/reactingParcelFilmFoam/splashPanel/system/extrudeToRegionMeshDict b/tutorials/lagrangian/reactingParcelFilmFoam/splashPanel/system/extrudeToRegionMeshDict
index 92b3f984e1a8d487823ea07dfcdd68f985bd367e..c20761906087c72fb248a2d8e2e2e173c98cc768 100644
--- a/tutorials/lagrangian/reactingParcelFilmFoam/splashPanel/system/extrudeToRegionMeshDict
+++ b/tutorials/lagrangian/reactingParcelFilmFoam/splashPanel/system/extrudeToRegionMeshDict
@@ -20,6 +20,8 @@ faceZones       (wallFilmFaces);
 
 oneD            false;
 
+sampleMode      nearestPatchFace;
+
 extrudeModel    linearNormal;
 
 nLayers         1;
diff --git a/tutorials/mesh/snappyHexMesh/flange/system/snappyHexMeshDict b/tutorials/mesh/snappyHexMesh/flange/system/snappyHexMeshDict
index d412e2772163fd2fc63ee992e7f88b82082502c6..feb4f2f871c001855b7ad3212f00677c0d57bede 100644
--- a/tutorials/mesh/snappyHexMesh/flange/system/snappyHexMeshDict
+++ b/tutorials/mesh/snappyHexMesh/flange/system/snappyHexMeshDict
@@ -53,10 +53,10 @@ castellatedMeshControls
     // Refinement parameters
     // ~~~~~~~~~~~~~~~~~~~~~
 
-    // While refining maximum number of cells per processor. This is basically
-    // the number of cells that fit on a processor. If you choose this too small
-    // it will do just more refinement iterations to obtain a similar mesh.
-    maxLocalCells 1000000;
+    // If local number of cells is >= maxLocalCells on any processor
+    // switches from from refinement followed by balancing
+    // (current method) to (weighted) balancing before refinement.
+    maxLocalCells 100000;
 
     // Overall cell limit (approximately). Refinement will stop immediately
     // upon reaching this number so a refinement level might not complete.
diff --git a/tutorials/multiphase/LTSInterFoam/wigleyHull/system/snappyHexMeshDict b/tutorials/multiphase/LTSInterFoam/wigleyHull/system/snappyHexMeshDict
index b63d2709eceb32708829829962e4b3ecf05c03d0..01badbd1ec0ac2a2512d5fdd4e4214feaa9467e3 100644
--- a/tutorials/multiphase/LTSInterFoam/wigleyHull/system/snappyHexMeshDict
+++ b/tutorials/multiphase/LTSInterFoam/wigleyHull/system/snappyHexMeshDict
@@ -71,10 +71,10 @@ castellatedMeshControls
     // Refinement parameters
     // ~~~~~~~~~~~~~~~~~~~~~
 
-    // While refining maximum number of cells per processor. This is basically
-    // the number of cells that fit on a processor. If you choose this too small
-    // it will do just more refinement iterations to obtain a similar mesh.
-    maxLocalCells 1000000;
+    // If local number of cells is >= maxLocalCells on any processor
+    // switches from from refinement followed by balancing
+    // (current method) to (weighted) balancing before refinement.
+    maxLocalCells 100000;
 
     // Overall cell limit (approximately). Refinement will stop immediately
     // upon reaching this number so a refinement level might not complete.
diff --git a/tutorials/multiphase/interDyMFoam/ras/damBreakWithObstacle/constant/dynamicMeshDict b/tutorials/multiphase/interDyMFoam/ras/damBreakWithObstacle/constant/dynamicMeshDict
index 91232bba6fd17de29ef21790acdbcdbfa6c3c903..64223ec7b8ff667637b4205292da9e398ecc0f21 100644
--- a/tutorials/multiphase/interDyMFoam/ras/damBreakWithObstacle/constant/dynamicMeshDict
+++ b/tutorials/multiphase/interDyMFoam/ras/damBreakWithObstacle/constant/dynamicMeshDict
@@ -35,13 +35,16 @@ dynamicRefineFvMeshCoeffs
     // Stop refinement if maxCells reached
     maxCells        200000;
     // Flux field and corresponding velocity field. Fluxes on changed
-    // faces get recalculated by interpolating the velocity.
+    // faces get recalculated by interpolating the velocity. Use 'none'
+    // on surfaceScalarFields that do not need to be reinterpolated.
     correctFluxes
     (
-        (
-            phi
-            U
-        )
+        (phi Urel)
+        (phiAbs U)
+        (phiAbs_0 U_0)
+        (nHatf none)
+        (rho*phi none)
+        (ghf none)
     );
     // Write the refinement level as a volScalarField
     dumpLevel       true;
diff --git a/tutorials/multiphase/interPhaseChangeFoam/cavitatingBullet/system/snappyHexMeshDict b/tutorials/multiphase/interPhaseChangeFoam/cavitatingBullet/system/snappyHexMeshDict
index 8c38433da730d235372d678a30f832e47cc52d87..5150850030ac242e598558d58da560e03415393c 100644
--- a/tutorials/multiphase/interPhaseChangeFoam/cavitatingBullet/system/snappyHexMeshDict
+++ b/tutorials/multiphase/interPhaseChangeFoam/cavitatingBullet/system/snappyHexMeshDict
@@ -68,10 +68,10 @@ castellatedMeshControls
     // Refinement parameters
     // ~~~~~~~~~~~~~~~~~~~~~
 
-    // While refining maximum number of cells per processor. This is basically
-    // the number of cells that fit on a processor. If you choose this too small
-    // it will do just more refinement iterations to obtain a similar mesh.
-    maxLocalCells 1000000;
+    // If local number of cells is >= maxLocalCells on any processor
+    // switches from from refinement followed by balancing
+    // (current method) to (weighted) balancing before refinement.
+    maxLocalCells 100000;
 
     // Overall cell limit (approximately). Refinement will stop immediately
     // upon reaching this number so a refinement level might not complete.
diff --git a/tutorials/multiphase/multiphaseEulerFoam/bubbleColumn/system/fvSolution b/tutorials/multiphase/multiphaseEulerFoam/bubbleColumn/system/fvSolution
index 9379d3029f5ef8c2a0612c7f586ea588736f09ee..cf4ce79ecf23c40a9c8a6335556f98005881425d 100644
--- a/tutorials/multiphase/multiphaseEulerFoam/bubbleColumn/system/fvSolution
+++ b/tutorials/multiphase/multiphaseEulerFoam/bubbleColumn/system/fvSolution
@@ -97,18 +97,12 @@ PIMPLE
 
 relaxationFactors
 {
-    fields
-    {
-    }
-    equations
-    {
-        "U.*"           1;
-        "T.*"           1;
-        "alpha.*"       1;
-        "Theta.*"       1;
-        "k.*"           1;
-        "epsilon.*"     1;
-    }
+    "U.*"           1;
+    "T.*"           1;
+    "alpha.*"       1;
+    "Theta.*"       1;
+    "k.*"           1;
+    "epsilon.*"     1;
 }
 
 
diff --git a/tutorials/multiphase/multiphaseEulerFoam/damBreak4phase/system/fvSolution b/tutorials/multiphase/multiphaseEulerFoam/damBreak4phase/system/fvSolution
index 39c47f6efcb6931edabaff134cfb31c1fd4ece44..296b0cd48839b3ce647e02a066bcaaa341e692f1 100644
--- a/tutorials/multiphase/multiphaseEulerFoam/damBreak4phase/system/fvSolution
+++ b/tutorials/multiphase/multiphaseEulerFoam/damBreak4phase/system/fvSolution
@@ -88,13 +88,7 @@ PIMPLE
 
 relaxationFactors
 {
-    fields
-    {
-    }
-    equations
-    {
-        "U.*"           1;
-    }
+    "U.*"           1;
 }
 
 // ************************************************************************* //
diff --git a/wmake/rules/General/mplibSGIMPI b/wmake/rules/General/mplibSGIMPI
new file mode 100644
index 0000000000000000000000000000000000000000..8595264660f3ae07d4fadb3b9ed8689d89571427
--- /dev/null
+++ b/wmake/rules/General/mplibSGIMPI
@@ -0,0 +1,3 @@
+PFLAGS     = -DSGIMPI -DMPI_NO_CPPBIND
+PINC       = -I$(MPI_ARCH_PATH)/include
+PLIBS      = -L$(MPI_ARCH_PATH)/lib -lmpi