diff --git a/applications/solvers/heatTransfer/buoyantBoussinesqSimpleFoam/Make/files b/applications/solvers/heatTransfer/buoyantBoussinesqSimpleFoam/Make/files
new file mode 100644
index 0000000000000000000000000000000000000000..677ada2ca2f3fb3500bc36f1dbff210fa19ad7b6
--- /dev/null
+++ b/applications/solvers/heatTransfer/buoyantBoussinesqSimpleFoam/Make/files
@@ -0,0 +1,3 @@
+buoyantBoussinesqSimpleFoam.C
+
+EXE = $(FOAM_APPBIN)/buoyantBoussinesqSimpleFoam
diff --git a/applications/solvers/heatTransfer/buoyantBoussinesqSimpleFoam/Make/options b/applications/solvers/heatTransfer/buoyantBoussinesqSimpleFoam/Make/options
new file mode 100644
index 0000000000000000000000000000000000000000..a53061a93cc503d9368d9d3a900ac6ef801015ba
--- /dev/null
+++ b/applications/solvers/heatTransfer/buoyantBoussinesqSimpleFoam/Make/options
@@ -0,0 +1,12 @@
+EXE_INC = \
+    -I$(LIB_SRC)/finiteVolume/lnInclude \
+    -I$(LIB_SRC)/turbulenceModels \
+    -I$(LIB_SRC)/turbulenceModels/incompressible/RAS/lnInclude \
+    -I$(LIB_SRC)/transportModels \
+    -I$(LIB_SRC)/transportModels/incompressible/singlePhaseTransportModel
+
+EXE_LIBS = \
+    -lfiniteVolume \
+    -lmeshTools \
+    -lincompressibleRASModels \
+    -lincompressibleTransportModels
diff --git a/applications/solvers/heatTransfer/buoyantBoussinesqSimpleFoam/TEqn.H b/applications/solvers/heatTransfer/buoyantBoussinesqSimpleFoam/TEqn.H
new file mode 100644
index 0000000000000000000000000000000000000000..d00f0877eaf592058b956d3c9f78979d91d6dbc1
--- /dev/null
+++ b/applications/solvers/heatTransfer/buoyantBoussinesqSimpleFoam/TEqn.H
@@ -0,0 +1,19 @@
+{
+    volScalarField kappaEff
+    (
+        "kappaEff",
+        turbulence->nu() + turbulence->nut()/Prt
+    );
+
+    fvScalarMatrix TEqn
+    (
+        fvm::div(phi, T)
+      - fvm::Sp(fvc::div(phi), T)
+      - fvm::laplacian(kappaEff, T)
+    );
+
+    TEqn.relax();
+
+    eqnResidual = TEqn.solve().initialResidual();
+    maxResidual = max(eqnResidual, maxResidual);
+}
diff --git a/applications/solvers/heatTransfer/buoyantBoussinesqSimpleFoam/UEqn.H b/applications/solvers/heatTransfer/buoyantBoussinesqSimpleFoam/UEqn.H
new file mode 100644
index 0000000000000000000000000000000000000000..cf5c4a197893afff99ffec01847b2ce9bbd57b3e
--- /dev/null
+++ b/applications/solvers/heatTransfer/buoyantBoussinesqSimpleFoam/UEqn.H
@@ -0,0 +1,25 @@
+    // Solve the momentum equation
+
+    tmp<fvVectorMatrix> UEqn
+    (
+        fvm::div(phi, U)
+      - fvm::Sp(fvc::div(phi), U)
+      + turbulence->divDevReff(U)
+    );
+
+    UEqn().relax();
+
+    eqnResidual = solve
+    (
+        UEqn()
+      ==
+       -fvc::reconstruct
+        (
+            (
+                fvc::snGrad(pd)
+              - betaghf*fvc::snGrad(T)
+            ) * mesh.magSf()
+        )
+    ).initialResidual();
+
+    maxResidual = max(eqnResidual, maxResidual);
diff --git a/applications/solvers/heatTransfer/buoyantBoussinesqSimpleFoam/buoyantBoussinesqSimpleFoam.C b/applications/solvers/heatTransfer/buoyantBoussinesqSimpleFoam/buoyantBoussinesqSimpleFoam.C
new file mode 100644
index 0000000000000000000000000000000000000000..5e9deff76449eda684405bbd010aa5e611404bda
--- /dev/null
+++ b/applications/solvers/heatTransfer/buoyantBoussinesqSimpleFoam/buoyantBoussinesqSimpleFoam.C
@@ -0,0 +1,105 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software; you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by the
+    Free Software Foundation; either version 2 of the License, or (at your
+    option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM; if not, write to the Free Software Foundation,
+    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+Application
+    buoyantBoussinesqSimpleFoam
+
+Description
+    Steady-state solver for buoyant, turbulent flow of incompressible fluids
+
+    Uses the Boussinesq approximation:
+    \f[
+        rho_{eff} = 1 - beta(T - T_{ref})
+    \f]
+
+    where:
+        \f$ rho_{eff} \f$ = the effective (driving) density
+        beta = thermal expansion coefficient [1/K]
+        T = temperature [K]
+        \f$ T_{ref} \f$ = reference temperature [K]
+
+    Valid when:
+    \f[
+        rho_{eff} << 1
+    \f]
+
+\*---------------------------------------------------------------------------*/
+
+#include "fvCFD.H"
+#include "singlePhaseTransportModel.H"
+#include "RASModel.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+int main(int argc, char *argv[])
+{
+
+#   include "setRootCase.H"
+#   include "createTime.H"
+#   include "createMesh.H"
+#   include "readEnvironmentalProperties.H"
+#   include "createFields.H"
+#   include "initContinuityErrs.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+    Info<< "\nStarting time loop\n" << endl;
+
+    for (runTime++; !runTime.end(); runTime++)
+    {
+        Info<< "Time = " << runTime.timeName() << nl << endl;
+
+#       include "readSIMPLEControls.H"
+#       include "initConvergenceCheck.H"
+
+        pd.storePrevIter();
+
+        // Pressure-velocity SIMPLE corrector
+        {
+#           include "UEqn.H"
+#           include "TEqn.H"
+#           include "pdEqn.H"
+        }
+
+        turbulence->correct();
+
+        if (runTime.write())
+        {
+#           include "writeAdditionalFields.H"
+        }
+
+        Info<< "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
+            << "  ClockTime = " << runTime.elapsedClockTime() << " s"
+            << nl << endl;
+
+#       include "convergenceCheck.H"
+    }
+
+    Info<< "End\n" << endl;
+
+    return 0;
+}
+
+
+// ************************************************************************* //
diff --git a/applications/solvers/heatTransfer/buoyantBoussinesqSimpleFoam/convergenceCheck.H b/applications/solvers/heatTransfer/buoyantBoussinesqSimpleFoam/convergenceCheck.H
new file mode 100644
index 0000000000000000000000000000000000000000..8958063193af348a058fd8f3baecb2547c00da3c
--- /dev/null
+++ b/applications/solvers/heatTransfer/buoyantBoussinesqSimpleFoam/convergenceCheck.H
@@ -0,0 +1,9 @@
+// check convergence
+
+if (maxResidual < convergenceCriterion)
+{
+    Info<< "reached convergence criterion: " << convergenceCriterion << endl;
+    runTime.writeAndEnd();
+    Info<< "latestTime = " << runTime.timeName() << endl;
+}
+
diff --git a/applications/solvers/heatTransfer/buoyantBoussinesqSimpleFoam/createFields.H b/applications/solvers/heatTransfer/buoyantBoussinesqSimpleFoam/createFields.H
new file mode 100644
index 0000000000000000000000000000000000000000..5f3f13626db0a860d7058e76ce5a90f397558c95
--- /dev/null
+++ b/applications/solvers/heatTransfer/buoyantBoussinesqSimpleFoam/createFields.H
@@ -0,0 +1,67 @@
+    Info<< "Reading thermophysical properties\n" << endl;
+
+    Info<< "Reading field T\n" << endl;
+    volScalarField T
+    (
+        IOobject
+        (
+            "T",
+            runTime.timeName(),
+            mesh,
+            IOobject::MUST_READ,
+            IOobject::AUTO_WRITE
+        ),
+        mesh
+    );
+
+    // kinematic pd
+    Info<< "Reading field pd\n" << endl;
+    volScalarField pd
+    (
+        IOobject
+        (
+            "pd",
+            runTime.timeName(),
+            mesh,
+            IOobject::MUST_READ,
+            IOobject::AUTO_WRITE
+        ),
+        mesh
+    );
+
+    Info<< "Reading field U\n" << endl;
+    volVectorField U
+    (
+        IOobject
+        (
+            "U",
+            runTime.timeName(),
+            mesh,
+            IOobject::MUST_READ,
+            IOobject::AUTO_WRITE
+        ),
+        mesh
+    );
+
+#   include "createPhi.H"
+
+#   include "readTransportProperties.H"
+
+    Info<< "Creating turbulence model\n" << endl;
+    autoPtr<incompressible::RASModel> turbulence
+    (
+        incompressible::RASModel::New(U, phi, laminarTransport)
+    );
+
+    Info<< "Calculating field beta*(g.h)\n" << endl;
+    surfaceScalarField betaghf("betagh", beta*(g & mesh.Cf()));
+
+    label pdRefCell = 0;
+    scalar pdRefValue = 0.0;
+    setRefCell
+    (
+        pd,
+        mesh.solutionDict().subDict("SIMPLE"),
+        pdRefCell,
+        pdRefValue
+    );
diff --git a/applications/solvers/heatTransfer/buoyantBoussinesqSimpleFoam/initConvergenceCheck.H b/applications/solvers/heatTransfer/buoyantBoussinesqSimpleFoam/initConvergenceCheck.H
new file mode 100644
index 0000000000000000000000000000000000000000..b56197f22a50cfd07b04fc14d40b9a5454da8c5b
--- /dev/null
+++ b/applications/solvers/heatTransfer/buoyantBoussinesqSimpleFoam/initConvergenceCheck.H
@@ -0,0 +1,7 @@
+// initialize values for convergence checks
+
+    scalar eqnResidual = 1, maxResidual = 0;
+    scalar convergenceCriterion = 0;
+
+    simple.readIfPresent("convergence", convergenceCriterion);
+
diff --git a/applications/solvers/heatTransfer/buoyantBoussinesqSimpleFoam/pdEqn.H b/applications/solvers/heatTransfer/buoyantBoussinesqSimpleFoam/pdEqn.H
new file mode 100644
index 0000000000000000000000000000000000000000..e782d26c8dc5ad4374d1b5a76ab7dfd72f6b9601
--- /dev/null
+++ b/applications/solvers/heatTransfer/buoyantBoussinesqSimpleFoam/pdEqn.H
@@ -0,0 +1,49 @@
+{
+    volScalarField rUA("rUA", 1.0/UEqn().A());
+    surfaceScalarField rUAf("(1|A(U))", fvc::interpolate(rUA));
+
+    U = rUA*UEqn().H();
+    UEqn.clear();
+
+    phi = fvc::interpolate(U) & mesh.Sf();
+    adjustPhi(phi, U, pd);
+    surfaceScalarField buoyancyPhi = -betaghf*fvc::snGrad(T)*rUAf*mesh.magSf();
+    phi -= buoyancyPhi;
+
+    for (int nonOrth=0; nonOrth<=nNonOrthCorr; nonOrth++)
+    {
+        fvScalarMatrix pdEqn
+        (
+            fvm::laplacian(rUAf, pd) == fvc::div(phi)
+        );
+
+        pdEqn.setReference(pdRefCell, pdRefValue);
+
+        // retain the residual from the first iteration
+        if (nonOrth == 0)
+        {
+            eqnResidual = pdEqn.solve().initialResidual();
+            maxResidual = max(eqnResidual, maxResidual);
+        }
+        else
+        {
+            pdEqn.solve();
+        }
+
+        if (nonOrth == nNonOrthCorr)
+        {
+            // Calculate the conservative fluxes
+            phi -= pdEqn.flux();
+
+            // Explicitly relax pressure for momentum corrector
+            pd.relax();
+
+            // Correct the momentum source with the pressure gradient flux
+            // calculated from the relaxed pressure
+            U -= rUA*fvc::reconstruct((buoyancyPhi + pdEqn.flux())/rUAf);
+            U.correctBoundaryConditions();
+        }
+    }
+
+    #include "continuityErrs.H"
+}
diff --git a/applications/solvers/heatTransfer/buoyantBoussinesqSimpleFoam/readTransportProperties.H b/applications/solvers/heatTransfer/buoyantBoussinesqSimpleFoam/readTransportProperties.H
new file mode 100644
index 0000000000000000000000000000000000000000..585128dfdeb7d5e5212f9412d9b415c05c15b752
--- /dev/null
+++ b/applications/solvers/heatTransfer/buoyantBoussinesqSimpleFoam/readTransportProperties.H
@@ -0,0 +1,13 @@
+    singlePhaseTransportModel laminarTransport(U, phi);
+
+    // thermal expansion coefficient [1/K]
+    dimensionedScalar beta(laminarTransport.lookup("beta"));
+
+    // reference temperature [K]
+    dimensionedScalar TRef(laminarTransport.lookup("TRef"));
+
+    // reference kinematic pressure [m2/s2]
+    dimensionedScalar pRef(laminarTransport.lookup("pRef"));
+
+    // turbulent Prandtl number
+    dimensionedScalar Prt(laminarTransport.lookup("Prt"));
diff --git a/applications/solvers/heatTransfer/buoyantBoussinesqSimpleFoam/writeAdditionalFields.H b/applications/solvers/heatTransfer/buoyantBoussinesqSimpleFoam/writeAdditionalFields.H
new file mode 100644
index 0000000000000000000000000000000000000000..20f7c6ae1dcff80630dc2ca21253b1e824ea5d77
--- /dev/null
+++ b/applications/solvers/heatTransfer/buoyantBoussinesqSimpleFoam/writeAdditionalFields.H
@@ -0,0 +1,29 @@
+{
+    volScalarField rhoEff
+    (
+        IOobject
+        (
+            "rhoEff",
+            runTime.timeName(),
+            mesh,
+            IOobject::NO_READ,
+            IOobject::AUTO_WRITE
+        ),
+        1.0 - beta*(T - TRef)
+    );
+    rhoEff.write();
+
+    volScalarField p
+    (
+        IOobject
+        (
+            "p",
+            runTime.timeName(),
+            mesh,
+            IOobject::NO_READ,
+            IOobject::AUTO_WRITE
+        ),
+        pd + rhoEff*(g & mesh.C()) + pRef
+    );
+    p.write();
+}
diff --git a/applications/solvers/heatTransfer/buoyantFoam/UEqn.H b/applications/solvers/heatTransfer/buoyantFoam/UEqn.H
index 988268c4ef274fbd59cd4af83fa0da3eb8a0c1b3..24cfbf4f685a291b1a836fc0dfd931f9bfc526d1 100644
--- a/applications/solvers/heatTransfer/buoyantFoam/UEqn.H
+++ b/applications/solvers/heatTransfer/buoyantFoam/UEqn.H
@@ -9,4 +9,18 @@
 
     UEqn.relax();
 
-    solve(UEqn == -fvc::grad(pd) - fvc::grad(rho)*gh);
+    if (momentumPredictor)
+    {
+        solve
+        (
+            UEqn
+         ==
+           -fvc::reconstruct
+            (
+                (
+                    fvc::snGrad(pd)
+                  + ghf*fvc::snGrad(rho)
+                ) * mesh.magSf()
+            )
+        );
+    }
diff --git a/applications/solvers/heatTransfer/buoyantFoam/buoyantFoam.C b/applications/solvers/heatTransfer/buoyantFoam/buoyantFoam.C
index cafb67790017eae9ce4d380dd5f687d18b4037d6..75eb401d3db5a512a14734f29460b6bfc76957f2 100644
--- a/applications/solvers/heatTransfer/buoyantFoam/buoyantFoam.C
+++ b/applications/solvers/heatTransfer/buoyantFoam/buoyantFoam.C
@@ -41,37 +41,41 @@ Description
 
 int main(int argc, char *argv[])
 {
-
-#   include "setRootCase.H"
-#   include "createTime.H"
-#   include "createMesh.H"
-#   include "readEnvironmentalProperties.H"
-#   include "createFields.H"
-#   include "initContinuityErrs.H"
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+    #include "setRootCase.H"
+    #include "createTime.H"
+    #include "createMesh.H"
+    #include "readEnvironmentalProperties.H"
+    #include "createFields.H"
+    #include "initContinuityErrs.H"
+    #include "readTimeControls.H"
+    #include "compressibleCourantNo.H"
+    #include "setInitialDeltaT.H"
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
     Info<< "\nStarting time loop\n" << endl;
 
     while (runTime.run())
     {
-#       include "readPISOControls.H"
-#       include "compressibleCourantNo.H"
-//#       include "setDeltaT.H"
+        #include "readTimeControls.H"
+        #include "readPISOControls.H"
+        #include "compressibleCourantNo.H"
+        #include "setDeltaT.H"
 
         runTime++;
+
         Info<< "Time = " << runTime.timeName() << nl << endl;
 
-#       include "rhoEqn.H"
+        #include "rhoEqn.H"
 
-#       include "UEqn.H"
+        #include "UEqn.H"
 
         // --- PISO loop
 
         for (int corr=0; corr<nCorr; corr++)
         {
-#           include "hEqn.H"
-#           include "pEqn.H"
+            #include "hEqn.H"
+            #include "pEqn.H"
         }
 
         turbulence->correct();
diff --git a/applications/solvers/heatTransfer/buoyantFoam/createFields.H b/applications/solvers/heatTransfer/buoyantFoam/createFields.H
index 3d604d4daf00132fbaf1339ac0aa53e024a09797..a647f0a3ef2a0831cd06f96ab973c58286a0ba9b 100644
--- a/applications/solvers/heatTransfer/buoyantFoam/createFields.H
+++ b/applications/solvers/heatTransfer/buoyantFoam/createFields.H
@@ -52,11 +52,13 @@
         )
     );
 
-    Info<< "Creating field dpdt\n" << endl;
-    volScalarField dpdt = fvc::ddt(p);
+    Info<< "Creating field DpDt\n" << endl;
+    volScalarField DpDt =
+        fvc::DDt(surfaceScalarField("phiU", phi/fvc::interpolate(rho)), p);
 
     Info<< "Calculating field g.h\n" << endl;
     volScalarField gh("gh", g & mesh.C());
+    surfaceScalarField ghf("gh", g & mesh.Cf());
 
     dimensionedScalar pRef("pRef", p.dimensions(), thermo->lookup("pRef"));
 
diff --git a/applications/solvers/heatTransfer/buoyantFoam/hEqn.H b/applications/solvers/heatTransfer/buoyantFoam/hEqn.H
index 008e3b0f56c6024160801b343b3fdc9d8c194128..f1a87c6a798229100ff3493a194d73ccfdd601b9 100644
--- a/applications/solvers/heatTransfer/buoyantFoam/hEqn.H
+++ b/applications/solvers/heatTransfer/buoyantFoam/hEqn.H
@@ -5,9 +5,7 @@
       + fvm::div(phi, h)
       - fvm::laplacian(turbulence->alphaEff(), h)
      ==
-        dpdt
-      + fvc::div(phi/fvc::interpolate(rho)*fvc::interpolate(p))
-      - p*fvc::div(phi/fvc::interpolate(rho))
+        DpDt
     );
 
     hEqn.relax();
diff --git a/applications/solvers/heatTransfer/buoyantFoam/pEqn.H b/applications/solvers/heatTransfer/buoyantFoam/pEqn.H
index 36378f7f6fe3d08ee3fbe0f60f01ccfda6d229af..91e190b4cdfa4eeab0151de9126ecab5f5173036 100644
--- a/applications/solvers/heatTransfer/buoyantFoam/pEqn.H
+++ b/applications/solvers/heatTransfer/buoyantFoam/pEqn.H
@@ -1,60 +1,67 @@
-bool closedVolume = pd.needReference();
+{
+    bool closedVolume = pd.needReference();
 
-rho = thermo->rho();
+    rho = thermo->rho();
 
-volScalarField rUA = 1.0/UEqn.A();
-U = rUA*UEqn.H();
+    volScalarField rUA = 1.0/UEqn.A();
+    surfaceScalarField rhorUAf("(rho*(1|A(U)))", fvc::interpolate(rho*rUA));
 
-phi =
-    fvc::interpolate(rho)
-   *(
-        (fvc::interpolate(U) & mesh.Sf())
-      + fvc::ddtPhiCorr(rUA, rho, U, phi)
-    )
-  - fvc::interpolate(rho*rUA*gh)*fvc::snGrad(rho)*mesh.magSf();
+    U = rUA*UEqn.H();
 
-for (int nonOrth=0; nonOrth<=nNonOrthCorr; nonOrth++)
-{
-    fvScalarMatrix pdEqn
+    surfaceScalarField phiU
     (
-        fvm::ddt(psi, pd)
-      + fvc::ddt(psi)*pRef
-      + fvc::ddt(psi, rho)*gh
-      + fvc::div(phi)
-      - fvm::laplacian(rho*rUA, pd)
+        fvc::interpolate(rho)
+       *(
+           (fvc::interpolate(U) & mesh.Sf())
+         + fvc::ddtPhiCorr(rUA, rho, U, phi)
+        )
     );
 
-    if (corr == nCorr-1 && nonOrth == nNonOrthCorr)
-    {
-        pdEqn.solve(mesh.solver(pd.name() + "Final"));
-    }
-    else
-    {
-        pdEqn.solve(mesh.solver(pd.name()));
-    }
+    phi = phiU - ghf*fvc::snGrad(rho)*rhorUAf*mesh.magSf();
 
-    if (nonOrth == nNonOrthCorr)
+    for (int nonOrth=0; nonOrth<=nNonOrthCorr; nonOrth++)
     {
-        phi += pdEqn.flux();
+        fvScalarMatrix pdEqn
+        (
+            fvm::ddt(psi, pd)
+          + fvc::ddt(psi)*pRef
+          + fvc::ddt(psi, rho)*gh
+          + fvc::div(phi)
+          - fvm::laplacian(rhorUAf, pd)
+        );
+
+        if (corr == nCorr-1 && nonOrth == nNonOrthCorr)
+        {
+            pdEqn.solve(mesh.solver(pd.name() + "Final"));
+        }
+        else
+        {
+            pdEqn.solve(mesh.solver(pd.name()));
+        }
+
+        if (nonOrth == nNonOrthCorr)
+        {
+            phi += pdEqn.flux();
+        }
     }
-}
 
-p == pd + rho*gh + pRef;
-dpdt = fvc::ddt(p);
+    U += rUA*fvc::reconstruct((phi - phiU)/rhorUAf);
+    U.correctBoundaryConditions();
 
-#include "rhoEqn.H"
-#include "compressibleContinuityErrs.H"
+    p == pd + rho*gh + pRef;
+    DpDt = fvc::DDt(surfaceScalarField("phiU", phi/fvc::interpolate(rho)), p);
 
-U -= rUA*(fvc::grad(pd) + fvc::grad(rho)*gh);
-U.correctBoundaryConditions();
+    #include "rhoEqn.H"
+    #include "compressibleContinuityErrs.H"
 
+    // For closed-volume cases adjust the pressure and density levels
+    // to obey overall mass continuity
+    if (closedVolume)
+    {
+        p += (initialMass - fvc::domainIntegrate(thermo->psi()*p))
+            /fvc::domainIntegrate(thermo->psi());
+        rho = thermo->rho();
+    }
 
-// For closed-volume cases adjust the pressure and density levels
-// to obey overall mass continuity
-if (closedVolume)
-{
-    p += (initialMass - fvc::domainIntegrate(thermo->psi()*p))
-        /fvc::domainIntegrate(thermo->psi());
     pd == p - (rho*gh + pRef);
-    rho = thermo->rho();
 }
diff --git a/applications/solvers/heatTransfer/buoyantSimpleFoam/UEqn.H b/applications/solvers/heatTransfer/buoyantSimpleFoam/UEqn.H
index 5bc4c4738ccc963dadfa1666a1886deb56cd5b5b..71a57cd2a930c3affd56ba48b809e455d2a93e6c 100644
--- a/applications/solvers/heatTransfer/buoyantSimpleFoam/UEqn.H
+++ b/applications/solvers/heatTransfer/buoyantSimpleFoam/UEqn.H
@@ -11,7 +11,15 @@
 
     eqnResidual = solve
     (
-        UEqn() == -fvc::grad(pd) - fvc::grad(rho)*gh
+        UEqn()
+     ==
+       -fvc::reconstruct
+        (
+            (
+                fvc::snGrad(pd)
+              + ghf*fvc::snGrad(rho)
+            ) * mesh.magSf()
+        )
     ).initialResidual();
 
     maxResidual = max(eqnResidual, maxResidual);
diff --git a/applications/solvers/heatTransfer/buoyantSimpleFoam/createFields.H b/applications/solvers/heatTransfer/buoyantSimpleFoam/createFields.H
index 184242be81be2a08d118f4992a260c56bfffce38..d26da5cb325560d17f59e3f9a1aed4d3f08acdc5 100644
--- a/applications/solvers/heatTransfer/buoyantSimpleFoam/createFields.H
+++ b/applications/solvers/heatTransfer/buoyantSimpleFoam/createFields.H
@@ -53,6 +53,7 @@
 
     Info<< "Calculating field g.h\n" << endl;
     volScalarField gh("gh", g & mesh.C());
+    surfaceScalarField ghf("gh", g & mesh.Cf());
 
     dimensionedScalar pRef("pRef", p.dimensions(), thermo->lookup("pRef"));
 
diff --git a/applications/solvers/heatTransfer/buoyantSimpleFoam/pEqn.H b/applications/solvers/heatTransfer/buoyantSimpleFoam/pEqn.H
index 8c3621205be1325da983f87fc737e2eea31b402e..3c257d249dad22088cf3323801740e6d7adbd258 100644
--- a/applications/solvers/heatTransfer/buoyantSimpleFoam/pEqn.H
+++ b/applications/solvers/heatTransfer/buoyantSimpleFoam/pEqn.H
@@ -1,55 +1,65 @@
-volScalarField rUA = 1.0/UEqn().A();
-U = rUA*UEqn().H();
-UEqn.clear();
+{
+    volScalarField rUA = 1.0/UEqn().A();
+    surfaceScalarField rhorUAf("(rho*(1|A(U)))", fvc::interpolate(rho*rUA));
 
-phi = fvc::interpolate(rho)*(fvc::interpolate(U) & mesh.Sf());
-bool closedVolume = adjustPhi(phi, U, p);
-phi -= fvc::interpolate(rho*gh*rUA)*fvc::snGrad(rho)*mesh.magSf();
+    U = rUA*UEqn().H();
+    UEqn.clear();
 
-for (int nonOrth=0; nonOrth<=nNonOrthCorr; nonOrth++)
-{
-    fvScalarMatrix pdEqn
-    (
-        fvm::laplacian(rho*rUA, pd) == fvc::div(phi)
-    );
-
-    pdEqn.setReference(pdRefCell, pdRefValue);
-    // retain the residual from the first iteration
-    if (nonOrth == 0)
-    {
-        eqnResidual = pdEqn.solve().initialResidual();
-        maxResidual = max(eqnResidual, maxResidual);
-    }
-    else
-    {
-        pdEqn.solve();
-    }
+    phi = fvc::interpolate(rho)*(fvc::interpolate(U) & mesh.Sf());
+    bool closedVolume = adjustPhi(phi, U, p);
+    surfaceScalarField buoyancyPhi = ghf*fvc::snGrad(rho)*rhorUAf*mesh.magSf();
+    phi -= buoyancyPhi;
 
-    if (nonOrth == nNonOrthCorr)
+    for (int nonOrth=0; nonOrth<=nNonOrthCorr; nonOrth++)
     {
-        phi -= pdEqn.flux();
+        fvScalarMatrix pdEqn
+        (
+            fvm::laplacian(rhorUAf, pd) == fvc::div(phi)
+        );
+
+        pdEqn.setReference(pdRefCell, pdRefValue);
+
+        // retain the residual from the first iteration
+        if (nonOrth == 0)
+        {
+            eqnResidual = pdEqn.solve().initialResidual();
+            maxResidual = max(eqnResidual, maxResidual);
+        }
+        else
+        {
+            pdEqn.solve();
+        }
+
+        if (nonOrth == nNonOrthCorr)
+        {
+            // Calculate the conservative fluxes
+            phi -= pdEqn.flux();
+
+            // Explicitly relax pressure for momentum corrector
+            pd.relax();
+
+            // Correct the momentum source with the pressure gradient flux
+            // calculated from the relaxed pressure
+            U -= rUA*fvc::reconstruct((buoyancyPhi + pdEqn.flux())/rhorUAf);
+            U.correctBoundaryConditions();
+        }
     }
-}
 
-#include "continuityErrs.H"
+    #include "continuityErrs.H"
 
-// Explicitly relax pressure for momentum corrector
-pd.relax();
+    p == pd + rho*gh + pRef;
 
-p = pd + rho*gh + pRef;
+    // For closed-volume cases adjust the pressure and density levels
+    // to obey overall mass continuity
+    if (closedVolume)
+    {
+        p += (initialMass - fvc::domainIntegrate(thermo->psi()*p))
+            /fvc::domainIntegrate(thermo->psi());
+    }
 
-U -= rUA*(fvc::grad(pd) + fvc::grad(rho)*gh);
-U.correctBoundaryConditions();
+    rho = thermo->rho();
+    rho.relax();
+    Info<< "rho max/min : " << max(rho).value() << " " << min(rho).value() << endl;
 
-// For closed-volume cases adjust the pressure and density levels
-// to obey overall mass continuity
-if (closedVolume)
-{
-    p += (initialMass - fvc::domainIntegrate(thermo->psi()*p))
-        /fvc::domainIntegrate(thermo->psi());
     pd == p - (rho*gh + pRef);
 }
-
-rho = thermo->rho();
-rho.relax();
-Info<< "rho max/min : " << max(rho).value() << " " << min(rho).value() << endl;
diff --git a/applications/solvers/heatTransfer/buoyantSimpleRadiationFoam/Make/options b/applications/solvers/heatTransfer/buoyantSimpleRadiationFoam/Make/options
index 22d41fdb8090d1e10ef1cb1270a0f19bd0ea72ff..89d7787af65e02bc13f8411df8b37fb8d41e7fda 100644
--- a/applications/solvers/heatTransfer/buoyantSimpleRadiationFoam/Make/options
+++ b/applications/solvers/heatTransfer/buoyantSimpleRadiationFoam/Make/options
@@ -1,4 +1,5 @@
 EXE_INC = \
+    -I../buoyantSimpleFoam \
     -I$(LIB_SRC)/thermophysicalModels/basic/lnInclude \
     -I$(LIB_SRC)/thermophysicalModels/radiation/lnInclude \
     -I$(LIB_SRC)/turbulenceModels \
diff --git a/applications/solvers/heatTransfer/buoyantSimpleRadiationFoam/UEqn.H b/applications/solvers/heatTransfer/buoyantSimpleRadiationFoam/UEqn.H
deleted file mode 100644
index 5bc4c4738ccc963dadfa1666a1886deb56cd5b5b..0000000000000000000000000000000000000000
--- a/applications/solvers/heatTransfer/buoyantSimpleRadiationFoam/UEqn.H
+++ /dev/null
@@ -1,18 +0,0 @@
-    // Solve the Momentum equation
-
-    tmp<fvVectorMatrix> UEqn
-    (
-        fvm::div(phi, U)
-      - fvm::Sp(fvc::div(phi), U)
-      + turbulence->divDevRhoReff(U)
-    );
-
-    UEqn().relax();
-
-    eqnResidual = solve
-    (
-        UEqn() == -fvc::grad(pd) - fvc::grad(rho)*gh
-    ).initialResidual();
-
-    maxResidual = max(eqnResidual, maxResidual);
-
diff --git a/applications/solvers/heatTransfer/buoyantSimpleRadiationFoam/createFields.H b/applications/solvers/heatTransfer/buoyantSimpleRadiationFoam/createFields.H
index 76e3805bca6d10005cc5fe92e05e9ce2d1c15c5b..62c06ec38d63955dbf901df2659d3b3c0af4328e 100644
--- a/applications/solvers/heatTransfer/buoyantSimpleRadiationFoam/createFields.H
+++ b/applications/solvers/heatTransfer/buoyantSimpleRadiationFoam/createFields.H
@@ -54,6 +54,7 @@
 
     Info<< "Calculating field g.h\n" << endl;
     volScalarField gh("gh", g & mesh.C());
+    surfaceScalarField ghf("gh", g & mesh.Cf());
 
     dimensionedScalar pRef("pRef", p.dimensions(), thermo->lookup("pRef"));
 
diff --git a/applications/solvers/heatTransfer/buoyantSimpleRadiationFoam/pEqn.H b/applications/solvers/heatTransfer/buoyantSimpleRadiationFoam/pEqn.H
deleted file mode 100644
index 2a713bac625755acc2a7ac170984549f237934ec..0000000000000000000000000000000000000000
--- a/applications/solvers/heatTransfer/buoyantSimpleRadiationFoam/pEqn.H
+++ /dev/null
@@ -1,54 +0,0 @@
-volScalarField rUA = 1.0/UEqn().A();
-U = rUA*UEqn().H();
-UEqn.clear();
-phi = fvc::interpolate(rho)*(fvc::interpolate(U) & mesh.Sf());
-bool closedVolume = adjustPhi(phi, U, p);
-phi -= fvc::interpolate(rho*gh*rUA)*fvc::snGrad(rho)*mesh.magSf();
-
-for (int nonOrth=0; nonOrth<=nNonOrthCorr; nonOrth++)
-{
-    fvScalarMatrix pdEqn
-    (
-        fvm::laplacian(rho*rUA, pd) == fvc::div(phi)
-    );
-
-    pdEqn.setReference(pdRefCell, pdRefValue);
-    // retain the residual from the first iteration
-    if (nonOrth == 0)
-    {
-        eqnResidual = pdEqn.solve().initialResidual();
-        maxResidual = max(eqnResidual, maxResidual);
-    }
-    else
-    {
-        pdEqn.solve();
-    }
-
-    if (nonOrth == nNonOrthCorr)
-    {
-        phi -= pdEqn.flux();
-    }
-}
-
-#include "continuityErrs.H"
-
-// Explicitly relax pressure for momentum corrector
-pd.relax();
-
-p = pd + rho*gh + pRef;
-
-U -= rUA*(fvc::grad(pd) + fvc::grad(rho)*gh);
-U.correctBoundaryConditions();
-
-// For closed-volume cases adjust the pressure and density levels
-// to obey overall mass continuity
-if (closedVolume)
-{
-    p += (initialMass - fvc::domainIntegrate(thermo->psi()*p))
-        /fvc::domainIntegrate(thermo->psi());
-    pd == p - (rho*gh + pRef);
-}
-
-rho = thermo->rho();
-rho.relax();
-Info<< "rho max/min : " << max(rho).value() << " " << min(rho).value() << endl;
diff --git a/applications/solvers/heatTransfer/chtMultiRegionFoam/Make/files b/applications/solvers/heatTransfer/chtMultiRegionFoam/Make/files
index 3ee71c0ea6ad8cd2afeb422b1b7efd4bfbfe7991..9d9152930a9c359695a4e969886336ce38466f62 100644
--- a/applications/solvers/heatTransfer/chtMultiRegionFoam/Make/files
+++ b/applications/solvers/heatTransfer/chtMultiRegionFoam/Make/files
@@ -7,6 +7,8 @@ derivedFvPatchFields/solidWallHeatFluxTemperatureCoupled/solidWallHeatFluxTemper
 derivedFvPatchFields/solidWallTemperatureCoupled/solidWallTemperatureCoupledFvPatchScalarField.C
 derivedFvPatchFields/solidWallMixedTemperatureCoupled/solidWallMixedTemperatureCoupledFvPatchScalarField.C
 
+fluid/compressibleCourantNo.C
+
 chtMultiRegionFoam.C
 
 EXE = $(FOAM_APPBIN)/chtMultiRegionFoam
diff --git a/applications/solvers/heatTransfer/chtMultiRegionFoam/chtMultiRegionFoam.C b/applications/solvers/heatTransfer/chtMultiRegionFoam/chtMultiRegionFoam.C
index dad472930c34743b8ea4519405c298e0f1575169..84c7c1180634d4bc1ba25b504769c7bc98001e1b 100644
--- a/applications/solvers/heatTransfer/chtMultiRegionFoam/chtMultiRegionFoam.C
+++ b/applications/solvers/heatTransfer/chtMultiRegionFoam/chtMultiRegionFoam.C
@@ -36,16 +36,10 @@ Description
 #include "turbulenceModel.H"
 #include "fixedGradientFvPatchFields.H"
 #include "regionProperties.H"
+#include "compressibleCourantNo.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-#include "solveContinuityEquation.C"
-#include "solveMomentumEquation.C"
-#include "compressibleContinuityErrors.C"
-#include "solvePressureDifferenceEquation.C"
-#include "solveEnthalpyEquation.C"
-#include "compressibleCourantNo.C"
-
 int main(int argc, char *argv[])
 {
 
@@ -58,7 +52,6 @@ int main(int argc, char *argv[])
 #   include "createSolidMeshes.H"
 
 #   include "createFluidFields.H"
-
 #   include "createSolidFields.H"
 
 #   include "initContinuityErrs.H"
@@ -89,6 +82,7 @@ int main(int argc, char *argv[])
         {
             Info<< "\nSolving for fluid region "
                 << fluidRegions[i].name() << endl;
+#           include "setRegionFluidFields.H"
 #           include "readFluidMultiRegionPISOControls.H"
 #           include "solveFluid.H"
         }
@@ -97,6 +91,7 @@ int main(int argc, char *argv[])
         {
             Info<< "\nSolving for solid region "
                 << solidRegions[i].name() << endl;
+#           include "setRegionSolidFields.H"
 #           include "readSolidMultiRegionPISOControls.H"
 #           include "solveSolid.H"
         }
diff --git a/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/UEqn.H b/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/UEqn.H
index ba3d099a9f72730909512c6017df90d51d8818d5..e719d92433926797b7850dc356ade232228ba502 100644
--- a/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/UEqn.H
+++ b/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/UEqn.H
@@ -1,10 +1,25 @@
-    tmp<fvVectorMatrix> UEqn = solveMomentumEquation
+    // Solve the Momentum equation
+    tmp<fvVectorMatrix> UEqn
     (
-        momentumPredictor,
-        Uf[i],
-        rhof[i],
-        phif[i],
-        pdf[i],
-        ghf[i],
-        turb[i]
+        fvm::ddt(rho, U)
+      + fvm::div(phi, U)
+      + turb.divDevRhoReff(U)
     );
+
+    UEqn().relax();
+
+    if (momentumPredictor)
+    {
+         solve
+         (
+            UEqn()
+         ==
+           -fvc::reconstruct
+            (
+                (
+                    fvc::snGrad(pd)
+                  + ghf*fvc::snGrad(rho)
+                ) * mesh.magSf()
+            )
+        );
+    }
diff --git a/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/compressibleContinuityErrors.C b/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/compressibleContinuityErrors.C
deleted file mode 100644
index 9cf6446aa0c5c5f416d7ae06cd0fdb47a2299aa7..0000000000000000000000000000000000000000
--- a/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/compressibleContinuityErrors.C
+++ /dev/null
@@ -1,58 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
-     \\/     M anipulation  |
--------------------------------------------------------------------------------
-License
-    This file is part of OpenFOAM.
-
-    OpenFOAM is free software; you can redistribute it and/or modify it
-    under the terms of the GNU General Public License as published by the
-    Free Software Foundation; either version 2 of the License, or (at your
-    option) any later version.
-
-    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
-    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-    for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with OpenFOAM; if not, write to the Free Software Foundation,
-    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-Description
-    Continuity errors for fluid meshes
-
-\*---------------------------------------------------------------------------*/
-
-void compressibleContinuityErrors
-(
-    scalar& cumulativeContErr,
-    const volScalarField& rho,
-    const basicThermo& thermo
-)
-{
-    dimensionedScalar totalMass = fvc::domainIntegrate(rho);
-
-    scalar sumLocalContErr =
-    (
-        fvc::domainIntegrate(mag(rho - thermo.rho()))/totalMass
-    ).value();
-
-    scalar globalContErr =
-    (
-        fvc::domainIntegrate(rho - thermo.rho())/totalMass
-    ).value();
-
-    cumulativeContErr += globalContErr;
-
-    const word& regionName = rho.mesh().name();
-
-    Info<< "time step continuity errors (" << regionName << ")"
-        << ": sum local = " << sumLocalContErr
-        << ", global = " << globalContErr
-        << ", cumulative = " << cumulativeContErr
-        << endl;
-}
diff --git a/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/compressibleContinuityErrors.H b/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/compressibleContinuityErrors.H
new file mode 100644
index 0000000000000000000000000000000000000000..046ca5ec378429b496b6e4bbe47c844a1a6999de
--- /dev/null
+++ b/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/compressibleContinuityErrors.H
@@ -0,0 +1,21 @@
+{
+    dimensionedScalar totalMass = fvc::domainIntegrate(rho);
+
+    scalar sumLocalContErr =
+    (
+        fvc::domainIntegrate(mag(rho - thermo.rho()))/totalMass
+    ).value();
+
+    scalar globalContErr =
+    (
+        fvc::domainIntegrate(rho - thermo.rho())/totalMass
+    ).value();
+
+    cumulativeContErr[i] += globalContErr;
+
+    Info<< "time step continuity errors (" << mesh.name() << ")"
+        << ": sum local = " << sumLocalContErr
+        << ", global = " << globalContErr
+        << ", cumulative = " << cumulativeContErr[i]
+        << endl;
+}
diff --git a/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/compressibleCourantNo.C b/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/compressibleCourantNo.C
index 487fd93825af3495db9ed5a67b0203878b1acb5d..e671a256c9a84900d458336fc45fa16aa64d3d3d 100644
--- a/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/compressibleCourantNo.C
+++ b/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/compressibleCourantNo.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
+    \\  /    A nd           | Copyright (C) 1991-2008 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -22,13 +22,12 @@ License
     along with OpenFOAM; if not, write to the Free Software Foundation,
     Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 
-Description
-    Calculates and outputs the mean and maximum Courant Numbers for the fluid
-    regions
-
 \*---------------------------------------------------------------------------*/
 
-scalar compressibleCourantNo
+#include "compressibleCourantNo.H"
+#include "fvc.H"
+
+Foam::scalar Foam::compressibleCourantNo
 (
     const fvMesh& mesh,
     const Time& runTime,
diff --git a/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/solveEnthalpyEquation.C b/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/compressibleCourantNo.H
similarity index 65%
rename from applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/solveEnthalpyEquation.C
rename to applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/compressibleCourantNo.H
index 2e9cae95ad912962432528c0ce7f5db16e901490..4bdfb84fcb80830cb87e557e8422fc56fb62fefe 100644
--- a/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/solveEnthalpyEquation.C
+++ b/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/compressibleCourantNo.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
+    \\  /    A nd           | Copyright (C) 1991-2008 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -23,34 +23,27 @@ License
     Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 
 Description
-    Solve enthalpy equation
+    Calculates and outputs the mean and maximum Courant Numbers for the fluid
+    regions
 
 \*---------------------------------------------------------------------------*/
 
-void solveEnthalpyEquation
-(
-    const volScalarField& rho,
-    const volScalarField& DpDt,
-    const surfaceScalarField& phi,
-    const compressible::turbulenceModel& turb,
-    basicThermo& thermo
-)
-{
-    volScalarField& h = thermo.h();
+#ifndef compressibleCourantNo_H
+#define compressibleCourantNo_H
+
+#include "fvMesh.H"
 
-    tmp<fvScalarMatrix> hEqn
+namespace Foam
+{
+    scalar compressibleCourantNo
     (
-        fvm::ddt(rho, h)
-      + fvm::div(phi, h)
-      - fvm::laplacian(turb.alphaEff(), h)
-     ==
-        DpDt
+        const fvMesh& mesh,
+        const Time& runTime,
+        const volScalarField& rho,
+        const surfaceScalarField& phi
     );
-    hEqn().relax();
-    hEqn().solve();
+}
 
-    thermo.correct();
+#endif
 
-    Info<< "Min/max T:" << min(thermo.T()) << ' ' << max(thermo.T())
-        << endl;
-}
+// ************************************************************************* //
diff --git a/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/compressibleMultiRegionCourantNo.H b/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/compressibleMultiRegionCourantNo.H
index 68c3621ec1fdb4fa4b0c2d9a805f7d3afd086767..3ca2f685819312306802794b946f5048e91e6e51 100644
--- a/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/compressibleMultiRegionCourantNo.H
+++ b/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/compressibleMultiRegionCourantNo.H
@@ -7,8 +7,8 @@
             (
                 fluidRegions[regionI],
                 runTime,
-                rhof[regionI],
-                phif[regionI]
+                rhoFluid[regionI],
+                phiFluid[regionI]
             ),
             CoNum
         );
diff --git a/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/createFluidFields.H b/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/createFluidFields.H
index 314b9d028a3fb16198e0f7842a19c98c2e859e2e..1f6e50de0a3872b76c239e920f054d5e1cb54ea2 100644
--- a/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/createFluidFields.H
+++ b/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/createFluidFields.H
@@ -1,15 +1,16 @@
     // Initialise fluid field pointer lists
-    PtrList<basicThermo> thermof(fluidRegions.size());
-    PtrList<volScalarField> rhof(fluidRegions.size());
-    PtrList<volScalarField> Kf(fluidRegions.size());
-    PtrList<volVectorField> Uf(fluidRegions.size());
-    PtrList<surfaceScalarField> phif(fluidRegions.size());
-    PtrList<compressible::turbulenceModel> turb(fluidRegions.size());
-    PtrList<volScalarField> DpDtf(fluidRegions.size());
-    PtrList<volScalarField> ghf(fluidRegions.size());
-    PtrList<volScalarField> pdf(fluidRegions.size());
-
-    List<scalar> initialMassf(fluidRegions.size());
+    PtrList<basicThermo> thermoFluid(fluidRegions.size());
+    PtrList<volScalarField> rhoFluid(fluidRegions.size());
+    PtrList<volScalarField> KFluid(fluidRegions.size());
+    PtrList<volVectorField> UFluid(fluidRegions.size());
+    PtrList<surfaceScalarField> phiFluid(fluidRegions.size());
+    PtrList<compressible::turbulenceModel> turbulence(fluidRegions.size());
+    PtrList<volScalarField> DpDtFluid(fluidRegions.size());
+    PtrList<volScalarField> ghFluid(fluidRegions.size());
+    PtrList<surfaceScalarField> ghfFluid(fluidRegions.size());
+    PtrList<volScalarField> pdFluid(fluidRegions.size());
+
+    List<scalar> initialMassFluid(fluidRegions.size());
 
     dimensionedScalar pRef
     (
@@ -24,8 +25,8 @@
         Info<< "*** Reading fluid mesh thermophysical properties for region "
             << fluidRegions[i].name() << nl << endl;
 
-        Info<< "    Adding to pdf\n" << endl;
-        pdf.set
+        Info<< "    Adding to pdFluid\n" << endl;
+        pdFluid.set
         (
             i,
             new volScalarField
@@ -42,16 +43,15 @@
             )
         );
 
-        Info<< "    Adding to thermof\n" << endl;
-
-        thermof.set
+        Info<< "    Adding to thermoFluid\n" << endl;
+        thermoFluid.set
         (
             i,
             basicThermo::New(fluidRegions[i]).ptr()
         );
 
-        Info<< "    Adding to rhof\n" << endl;
-        rhof.set
+        Info<< "    Adding to rhoFluid\n" << endl;
+        rhoFluid.set
         (
             i,
             new volScalarField
@@ -64,12 +64,12 @@
                     IOobject::NO_READ,
                     IOobject::AUTO_WRITE
                 ),
-                thermof[i].rho()
+                thermoFluid[i].rho()
             )
         );
 
-        Info<< "    Adding to Kf\n" << endl;
-        Kf.set
+        Info<< "    Adding to KFluid\n" << endl;
+        KFluid.set
         (
             i,
             new volScalarField
@@ -82,12 +82,12 @@
                     IOobject::NO_READ,
                     IOobject::NO_WRITE
                 ),
-                thermof[i].Cp()*thermof[i].alpha()
+                thermoFluid[i].Cp()*thermoFluid[i].alpha()
             )
         );
 
-        Info<< "    Adding to Uf\n" << endl;
-        Uf.set
+        Info<< "    Adding to UFluid\n" << endl;
+        UFluid.set
         (
             i,
             new volVectorField
@@ -104,8 +104,8 @@
             )
         );
 
-        Info<< "    Adding to phif\n" << endl;
-        phif.set
+        Info<< "    Adding to phiFluid\n" << endl;
+        phiFluid.set
         (
             i,
             new surfaceScalarField
@@ -118,29 +118,29 @@
                     IOobject::READ_IF_PRESENT,
                     IOobject::AUTO_WRITE
                 ),
-                linearInterpolate(rhof[i]*Uf[i])
+                linearInterpolate(rhoFluid[i]*UFluid[i])
                     & fluidRegions[i].Sf()
             )
         );
 
-        Info<< "    Adding to turb\n" << endl;
-        turb.set
+        Info<< "    Adding to turbulence\n" << endl;
+        turbulence.set
         (
             i,
             autoPtr<compressible::turbulenceModel>
             (
                 compressible::turbulenceModel::New
                 (
-                    rhof[i],
-                    Uf[i],
-                    phif[i],
-                    thermof[i]
+                    rhoFluid[i],
+                    UFluid[i],
+                    phiFluid[i],
+                    thermoFluid[i]
                 )
             ).ptr()
         );
 
-        Info<< "    Adding to DpDtf\n" << endl;
-        DpDtf.set
+        Info<< "    Adding to DpDtFluid\n" << endl;
+        DpDtFluid.set
         (
             i,
             new volScalarField
@@ -150,9 +150,9 @@
                     surfaceScalarField
                     (
                         "phiU",
-                        phif[i]/fvc::interpolate(rhof[i])
+                        phiFluid[i]/fvc::interpolate(rhoFluid[i])
                     ),
-                    thermof[i].p()
+                    thermoFluid[i].p()
                 )
             )
         );
@@ -162,8 +162,8 @@
                 ("environmentalProperties");
         dimensionedVector g(environmentalProperties.lookup("g"));
 
-        Info<< "    Adding to ghf\n" << endl;
-        ghf.set
+        Info<< "    Adding to ghFluid\n" << endl;
+        ghFluid.set
         (
             i,
             new volScalarField
@@ -172,12 +172,21 @@
                  g & fluidRegions[i].C()
             )
         );
+        ghfFluid.set
+        (
+            i,
+            new surfaceScalarField
+            (
+                "ghf",
+                 g & fluidRegions[i].Cf()
+            )
+        );
 
         Info<< "    Updating p from pd\n" << endl;
-        thermof[i].p() == pdf[i] + rhof[i]*ghf[i] + pRef;
-        thermof[i].correct();
+        thermoFluid[i].p() == pdFluid[i] + rhoFluid[i]*ghFluid[i] + pRef;
+        thermoFluid[i].correct();
 
-        initialMassf[i] = fvc::domainIntegrate(rhof[i]).value();
+        initialMassFluid[i] = fvc::domainIntegrate(rhoFluid[i]).value();
     }
 
 
diff --git a/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/hEqn.H b/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/hEqn.H
index 301ceddfdb432b980642c092d15257e87f51e71e..d421649f13402f04c8f545bbeab03936d10d6aa2 100644
--- a/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/hEqn.H
+++ b/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/hEqn.H
@@ -1,9 +1,17 @@
-    solveEnthalpyEquation
+{
+    tmp<fvScalarMatrix> hEqn
     (
-        rhof[i],
-        DpDtf[i],
-        phif[i],
-        turb[i],
-        thermof[i]
+        fvm::ddt(rho, h)
+      + fvm::div(phi, h)
+      - fvm::laplacian(turb.alphaEff(), h)
+     ==
+        DpDt
     );
+    hEqn().relax();
+    hEqn().solve();
 
+    thermo.correct();
+
+    Info<< "Min/max T:" << min(thermo.T()) << ' ' << max(thermo.T())
+        << endl;
+}
diff --git a/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/initContinuityErrs.H b/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/initContinuityErrs.H
new file mode 100644
index 0000000000000000000000000000000000000000..1a7f5a3262c79506f0459fd1bedbbbe1bd086e72
--- /dev/null
+++ b/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/initContinuityErrs.H
@@ -0,0 +1 @@
+List<scalar> cumulativeContErr(fluidRegions.size(), 0.0);
diff --git a/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/pEqn.H b/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/pEqn.H
index 2b1f5fceb15b1cf8854cdedd9794142284360e61..e297989809aaa930b9c0be00e3049842869e44aa 100644
--- a/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/pEqn.H
+++ b/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/pEqn.H
@@ -1,60 +1,75 @@
 {
-    bool closedVolume = false;
+    bool closedVolume = pd.needReference();
 
-    rhof[i] = thermof[i].rho();
+    rho = thermo.rho();
 
     volScalarField rUA = 1.0/UEqn().A();
-    Uf[i] = rUA*UEqn().H();
+    surfaceScalarField rhorUAf("(rho*(1|A(U)))", fvc::interpolate(rho*rUA));
 
-    phif[i] =
-        fvc::interpolate(rhof[i])
+    U = rUA*UEqn().H();
+
+    surfaceScalarField phiU
+    (
+        fvc::interpolate(rho)
        *(
-            (fvc::interpolate(Uf[i]) & fluidRegions[i].Sf())
-          + fvc::ddtPhiCorr(rUA, rhof[i], Uf[i], phif[i])
+            (fvc::interpolate(U) & mesh.Sf())
+          + fvc::ddtPhiCorr(rUA, rho, U, phi)
         )
-      - fvc::interpolate(rhof[i]*rUA*ghf[i])
-       *fvc::snGrad(rhof[i])
-       *fluidRegions[i].magSf();
+    );
 
-    // Solve pressure difference
-#   include "pdEqn.H"
+    phi = phiU - ghf*fvc::snGrad(rho)*rhorUAf*mesh.magSf();
 
-    // Solve continuity
-#   include "rhoEqn.H"
+    for (int nonOrth=0; nonOrth<=nNonOrthCorr; nonOrth++)
+    {
+        fvScalarMatrix pdEqn
+        (
+            fvm::ddt(psi, pd)
+          + fvc::ddt(psi)*pRef
+          + fvc::ddt(psi, rho)*gh
+          + fvc::div(phi)
+          - fvm::laplacian(rho*rUA, pd)
+        );
 
-    // Update pressure field (including bc)
-    thermof[i].p() == pdf[i] + rhof[i]*ghf[i] + pRef;
-    DpDtf[i] = fvc::DDt
-    (
-        surfaceScalarField("phiU", phif[i]/fvc::interpolate(rhof[i])),
-        thermof[i].p()
-    );
+        if (corr == nCorr-1 && nonOrth == nNonOrthCorr)
+        {
+            pdEqn.solve(mesh.solver(pd.name() + "Final"));
+        }
+        else
+        {
+            pdEqn.solve(mesh.solver(pd.name()));
+        }
 
-    // Update continuity errors
-    compressibleContinuityErrors(cumulativeContErr, rhof[i], thermof[i]);
+        if (nonOrth == nNonOrthCorr)
+        {
+            phi += pdEqn.flux();
+        }
+    }
 
     // Correct velocity field
-    Uf[i] -= rUA*(fvc::grad(pdf[i]) + fvc::grad(rhof[i])*ghf[i]);
-    Uf[i].correctBoundaryConditions();
+    U += rUA*fvc::reconstruct((phi - phiU)/rhorUAf);
+    U.correctBoundaryConditions();
+
+    // Update pressure field (including bc)
+    p == pd + rho*gh + pRef;
+    DpDt = fvc::DDt(surfaceScalarField("phiU", phi/fvc::interpolate(rho)), p);
+
+    // Solve continuity
+#   include "rhoEqn.H"
+
+    // Update continuity errors
+#   include "compressibleContinuityErrors.H"
 
     // For closed-volume cases adjust the pressure and density levels
     // to obey overall mass continuity
     if (closedVolume)
     {
-        thermof[i].p() +=
-            (
-                dimensionedScalar
-                (
-                    "massIni",
-                    dimMass,
-                    initialMassf[i]
-                )
-              - fvc::domainIntegrate(thermof[i].psi()*thermof[i].p())
-            )/fvc::domainIntegrate(thermof[i].psi());
-        pdf[i] == thermof[i].p() - (rhof[i]*ghf[i] + pRef);
-        rhof[i] = thermof[i].rho();
+        p += (massIni - fvc::domainIntegrate(psi*p))/fvc::domainIntegrate(psi);
+        rho = thermo.rho();
     }
 
     // Update thermal conductivity
-    Kf[i] = thermof[i].Cp()*turb[i].alphaEff();
+    K = thermoFluid[i].Cp()*turb.alphaEff();
+
+    // Update pd (including bc)
+    pd == p - (rho*gh + pRef);
 }
diff --git a/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/pdEqn.H b/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/pdEqn.H
deleted file mode 100644
index a3938432565cf675aa3dee0caee3a19eaafbdb14..0000000000000000000000000000000000000000
--- a/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/pdEqn.H
+++ /dev/null
@@ -1,14 +0,0 @@
-    solvePressureDifferenceEquation
-    (
-        corr,
-        nCorr,
-        nNonOrthCorr,
-        closedVolume,
-        pdf[i],
-        pRef,
-        rhof[i],
-        thermof[i].psi(),
-        rUA,
-        ghf[i],
-        phif[i]
-    );
diff --git a/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/rhoEqn.H b/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/rhoEqn.H
index a7e2a98c4aa5251ea9048f47d156dbbe4f628f3e..a6b0ac9fe1c0c27d1f2479f27ab3715c87537cd9 100644
--- a/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/rhoEqn.H
+++ b/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/rhoEqn.H
@@ -1 +1 @@
-    solveContinuityEquation(rhof[i], phif[i]);
+    solve(fvm::ddt(rho) + fvc::div(phi));
diff --git a/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/setInitialDeltaT.H b/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/setInitialDeltaT.H
deleted file mode 100644
index 161eb742e76f2e7f798ae59cbaf6c50aff0b68da..0000000000000000000000000000000000000000
--- a/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/setInitialDeltaT.H
+++ /dev/null
@@ -1,15 +0,0 @@
-    if (adjustTimeStep)
-    {
-        if (CoNum > SMALL)
-        {
-            runTime.setDeltaT
-            (
-                min
-                (
-                    maxCo*runTime.deltaT().value()/CoNum,
-                    maxDeltaT
-                )
-            );
-        }
-    }
-
diff --git a/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/setRegionFluidFields.H b/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/setRegionFluidFields.H
new file mode 100644
index 0000000000000000000000000000000000000000..bc4590a4286e71d0db721d6f5db9dde70345f810
--- /dev/null
+++ b/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/setRegionFluidFields.H
@@ -0,0 +1,18 @@
+    const fvMesh& mesh = fluidRegions[i];
+
+    basicThermo& thermo = thermoFluid[i];
+    volScalarField& rho = rhoFluid[i];
+    volScalarField& K = KFluid[i];
+    volVectorField& U = UFluid[i];
+    surfaceScalarField phi = phiFluid[i];
+    compressible::turbulenceModel& turb = turbulence[i];
+    volScalarField& DpDt = DpDtFluid[i];
+    const volScalarField& gh = ghFluid[i];
+    const surfaceScalarField& ghf = ghfFluid[i];
+    volScalarField& pd = pdFluid[i];
+
+    volScalarField& p = thermo.p();
+    const volScalarField& psi = thermo.psi();
+    volScalarField& h = thermo.h();
+
+    const dimensionedScalar massIni("massIni", dimMass, initialMassFluid[i]);
diff --git a/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/solveFluid.H b/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/solveFluid.H
index e24771256f48c6232a12e05d30438e3a42f3c3e0..19ec50cac253986322e9155df1c2bcc0d7632c4a 100644
--- a/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/solveFluid.H
+++ b/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/solveFluid.H
@@ -12,4 +12,4 @@
     #       include "pEqn.H"
         }
     }
-    turb[i].correct();
+    turb.correct();
diff --git a/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/solvePressureDifferenceEquation.C b/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/solvePressureDifferenceEquation.C
deleted file mode 100644
index 6d8843ab421d9157fd6c13a4e059ac8dfa0dd398..0000000000000000000000000000000000000000
--- a/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/solvePressureDifferenceEquation.C
+++ /dev/null
@@ -1,73 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
-     \\/     M anipulation  |
--------------------------------------------------------------------------------
-License
-    This file is part of OpenFOAM.
-
-    OpenFOAM is free software; you can redistribute it and/or modify it
-    under the terms of the GNU General Public License as published by the
-    Free Software Foundation; either version 2 of the License, or (at your
-    option) any later version.
-
-    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
-    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-    for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with OpenFOAM; if not, write to the Free Software Foundation,
-    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-Description
-    Solve pressure difference equation
-
-\*---------------------------------------------------------------------------*/
-
-void solvePressureDifferenceEquation
-(
-    const label corr,
-    const label nCorr,
-    const label nNonOrthCorr,
-    bool& closedVolume,
-    volScalarField& pd,
-    const dimensionedScalar& pRef,
-    const volScalarField& rho,
-    const volScalarField& psi,
-    const volScalarField& rUA,
-    const volScalarField& gh,
-    surfaceScalarField& phi
-)
-{
-    closedVolume = pd.needReference();
-
-    for (int nonOrth=0; nonOrth<=nNonOrthCorr; nonOrth++)
-    {
-        fvScalarMatrix pdEqn
-        (
-            fvm::ddt(psi, pd)
-          + fvc::ddt(psi)*pRef
-          + fvc::ddt(psi, rho)*gh
-          + fvc::div(phi)
-          - fvm::laplacian(rho*rUA, pd)
-        );
-
-        //pdEqn.solve();
-        if (corr == nCorr-1 && nonOrth == nNonOrthCorr)
-        {
-            pdEqn.solve(pd.mesh().solver(pd.name() + "Final"));
-        }
-        else
-        {
-            pdEqn.solve(pd.mesh().solver(pd.name()));
-        }
-
-        if (nonOrth == nNonOrthCorr)
-        {
-            phi += pdEqn.flux();
-        }
-    }
-}
diff --git a/applications/solvers/heatTransfer/chtMultiRegionFoam/solid/setRegionSolidFields.H b/applications/solvers/heatTransfer/chtMultiRegionFoam/solid/setRegionSolidFields.H
new file mode 100644
index 0000000000000000000000000000000000000000..04c90d2c4c108f479145e86e64c980f7d6296cba
--- /dev/null
+++ b/applications/solvers/heatTransfer/chtMultiRegionFoam/solid/setRegionSolidFields.H
@@ -0,0 +1,6 @@
+//    fvMesh& mesh = solidRegions[i];
+
+    volScalarField& rho = rhos[i];
+    volScalarField& cp = cps[i];
+    volScalarField& K = Ks[i];
+    volScalarField& T = Ts[i];
diff --git a/applications/solvers/heatTransfer/chtMultiRegionFoam/solid/solveSolid.H b/applications/solvers/heatTransfer/chtMultiRegionFoam/solid/solveSolid.H
index 790d4ec9348d2b855f23a2dcb5ea33cf2094b620..5fa731824f375adfeb3e2175f280de55da5cd4b2 100644
--- a/applications/solvers/heatTransfer/chtMultiRegionFoam/solid/solveSolid.H
+++ b/applications/solvers/heatTransfer/chtMultiRegionFoam/solid/solveSolid.H
@@ -3,10 +3,9 @@
     {
         solve
         (
-            fvm::ddt(rhosCps[i], Ts[i]) - fvm::laplacian(Ks[i], Ts[i])
+            fvm::ddt(rho*cp, T) - fvm::laplacian(K, T)
         );
     }
 
-    Info<< "Min/max T:" << min(Ts[i]) << ' ' << max(Ts[i])
-        << endl;
+    Info<< "Min/max T:" << min(T) << ' ' << max(T) << endl;
 }
diff --git a/applications/solvers/multiphase/interFoam/alphaEqn.H b/applications/solvers/multiphase/interFoam/alphaEqn.H
index 3bf24a845efadf9f66af09ba27e379859a7b3c14..0b2fb4ebf8cd36525b52507fd48b245293b0ddbc 100644
--- a/applications/solvers/multiphase/interFoam/alphaEqn.H
+++ b/applications/solvers/multiphase/interFoam/alphaEqn.H
@@ -6,7 +6,7 @@
     phic = min(interface.cAlpha()*phic, max(phic));
     surfaceScalarField phir = phic*interface.nHatf();
 
-    for (int gCorr=0; gCorr<nAlphaCorr; gCorr++)
+    for (int aCorr=0; aCorr<nAlphaCorr; aCorr++)
     {
         surfaceScalarField phiAlpha =
             fvc::flux
diff --git a/applications/solvers/multiphase/twoPhaseEulerFoam/phaseModel/phaseModel/phaseModel.C b/applications/solvers/multiphase/twoPhaseEulerFoam/phaseModel/phaseModel/phaseModel.C
index d1e7e5fa4a14e7c64993d38df430ecefb6078dc2..5442ad17ba79aa800345c64d4a0fdd9cbe82cd13 100644
--- a/applications/solvers/multiphase/twoPhaseEulerFoam/phaseModel/phaseModel/phaseModel.C
+++ b/applications/solvers/multiphase/twoPhaseEulerFoam/phaseModel/phaseModel/phaseModel.C
@@ -81,17 +81,20 @@ Foam::phaseModel::phaseModel
     {
         Info<< "Reading face flux field " << phiName << endl;
 
-        phiPtr_ = new surfaceScalarField
+        phiPtr_.reset
         (
-            IOobject
+            new surfaceScalarField
             (
-                phiName,
-                mesh.time().timeName(),
-                mesh,
-                IOobject::MUST_READ,
-                IOobject::AUTO_WRITE
-            ),
-            mesh
+                IOobject
+                (
+                    phiName,
+                    mesh.time().timeName(),
+                    mesh,
+                    IOobject::MUST_READ,
+                    IOobject::AUTO_WRITE
+                ),
+                mesh
+            )
         );
     }
     else
@@ -112,18 +115,21 @@ Foam::phaseModel::phaseModel
             }
         }
 
-        phiPtr_ = new surfaceScalarField
+        phiPtr_.reset
         (
-            IOobject
+            new surfaceScalarField
             (
-                phiName,
-                mesh.time().timeName(),
-                mesh,
-                IOobject::NO_READ,
-                IOobject::AUTO_WRITE
-            ),
-            fvc::interpolate(U_) & mesh.Sf(),
-            phiTypes
+                IOobject
+                (
+                    phiName,
+                    mesh.time().timeName(),
+                    mesh,
+                    IOobject::NO_READ,
+                    IOobject::AUTO_WRITE
+                ),
+                fvc::interpolate(U_) & mesh.Sf(),
+                phiTypes
+            )
         );
     }
 }
diff --git a/applications/solvers/multiphase/twoPhaseEulerFoam/phaseModel/phaseModel/phaseModel.H b/applications/solvers/multiphase/twoPhaseEulerFoam/phaseModel/phaseModel/phaseModel.H
index 648950545a613cfe64dc06f84b8c69bbfd38b916..26ab9f9d7e81f457273c5104600d9da195a7232d 100644
--- a/applications/solvers/multiphase/twoPhaseEulerFoam/phaseModel/phaseModel/phaseModel.H
+++ b/applications/solvers/multiphase/twoPhaseEulerFoam/phaseModel/phaseModel/phaseModel.H
@@ -69,7 +69,7 @@ class phaseModel
         volVectorField U_;
 
         //- Fluxes
-        surfaceScalarField* phiPtr_;
+        autoPtr<surfaceScalarField> phiPtr_;
 
 
 public:
@@ -133,12 +133,12 @@ public:
 
         const surfaceScalarField& phi() const
         {
-            return *phiPtr_;
+            return phiPtr_();
         }
 
         surfaceScalarField& phi()
         {
-            return *phiPtr_;
+            return phiPtr_();
         }
 };
 
diff --git a/applications/test/HashSet/hashSetTest.C b/applications/test/HashSet/hashSetTest.C
index 9625b2e0dc61bc5053441729faecfbe18ea8c7d3..21e1276604518f9b9adf4905305ed091702ac48e 100644
--- a/applications/test/HashSet/hashSetTest.C
+++ b/applications/test/HashSet/hashSetTest.C
@@ -111,6 +111,33 @@ int main(int argc, char *argv[])
     Info<< "setD : " << setD << endl;
     Info<< "setB ^ setC ^ setD : " << (setB ^ setC ^ setD) << endl;
 
+    // test operator[]
+
+    Info<< "setD : " << setD << endl;
+    if (setD[0])
+    {
+        Info<< "setD has 0" << endl;
+    }
+    else
+    {
+        Info<< "setD has no 0" << endl;
+    }
+
+
+    if (setD[11])
+    {
+        Info<< "setD has 11" << endl;
+    }
+    else
+    {
+        Info<< "setD has no 0" << endl;
+    }
+
+    Info<< "setD : " << setD << endl;
+
+    // this doesn't work (yet?)
+    // setD[12] = true;
+
     return 0;
 }
 
diff --git a/applications/test/PackedList/PackedListTest.C b/applications/test/PackedList/PackedListTest.C
index b00c703a37b60986727350edac1b83c992af9316..f1f58f3abcad7d5450102a969c996664934c448f 100644
--- a/applications/test/PackedList/PackedListTest.C
+++ b/applications/test/PackedList/PackedListTest.C
@@ -38,7 +38,6 @@ using namespace Foam;
 
 int main(int argc, char *argv[])
 {
-    bool changed;
     Info<< "PackedList max_bits() = " << PackedList<0>::max_bits() << nl;
 
     Info<< "\ntest allocation with value\n";
@@ -46,11 +45,50 @@ int main(int argc, char *argv[])
     list1.print(Info);
 
     Info<< "\ntest assign uniform value\n";
-    list1 = 2;
+    list1 = 3;
+    list1.print(Info);
+
+    Info<< "\ntest assign uniform value (with overflow)\n";
+    list1 = -1;
+    list1.print(Info);
+
+    Info<< "\ntest assign between references\n";
+    list1[2] = 3;
+    list1[4] = list1[2];
+    list1.print(Info);
+
+    Info<< "\ntest assign between references, with chaining\n";
+    list1[4] = list1[2] = 1;
+    list1.print(Info);
+
+    {
+        const PackedList<3>& constLst = list1;
+        Info<< "\ntest operator[] const with out-of-range index\n";
+        constLst.print(Info);
+        if (!constLst[20])
+        {
+            Info<< "[20] is false (expected) list size should be unchanged (const)\n";
+        }
+        constLst.print(Info);
+
+        Info<< "\ntest operator[] non-const with out-of-range index\n";
+        if (!list1[20])
+        {
+            Info<< "[20] is false (expected) but list was resized?? (non-const)\n";
+        }
+        list1.print(Info);
+    }
+
+
+    Info<< "\ntest operator[] with out-of-range index\n";
+    if (!list1[20])
+    {
+        Info<< "[20] is false, as expected\n";
+    }
     list1.print(Info);
 
     Info<< "\ntest resize with value (without reallocation)\n";
-    list1.resize(6, 3);
+    list1.resize(8, list1.max_value());
     list1.print(Info);
 
     Info<< "\ntest set() function\n";
@@ -96,7 +134,7 @@ int main(int argc, char *argv[])
     list1.print(Info);
 
     Info<< "\ntest setCapacity() operation\n";
-    list1.setCapacity(30);
+    list1.setCapacity(100);
     list1.print(Info);
 
     Info<< "\ntest operator[] assignment\n";
@@ -108,7 +146,15 @@ int main(int argc, char *argv[])
     list1.print(Info);
 
     Info<< "\ntest setCapacity smaller\n";
-    list1.setCapacity(32);
+    list1.setCapacity(24);
+    list1.print(Info);
+
+    Info<< "\ntest resize much smaller\n";
+    list1.resize(150);
+    list1.print(Info);
+
+    Info<< "\ntest trim\n";
+    list1.trim();
     list1.print(Info);
 
     // add in some misc values
@@ -118,37 +164,54 @@ int main(int argc, char *argv[])
 
     Info<< "\ntest iterator\n";
     PackedList<3>::iterator iter = list1.begin();
-    Info<< "iterator:" << iter() << "\n";
+    Info<< "begin():";
     iter.print(Info) << "\n";
 
-    Info<< "\ntest iterator operator=\n";
-    changed = (iter = 5);
-
     Info<< "iterator:" << iter() << "\n";
-    Info<< "changed:" << changed << "\n";
-    changed = (iter = 5);
-    Info<< "changed:" << changed << "\n";
+    iter() = 5;
+    iter.print(Info);
     list1.print(Info);
 
+    iter = list1[31];
+    Info<< "iterator:" << iter() << "\n";
+    iter.print(Info);
+
+
     Info<< "\ntest get() method\n";
-    Info<< "get(10):" << list1.get(10)
-        << " and list[10]:" << unsigned(list1[10]) << "\n";
+    Info<< "get(10):" << list1.get(10) << " and list[10]:" << list1[10] << "\n";
     list1.print(Info);
 
     Info<< "\ntest iterator indexing\n";
-    Info<< "end() ";
-    list1.end().print(Info) << "\n";
+    Info<< "cend() ";
+    list1.cend().print(Info) << "\n";
 
-    for (iter = list1[31]; iter != list1.end(); ++iter)
     {
-        iter.print(Info);
+        Info<< "\ntest assignment of iterator\n";
+        list1.print(Info);
+        PackedList<3>::iterator cit = list1[25];
+        cit.print(Info);
+        list1.end().print(Info);
     }
 
-    Info<< "\ntest operator[] auto-vivify\n";
-    const unsigned int val = list1[45];
 
-    Info<< "list[45]:" << val << "\n";
-    list1.print(Info);
+    for
+    (
+        PackedList<3>::iterator cit = list1[5];
+        cit != list1.end();
+        ++cit
+    )
+    {
+        cit.print(Info);
+    }
+
+//     Info<< "\ntest operator[] auto-vivify\n";
+//     const unsigned int val = list1[45];
+//
+//     Info<< "list[45]:" << val << "\n";
+//     list1[45] = list1.max_value();
+//     Info<< "list[45]:" << list1[45] << "\n";
+//     list1[49] = list1.max_value();
+//     list1.print(Info);
 
 
     Info<< "\ntest copy constructor + append\n";
@@ -161,8 +224,15 @@ int main(int argc, char *argv[])
 
     Info<< "\ntest pattern that fills all bits\n";
     PackedList<4> list3(8, 8);
-    list3[list3.size()-2] = 0;
-    list3[list3.size()-1] = list3.max_value();
+
+    label pos = list3.size() - 1;
+
+    list3[pos--] = list3.max_value();
+    list3[pos--] = 0;
+    list3[pos--] = list3.max_value();
+    list3.print(Info);
+
+    Info<< "removed final value: " << list3.remove() << endl;
     list3.print(Info);
 
     Info<< "\n\nDone.\n";
diff --git a/applications/test/PackedList2/Make/files b/applications/test/PackedList2/Make/files
new file mode 100644
index 0000000000000000000000000000000000000000..bb1f3085fadb26a1f3d158d599b523f9b7be10e6
--- /dev/null
+++ b/applications/test/PackedList2/Make/files
@@ -0,0 +1,3 @@
+PackedListTest2.C
+
+EXE = $(FOAM_USER_APPBIN)/PackedListTest2
diff --git a/applications/test/PackedList2/Make/options b/applications/test/PackedList2/Make/options
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/applications/test/PackedList2/PackedListTest2.C b/applications/test/PackedList2/PackedListTest2.C
new file mode 100644
index 0000000000000000000000000000000000000000..22282058ac741a50d2a3366083a9091f55012153
--- /dev/null
+++ b/applications/test/PackedList2/PackedListTest2.C
@@ -0,0 +1,348 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software; you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by the
+    Free Software Foundation; either version 2 of the License, or (at your
+    option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM; if not, write to the Free Software Foundation,
+    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+Application
+
+Description
+
+\*---------------------------------------------------------------------------*/
+
+#include "argList.H"
+#include "boolList.H"
+#include "PackedBoolList.H"
+#include "HashSet.H"
+#include "cpuTime.H"
+#include <vector>
+
+using namespace Foam;
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+
+// Main program:
+
+int main(int argc, char *argv[])
+{
+    const label n = 1000000;
+    const label nIters = 1000;
+
+    unsigned int sum = 0;
+
+    PackedBoolList packed(n, 1);
+    boolList unpacked(n, true);
+    std::vector<bool> stlVector(n, true);
+
+    labelHashSet emptyHash;
+    labelHashSet fullHash(1000);
+    for(label i = 0; i < n; i++)
+    {
+        fullHash.insert(i);
+    }
+
+    cpuTime timer;
+
+    for (label iter = 0; iter < nIters; ++iter)
+    {
+        packed.resize(40);
+        packed.shrink();
+        packed.resize(n, 1);
+    }
+    Info<< "resize/shrink/resize:" << timer.cpuTimeIncrement() << " s\n\n";
+
+    // set every other bit on:
+    Info<< "set every other bit on and count\n";
+    packed.storage() = 0xAAAAAAAAu;
+
+    // Count packed
+    sum = 0;
+    for (label iter = 0; iter < nIters; ++iter)
+    {
+        forAll(packed, i)
+        {
+            sum += packed[i];
+        }
+    }
+    Info<< "Counting brute-force:" << timer.cpuTimeIncrement()
+        << " s" << endl;
+    Info<< "  sum " << sum << endl;
+
+
+    // Count packed
+    sum = 0;
+    for (label iter = 0; iter < nIters; ++iter)
+    {
+        sum += packed.count();
+    }
+    Info<< "Counting via count():" << timer.cpuTimeIncrement()
+        << " s" << endl;
+    Info<< "  sum " << sum << endl;
+
+
+    // Dummy addition
+    sum = 0;
+    for (label iter = 0; iter < nIters; ++iter)
+    {
+        forAll(unpacked, i)
+        {
+            sum += i + 1;
+        }
+    }
+    Info<< "Dummy loop:" << timer.cpuTimeIncrement() << " s" << endl;
+    Info<< "  sum " << sum << endl;
+
+    //
+    // Read
+    //
+
+    // Read stl
+    sum = 0;
+    for (label iter = 0; iter < nIters; ++iter)
+    {
+        for(unsigned int i = 0; i < stlVector.size(); i++)
+        {
+            sum += stlVector[i];
+        }
+    }
+    Info<< "Reading stl:" << timer.cpuTimeIncrement() << " s" << endl;
+    Info<< "  sum " << sum << endl;
+
+
+    // Read unpacked
+    sum = 0;
+    for (label iter = 0; iter < nIters; ++iter)
+    {
+        forAll(unpacked, i)
+        {
+            sum += unpacked[i];
+        }
+    }
+    Info<< "Reading unpacked:" << timer.cpuTimeIncrement() << " s" << endl;
+    Info<< "  sum " << sum << endl;
+
+
+    // Read packed
+    sum = 0;
+    for (label iter = 0; iter < nIters; ++iter)
+    {
+        forAll(packed, i)
+        {
+            sum += packed.get(i);
+        }
+    }
+    Info<< "Reading packed using get:" << timer.cpuTimeIncrement()
+        << " s" << endl;
+    Info<< "  sum " << sum << endl;
+
+
+    // Read packed
+    sum = 0;
+    for (label iter = 0; iter < nIters; ++iter)
+    {
+        forAll(packed, i)
+        {
+            sum += packed[i];
+        }
+    }
+    Info<< "Reading packed using reference:" << timer.cpuTimeIncrement()
+        << " s" << endl;
+    Info<< "  sum " << sum << endl;
+
+
+    // Read via iterator
+    sum = 0;
+    for (label iter = 0; iter < nIters; ++iter)
+    {
+        for
+        (
+            PackedBoolList::iterator it = packed.begin();
+            it != packed.end();
+            ++it
+        )
+        {
+            sum += it;
+        }
+    }
+    Info<< "Reading packed using iterator:" << timer.cpuTimeIncrement()
+        << " s" << endl;
+    Info<< "  sum " << sum << endl;
+
+
+    // Read via iterator
+    sum = 0;
+    for (label iter = 0; iter < nIters; ++iter)
+    {
+        for
+        (
+            PackedBoolList::const_iterator cit = packed.cbegin();
+            cit != packed.cend();
+            ++cit
+        )
+        {
+            sum += cit();
+        }
+    }
+    Info<< "Reading packed using const_iterator():" << timer.cpuTimeIncrement()
+        << " s" << endl;
+    Info<< "  sum " << sum << endl;
+
+
+    // Read empty hash
+    sum = 0;
+    for (label iter = 0; iter < nIters; ++iter)
+    {
+        forAll(unpacked, i)
+        {
+            sum += emptyHash.found(i);
+        }
+    }
+    Info<< "Reading empty labelHashSet:" << timer.cpuTimeIncrement()
+        << " s" << endl;
+    Info<< "  sum " << sum << endl;
+
+
+    // Read full hash
+    sum = 0;
+    for (label iter = 0; iter < nIters; ++iter)
+    {
+        forAll(unpacked, i)
+        {
+            sum += fullHash.found(i);
+        }
+    }
+    Info<< "Reading full labelHashSet:" << timer.cpuTimeIncrement()
+        << " s" << endl;
+    Info<< "  sum " << sum << endl;
+
+
+    //
+    // Write
+    //
+
+    // Write stl
+    for (label iter = 0; iter < nIters; ++iter)
+    {
+        for (unsigned int i = 0; i < stlVector.size(); i++)
+        {
+            stlVector[i] = true;
+        }
+    }
+    Info<< "Writing stl:" << timer.cpuTimeIncrement() << " s" << endl;
+
+    // Write unpacked
+    for (label iter = 0; iter < nIters; ++iter)
+    {
+        forAll(unpacked, i)
+        {
+            unpacked[i] = true;
+        }
+    }
+    Info<< "Writing unpacked:" << timer.cpuTimeIncrement() << " s" << endl;
+
+
+    // Write packed
+    for (label iter = 0; iter < nIters; ++iter)
+    {
+        forAll(packed, i)
+        {
+            packed[i] = 1;
+        }
+    }
+    Info<< "Writing packed using reference:" << timer.cpuTimeIncrement()
+        << " s" << endl;
+
+
+    // Write packed
+    for (label iter = 0; iter < nIters; ++iter)
+    {
+        forAll(packed, i)
+        {
+            packed.set(i, 1);
+        }
+    }
+    Info<< "Writing packed using set:" << timer.cpuTimeIncrement()
+        << " s" << endl;
+
+
+    // Write packed
+    for (label iter = 0; iter < nIters; ++iter)
+    {
+        for
+        (
+            PackedBoolList::iterator it = packed.begin();
+            it != packed.end();
+            ++it
+        )
+        {
+            it() = 1;
+        }
+    }
+    Info<< "Writing packed using iterator:" << timer.cpuTimeIncrement()
+        << " s" << endl;
+
+
+    // Write packed
+    for (label iter = 0; iter < nIters; ++iter)
+    {
+        packed = 0;
+    }
+    Info<< "Writing packed uniform 0:" << timer.cpuTimeIncrement()
+        << " s" << endl;
+
+
+    // Write packed
+    for (label iter = 0; iter < nIters; ++iter)
+    {
+        packed = 1;
+    }
+    Info<< "Writing packed uniform 1:" << timer.cpuTimeIncrement()
+        << " s" << endl;
+
+
+    PackedList<3> oddPacked(n, 3);
+
+    // Write packed
+    for (label iter = 0; iter < nIters; ++iter)
+    {
+        packed = 0;
+    }
+    Info<< "Writing packed<3> uniform 0:" << timer.cpuTimeIncrement()
+        << " s" << endl;
+
+
+    // Write packed
+    for (label iter = 0; iter < nIters; ++iter)
+    {
+        packed = 1;
+    }
+    Info<< "Writing packed<3> uniform 1:" << timer.cpuTimeIncrement()
+        << " s" << endl;
+
+
+    Info << "End\n" << endl;
+
+    return 0;
+}
+
+
+// ************************************************************************* //
diff --git a/applications/test/fileName/fileNameTest.C b/applications/test/fileName/fileNameTest.C
index c48e4ba2fc39cec284063ceac214158c9c64e996..f5a4a93542ac7a1cac740a6aab5e3053ad9af84c 100644
--- a/applications/test/fileName/fileNameTest.C
+++ b/applications/test/fileName/fileNameTest.C
@@ -31,6 +31,7 @@ Description
 \*---------------------------------------------------------------------------*/
 
 #include "fileName.H"
+#include "SubList.H"
 #include "IOstreams.H"
 #include "OSspecific.H"
 
@@ -50,19 +51,55 @@ int main()
 
     fileName pathName(wrdList);
 
-    Info<< "pathName = " << pathName << endl;
-    Info<< "pathName.name() = " << pathName.name() << endl;
-    Info<< "pathName.path() = " << pathName.path() << endl;
-    Info<< "pathName.ext() = " << pathName.ext() << endl;
+    Info<< "pathName = " << pathName << nl
+        << "pathName.name() = " << pathName.name() << nl
+        << "pathName.path() = " << pathName.path() << nl
+        << "pathName.ext()  = " << pathName.ext() << endl;
 
-    Info<< "pathName.components() = " << pathName.components() << endl;
-    Info<< "pathName.component(2) = " << pathName.component(2) << endl;
+    Info<< "pathName.components() = " << pathName.components() << nl
+        << "pathName.component(2) = " << pathName.component(2) << nl
+        << endl;
 
+    // try with different combination
+    for (label start = 0; start < wrdList.size(); ++start)
+    {
+        fileName instance, local;
+        word name;
+
+        fileName path(SubList<word>(wrdList, wrdList.size()-start, start));
+        fileName path2 = "." / path;
+
+        path.IOobjectComponents
+        (
+            instance,
+            local,
+            name
+        );
+
+        Info<< "IOobjectComponents for " << path << nl
+            << "  instance = " << instance << nl
+            << "  local    = " << local << nl
+            << "  name     = " << name << endl;
+
+        path2.IOobjectComponents
+        (
+            instance,
+            local,
+            name
+        );
+
+        Info<< "IOobjectComponents for " << path2 << nl
+            << "  instance = " << instance << nl
+            << "  local    = " << local << nl
+            << "  name     = " << name << endl;
+
+    }
 
     // test findEtcFile
     Info<< "\n\nfindEtcFile tests:" << nl
         << " controlDict => " << findEtcFile("controlDict") << nl
         << " badName => " << findEtcFile("badName") << endl;
+
     Info<< "This should emit a fatal error:" << endl;
     Info<< " badName(die) => " << findEtcFile("badName", true) << nl
         << endl;
diff --git a/applications/utilities/mesh/advanced/collapseEdges/collapseEdges.C b/applications/utilities/mesh/advanced/collapseEdges/collapseEdges.C
index c92418dc803e98f119ed83d90801a0074dd8a619..a780d8aecb09804c771eec42d4c469da73ce993c 100644
--- a/applications/utilities/mesh/advanced/collapseEdges/collapseEdges.C
+++ b/applications/utilities/mesh/advanced/collapseEdges/collapseEdges.C
@@ -464,6 +464,7 @@ int main(int argc, char *argv[])
 #   include "createTime.H"
     runTime.functionObjects().off();
 #   include "createPolyMesh.H"
+    const word oldInstance = mesh.pointsInstance();
 
     scalar minLen(readScalar(IStringStream(args.additionalArgs()[0])()));
     scalar angle(readScalar(IStringStream(args.additionalArgs()[1])()));
@@ -587,8 +588,12 @@ int main(int argc, char *argv[])
         {
             runTime++;
         }
+        else
+        {
+            mesh.setInstance(oldInstance);
+        }
 
-        Info << "Writing collapsed mesh to time " << runTime.value() << endl;
+        Info<< "Writing collapsed mesh to time " << runTime.timeName() << endl;
 
         mesh.write();
     }
diff --git a/applications/utilities/mesh/advanced/combinePatchFaces/combinePatchFaces.C b/applications/utilities/mesh/advanced/combinePatchFaces/combinePatchFaces.C
index c4e47890d5eb95949d96c1ee2b9af86d134fad8c..17092d5a6ec8ddfd460d68b5a8f12e0211782ea9 100644
--- a/applications/utilities/mesh/advanced/combinePatchFaces/combinePatchFaces.C
+++ b/applications/utilities/mesh/advanced/combinePatchFaces/combinePatchFaces.C
@@ -441,6 +441,7 @@ int main(int argc, char *argv[])
 #   include "createTime.H"
     runTime.functionObjects().off();
 #   include "createPolyMesh.H"
+    const word oldInstance = mesh.pointsInstance();
 
     scalar featureAngle(readScalar(IStringStream(args.additionalArgs()[0])()));
 
@@ -502,6 +503,11 @@ int main(int argc, char *argv[])
 
     if (nChanged > 0)
     {
+        if (overwrite)
+        {
+            mesh.setInstance(oldInstance);
+        }
+
         Info<< "Writing morphed mesh to time " << runTime.timeName() << endl;
 
         mesh.write();
diff --git a/applications/utilities/mesh/advanced/modifyMesh/modifyMesh.C b/applications/utilities/mesh/advanced/modifyMesh/modifyMesh.C
index 67fdc0807e5975a624666afc16f8523afcaac306..0011d750e5613785d69f54d2a8dff9944b596b23 100644
--- a/applications/utilities/mesh/advanced/modifyMesh/modifyMesh.C
+++ b/applications/utilities/mesh/advanced/modifyMesh/modifyMesh.C
@@ -334,6 +334,7 @@ int main(int argc, char *argv[])
 #   include "createTime.H"
     runTime.functionObjects().off();
 #   include "createPolyMesh.H"
+    const word oldInstance = mesh.pointsInstance();
 
     bool overwrite = args.options().found("overwrite");
 
@@ -553,9 +554,13 @@ int main(int argc, char *argv[])
         {
             runTime++;
         }
+        else
+        {
+            mesh.setInstance(oldInstance);
+        }
 
         // Write resulting mesh
-        Info << "Writing modified mesh to time " << runTime.value() << endl;
+        Info << "Writing modified mesh to time " << runTime.timeName() << endl;
         mesh.write();
     }
     else if (edgeToPos.size())
@@ -602,9 +607,13 @@ int main(int argc, char *argv[])
         {
             runTime++;
         }
+        else
+        {
+            mesh.setInstance(oldInstance);
+        }
 
         // Write resulting mesh
-        Info << "Writing modified mesh to time " << runTime.value() << endl;
+        Info << "Writing modified mesh to time " << runTime.timeName() << endl;
         mesh.write();
     }
     else
@@ -641,9 +650,13 @@ int main(int argc, char *argv[])
         {
             runTime++;
         }
+        else
+        {
+            mesh.setInstance(oldInstance);
+        }
 
         // Write resulting mesh
-        Info << "Writing modified mesh to time " << runTime.value() << endl;
+        Info << "Writing modified mesh to time " << runTime.timeName() << endl;
         mesh.write();
     }
 
diff --git a/applications/utilities/mesh/advanced/refineHexMesh/refineHexMesh.C b/applications/utilities/mesh/advanced/refineHexMesh/refineHexMesh.C
index 4a45f214f6e4911c91fdd1621f986d692c7db216..364aed2e16c4196938e76e0bd9839f67899f470f 100644
--- a/applications/utilities/mesh/advanced/refineHexMesh/refineHexMesh.C
+++ b/applications/utilities/mesh/advanced/refineHexMesh/refineHexMesh.C
@@ -58,6 +58,8 @@ int main(int argc, char *argv[])
 #   include "createTime.H"
     runTime.functionObjects().off();
 #   include "createMesh.H"
+    const word oldInstance = mesh.pointsInstance();
+
     pointMesh pMesh(mesh);
 
     word cellSetName(args.args()[1]);
@@ -177,6 +179,10 @@ int main(int argc, char *argv[])
     Pout<< "Refined from " << returnReduce(map().nOldCells(), sumOp<label>())
         << " to " << mesh.globalData().nTotalCells() << " cells." << nl << endl;
 
+    if (overwrite)
+    {
+        mesh.setInstance(oldInstance);
+    }
     Info<< "Writing mesh to " << runTime.timeName() << endl;
 
     mesh.write();
diff --git a/applications/utilities/mesh/advanced/refineWallLayer/refineWallLayer.C b/applications/utilities/mesh/advanced/refineWallLayer/refineWallLayer.C
index 672cf3f6baf2e48aba495f0e13d15f8b8cb07b33..9c608366aae814d6e48c8c331ad76581b25a7ede 100644
--- a/applications/utilities/mesh/advanced/refineWallLayer/refineWallLayer.C
+++ b/applications/utilities/mesh/advanced/refineWallLayer/refineWallLayer.C
@@ -56,6 +56,7 @@ int main(int argc, char *argv[])
 #   include "createTime.H"
     runTime.functionObjects().off();
 #   include "createPolyMesh.H"
+    const word oldInstance = mesh.pointsInstance();
 
     word patchName(args.additionalArgs()[0]);
 
@@ -226,8 +227,13 @@ int main(int argc, char *argv[])
     // Update stored labels on meshCutter.
     cutter.updateMesh(morphMap());
 
+    if (overwrite)
+    {
+        mesh.setInstance(oldInstance);
+    }
+
     // Write resulting mesh
-    Info << "Writing refined morphMesh to time " << runTime.value() << endl;
+    Info << "Writing refined morphMesh to time " << runTime.timeName() << endl;
 
     mesh.write();
 
diff --git a/applications/utilities/mesh/advanced/removeFaces/removeFaces.C b/applications/utilities/mesh/advanced/removeFaces/removeFaces.C
index b5af23a51623e8b21943fcbb985ead0090e79ca2..26ee404fe8d79809c9519d27d52b825d3e45fe28 100644
--- a/applications/utilities/mesh/advanced/removeFaces/removeFaces.C
+++ b/applications/utilities/mesh/advanced/removeFaces/removeFaces.C
@@ -55,6 +55,7 @@ int main(int argc, char *argv[])
 #   include "createTime.H"
     runTime.functionObjects().off();
 #   include "createMesh.H"
+    const word oldInstance = mesh.pointsInstance();
 
     bool overwrite = args.options().found("overwrite");
 
@@ -167,6 +168,10 @@ int main(int argc, char *argv[])
     {
         runTime++;
     }
+    else
+    {
+        mesh.setInstance(oldInstance);
+    }
 
     // Take over refinement levels and write to new time directory.
     Pout<< "Writing mesh to time " << runTime.timeName() << endl;
diff --git a/applications/utilities/mesh/advanced/splitCells/splitCells.C b/applications/utilities/mesh/advanced/splitCells/splitCells.C
index 4e5b501b8526e55d02ff6f52260326ee4b48d639..6424745e9ad8df6cbcbc1228edbcb2a21fda4f21 100644
--- a/applications/utilities/mesh/advanced/splitCells/splitCells.C
+++ b/applications/utilities/mesh/advanced/splitCells/splitCells.C
@@ -534,6 +534,7 @@ int main(int argc, char *argv[])
 #   include "createTime.H"
     runTime.functionObjects().off();
 #   include "createPolyMesh.H"
+    const word oldInstance = mesh.pointsInstance();
 
     scalar featureAngle(readScalar(IStringStream(args.additionalArgs()[0])()));
 
@@ -693,7 +694,13 @@ int main(int argc, char *argv[])
         Info<< "Remaining:" << cellsToCut.size() << endl;
 
         // Write resulting mesh
-        Info << "Writing refined morphMesh to time " << runTime.value() << endl;
+        if (overwrite)
+        {
+            mesh.setInstance(oldInstance);
+        }
+
+        Info<< "Writing refined morphMesh to time " << runTime.timeName()
+            << endl;
 
         mesh.write();
     }
diff --git a/applications/utilities/mesh/conversion/polyDualMesh/makePolyDualMesh.C b/applications/utilities/mesh/conversion/polyDualMesh/makePolyDualMesh.C
index b647ec8d13b74980718727fdba437cbb6b0a07c2..ab55305402154b07b5ae68e8275ddd23cd0558c9 100644
--- a/applications/utilities/mesh/conversion/polyDualMesh/makePolyDualMesh.C
+++ b/applications/utilities/mesh/conversion/polyDualMesh/makePolyDualMesh.C
@@ -354,6 +354,7 @@ int main(int argc, char *argv[])
     runTime.setTime(Times[startTime], startTime);
 
 #   include "createMesh.H"
+    const word oldInstance = mesh.pointsInstance();
 
     // Mark boundary edges and points.
     // (Note: in 1.4.2 we can use the built-in mesh point ordering
@@ -499,7 +500,10 @@ int main(int argc, char *argv[])
     if (!overwrite)
     {
         runTime++;
-        mesh.setInstance(runTime.timeName());
+    }
+    else
+    {
+        mesh.setInstance(oldInstance);
     }
 
     Info<< "Writing dual mesh to " << runTime.timeName() << endl;
diff --git a/applications/utilities/mesh/generation/blockMesh/blockMeshApp.C b/applications/utilities/mesh/generation/blockMesh/blockMeshApp.C
index 1723fa51019e6e0fa419677058500a890da6b7f3..69439764c7052e3a1dbf78d0b24a279dd1d22f7c 100644
--- a/applications/utilities/mesh/generation/blockMesh/blockMeshApp.C
+++ b/applications/utilities/mesh/generation/blockMesh/blockMeshApp.C
@@ -78,10 +78,10 @@ int main(int argc, char *argv[])
 #   include "setRootCase.H"
 #   include "createTime.H"
 
+    const word dictName("blockMeshDict");
+
     word regionName;
     fileName polyMeshDir;
-    word dictName("blockMeshDict");
-    fileName dictPath(runTime.constant());
 
     if (args.options().found("region"))
     {
@@ -98,55 +98,58 @@ int main(int argc, char *argv[])
         polyMeshDir = polyMesh::meshSubDir;
     }
 
-    fileName dictLocal = polyMeshDir;
+    autoPtr<IOobject> meshDictIoPtr;
 
     if (args.options().found("dict"))
     {
-        wordList elems(fileName(args.options()["dict"]).components());
-        dictName = elems[elems.size()-1];
-        dictPath = elems[0];
-        dictLocal = "";
+        fileName dictPath(args.options()["dict"]);
 
-        if (elems.size() == 1)
-        {
-            dictPath = ".";
-        }
-        else if (elems.size() > 2)
-        {
-            dictLocal = fileName(SubList<word>(elems, elems.size()-2, 1));
-        }
+        meshDictIoPtr.set
+        (
+            new IOobject
+            (
+                ( dictPath.isDir() ? dictPath/dictName : dictPath ),
+                runTime,
+                IOobject::MUST_READ,
+                IOobject::NO_WRITE,
+                false
+            )
+        );
+    }
+    else
+    {
+        meshDictIoPtr.set
+        (
+            new IOobject
+            (
+                dictName,
+                runTime.constant(),
+                polyMeshDir,
+                runTime,
+                IOobject::MUST_READ,
+                IOobject::NO_WRITE,
+                false
+            )
+        );
     }
 
-    bool writeTopo = args.options().found("blockTopology");
-
-    IOobject meshDictIo
-    (
-        dictName,
-        dictPath,
-        dictLocal,
-        runTime,
-        IOobject::MUST_READ,
-        IOobject::NO_WRITE,
-        false
-    );
-
-    if (!meshDictIo.headerOk())
+    if (!meshDictIoPtr->headerOk())
     {
         FatalErrorIn(args.executable())
             << "Cannot open mesh description file\n    "
-            << meshDictIo.objectPath()
+            << meshDictIoPtr->objectPath()
             << nl
             << exit(FatalError);
     }
 
     Info<< nl << "Creating block mesh from\n    "
-        << meshDictIo.objectPath() << nl << endl;
-
-    IOdictionary meshDict(meshDictIo);
+        << meshDictIoPtr->objectPath() << nl << endl;
 
+    IOdictionary meshDict(meshDictIoPtr());
     blockMesh blocks(meshDict);
 
-    if (writeTopo)
+
+    if (args.options().found("blockTopology"))
     {
         // Write mesh as edges.
         {
diff --git a/applications/utilities/mesh/generation/extrude2DMesh/doExtrude2DMesh.C b/applications/utilities/mesh/generation/extrude2DMesh/doExtrude2DMesh.C
index 4d38c24269b9b4021eafaf35e68096dcb5c10ea1..2e0c16a5116843d70ddf5c3266900a09f4d13292 100644
--- a/applications/utilities/mesh/generation/extrude2DMesh/doExtrude2DMesh.C
+++ b/applications/utilities/mesh/generation/extrude2DMesh/doExtrude2DMesh.C
@@ -63,6 +63,7 @@ int main(int argc, char *argv[])
 #   include "createTime.H"
     runTime.functionObjects().off();
 #   include "createPolyMesh.H"
+    const word oldInstance = mesh.pointsInstance();
 
     scalar thickness(readScalar(IStringStream(args.additionalArgs()[0])()));
     bool overwrite = args.options().found("overwrite");
@@ -182,6 +183,10 @@ int main(int argc, char *argv[])
     {
         runTime++;
     }
+    else
+    {
+        mesh.setInstance(oldInstance);
+    }
 
     // Take over refinement levels and write to new time directory.
     Pout<< "Writing extruded mesh to time " << runTime.timeName() << nl
diff --git a/applications/utilities/mesh/generation/snappyHexMesh/Make/options b/applications/utilities/mesh/generation/snappyHexMesh/Make/options
index d5262d8d39414ed9359a521a4a124565b94953ef..d9eb36aa340d1aa8389aa2759d17871b99f25680 100644
--- a/applications/utilities/mesh/generation/snappyHexMesh/Make/options
+++ b/applications/utilities/mesh/generation/snappyHexMesh/Make/options
@@ -10,4 +10,8 @@ EXE_INC = \
 
 EXE_LIBS = \
     -L$(FOAM_MPI_LIBBIN) -lparMetisDecompositionMethod \
+    -lfiniteVolume \
+    -ldecompositionMethods \
+    -lmeshTools \
+    -ldynamicMesh \
     -lautoMesh
diff --git a/applications/utilities/mesh/manipulation/attachMesh/attachMesh.C b/applications/utilities/mesh/manipulation/attachMesh/attachMesh.C
index bf8665afbd3cea9a25085905dc2ffba67be7643f..1f9a898d4317582923d7ca61dcbe70de876fb17c 100644
--- a/applications/utilities/mesh/manipulation/attachMesh/attachMesh.C
+++ b/applications/utilities/mesh/manipulation/attachMesh/attachMesh.C
@@ -48,6 +48,7 @@ int main(int argc, char *argv[])
 #   include "createTime.H"
     runTime.functionObjects().off();
 #   include "createPolyMesh.H"
+    const word oldInstance = mesh.pointsInstance();
 
     bool overwrite = args.options().found("overwrite");
 
@@ -61,6 +62,10 @@ int main(int argc, char *argv[])
 
     attachPolyTopoChanger(mesh).attach();
 
+    if (overwrite)
+    {
+        mesh.setInstance(oldInstance);
+    }
     mesh.write();
 
     Info<< "End\n" << endl;
diff --git a/applications/utilities/mesh/manipulation/autoPatch/autoPatch.C b/applications/utilities/mesh/manipulation/autoPatch/autoPatch.C
index abf5a5654ee1b991bd3e18b3d80529a2e685a201..96a7ee5197381c694c0a084aa8d5dc4c6aca2a0e 100644
--- a/applications/utilities/mesh/manipulation/autoPatch/autoPatch.C
+++ b/applications/utilities/mesh/manipulation/autoPatch/autoPatch.C
@@ -77,6 +77,7 @@ int main(int argc, char *argv[])
 #   include "createTime.H"
     runTime.functionObjects().off();
 #   include "createPolyMesh.H"
+    const word oldInstance = mesh.pointsInstance();
 
     Info<< "Mesh read in = "
         << runTime.cpuTimeIncrement()
@@ -243,6 +244,10 @@ int main(int argc, char *argv[])
     polyMeshRepatcher.repatch();
 
     // Write resulting mesh
+    if (overwrite)
+    {
+        mesh.setInstance(oldInstance);
+    }
     mesh.write();
 
 
diff --git a/applications/utilities/mesh/manipulation/cellSet/cellSet.C b/applications/utilities/mesh/manipulation/cellSet/cellSet.C
index addac968b8979a514154a891c188c72f0431a7d2..ca8225d3f2d3d0094db068b45a6a405dd2e42d4e 100644
--- a/applications/utilities/mesh/manipulation/cellSet/cellSet.C
+++ b/applications/utilities/mesh/manipulation/cellSet/cellSet.C
@@ -74,19 +74,7 @@ int main(int argc, char *argv[])
 {
 #   include "setRootCase.H"
 #   include "createTime.H"
-
-    Info<< "Reading mesh for time = " << runTime.value() << endl;
-
-    Info<< "Create mesh\n" << endl;
-    polyMesh mesh
-    (
-        IOobject
-        (
-            polyMesh::defaultRegion,
-            runTime.timeName(),
-            runTime
-        )
-    );
+#   include "createPolyMesh.H"
 
     Info<< "Reading cellSetDict\n" << endl;
 
diff --git a/applications/utilities/mesh/manipulation/createBaffles/createBaffles.C b/applications/utilities/mesh/manipulation/createBaffles/createBaffles.C
index 2d4577739712f8b40a7399d473aca40e84b1483c..4970d0bcce3c0f4836ab92b0e8c2b1283cee8e84 100644
--- a/applications/utilities/mesh/manipulation/createBaffles/createBaffles.C
+++ b/applications/utilities/mesh/manipulation/createBaffles/createBaffles.C
@@ -60,6 +60,7 @@ int main(int argc, char *argv[])
 #   include "createTime.H"
     runTime.functionObjects().off();
 #   include "createMesh.H"
+    const word oldInstance = mesh.pointsInstance();
 
     const polyBoundaryMesh& patches = mesh.boundaryMesh();
     const faceZoneMesh& faceZones = mesh.faceZones();
@@ -247,6 +248,10 @@ int main(int argc, char *argv[])
         mesh.movePoints(map().preMotionPoints());
     }
 
+    if (overwrite)
+    {
+        mesh.setInstance(oldInstance);
+    }
     Pout<< "Writing mesh to " << runTime.timeName() << endl;
 
     mesh.write();
diff --git a/applications/utilities/mesh/manipulation/createPatch/createPatch.C b/applications/utilities/mesh/manipulation/createPatch/createPatch.C
index d6d58dd5420344939489025ad5456f315dc67bb9..7e0443a614666c63e1f13aa4766737cdc62757a8 100644
--- a/applications/utilities/mesh/manipulation/createPatch/createPatch.C
+++ b/applications/utilities/mesh/manipulation/createPatch/createPatch.C
@@ -569,6 +569,7 @@ int main(int argc, char *argv[])
 
 
 #   include "createPolyMesh.H"
+    const word oldInstance = mesh.pointsInstance();
 
     const polyBoundaryMesh& patches = mesh.boundaryMesh();
 
@@ -909,6 +910,10 @@ int main(int argc, char *argv[])
     {
         runTime++;
     }
+    else
+    {
+        mesh.setInstance(oldInstance);
+    }
 
     // Write resulting mesh
     Info<< "Writing repatched mesh to " << runTime.timeName() << nl << endl;
diff --git a/applications/utilities/mesh/manipulation/faceSet/faceSet.C b/applications/utilities/mesh/manipulation/faceSet/faceSet.C
index de41b2c464495d9a73da73759f87ce15e7a7aef3..d1700cc2f962259e9bb29e65f2ca81e18a60ade9 100644
--- a/applications/utilities/mesh/manipulation/faceSet/faceSet.C
+++ b/applications/utilities/mesh/manipulation/faceSet/faceSet.C
@@ -74,19 +74,7 @@ int main(int argc, char *argv[])
 {
 #   include "setRootCase.H"
 #   include "createTime.H"
-
-    Info<< "Reading mesh for time = " << runTime.value() << endl;
-
-    Info<< "Create mesh\n" << endl;
-    polyMesh mesh
-    (
-        IOobject
-        (
-            polyMesh::defaultRegion,
-            runTime.timeName(),
-            runTime
-        )
-    );
+#   include "createPolyMesh.H"
 
     Info<< "Reading faceSetDict\n" << endl;
 
diff --git a/applications/utilities/mesh/manipulation/mergeMeshes/mergeMeshes.C b/applications/utilities/mesh/manipulation/mergeMeshes/mergeMeshes.C
index aa55e24df176bc7578ef8cfbf3be3563947fbe0e..28955c4d6f7831cf7ab0d9b20a82d522c931f36d 100644
--- a/applications/utilities/mesh/manipulation/mergeMeshes/mergeMeshes.C
+++ b/applications/utilities/mesh/manipulation/mergeMeshes/mergeMeshes.C
@@ -42,7 +42,7 @@ int main(int argc, char *argv[])
 #   include "setRoots.H"
 #   include "createTimes.H"
 
-    Info<< "Reading master mesh for time = " << runTimeMaster.value() << endl;
+    Info<< "Reading master mesh for time = " << runTimeMaster.timeName() << endl;
 
     Info<< "Create mesh\n" << endl;
     mergePolyMesh masterMesh
@@ -56,7 +56,7 @@ int main(int argc, char *argv[])
     );
 
 
-    Info<< "Reading mesh to add for time = " << runTimeToAdd.value() << endl;
+    Info<< "Reading mesh to add for time = " << runTimeToAdd.timeName() << endl;
 
     Info<< "Create mesh\n" << endl;
     polyMesh meshToAdd
@@ -71,7 +71,7 @@ int main(int argc, char *argv[])
 
     runTimeMaster++;
 
-    Info<< "Writing combined mesh to " << runTimeMaster.value() << endl;
+    Info<< "Writing combined mesh to " << runTimeMaster.timeName() << endl;
 
     masterMesh.addMesh(meshToAdd);
     masterMesh.merge();
diff --git a/applications/utilities/mesh/manipulation/mergeOrSplitBaffles/mergeOrSplitBaffles.C b/applications/utilities/mesh/manipulation/mergeOrSplitBaffles/mergeOrSplitBaffles.C
index ccc91a903baa35521ee0aeaf14dbfd85fce0acfb..7f694438e97530cb93f88202adccfd84be9c3151 100644
--- a/applications/utilities/mesh/manipulation/mergeOrSplitBaffles/mergeOrSplitBaffles.C
+++ b/applications/utilities/mesh/manipulation/mergeOrSplitBaffles/mergeOrSplitBaffles.C
@@ -229,6 +229,7 @@ int main(int argc, char *argv[])
 #   include "createTime.H"
     runTime.functionObjects().off();
 #   include "createMesh.H"
+    const word oldInstance = mesh.pointsInstance();
 
     bool split = args.options().found("split");
     bool overwrite = args.options().found("overwrite");
@@ -338,7 +339,10 @@ int main(int argc, char *argv[])
         mesh.movePoints(map().preMotionPoints());
     }
 
-
+    if (overwrite)
+    {
+        mesh.setInstance(oldInstance);
+    }
     Pout<< "Writing mesh to time " << runTime.timeName() << endl;
     mesh.write();
 
diff --git a/applications/utilities/mesh/manipulation/pointSet/pointSet.C b/applications/utilities/mesh/manipulation/pointSet/pointSet.C
index 79414fcde7b25b591bceacd0a9dd7c55f20b3ab2..ef57d08d0779ab1da32045e5bdd55e18d52093bf 100644
--- a/applications/utilities/mesh/manipulation/pointSet/pointSet.C
+++ b/applications/utilities/mesh/manipulation/pointSet/pointSet.C
@@ -74,19 +74,7 @@ int main(int argc, char *argv[])
 {
 #   include "setRootCase.H"
 #   include "createTime.H"
-
-    Info<< "Reading mesh for time = " << runTime.value() << endl;
-
-    Info<< "Create mesh\n" << endl;
-    polyMesh mesh
-    (
-        IOobject
-        (
-            polyMesh::defaultRegion,
-            runTime.timeName(),
-            runTime
-        )
-    );
+#   include "createPolyMesh.H"
 
     Info<< "Reading pointSetDict\n" << endl;
 
diff --git a/applications/utilities/mesh/manipulation/refineMesh/refineMesh.C b/applications/utilities/mesh/manipulation/refineMesh/refineMesh.C
index 95c7973d2c4bffbcb3de3bfefd8abb69cf420b97..7636801b51ea74524ea301ca9fb2374f9ebc2e1b 100644
--- a/applications/utilities/mesh/manipulation/refineMesh/refineMesh.C
+++ b/applications/utilities/mesh/manipulation/refineMesh/refineMesh.C
@@ -300,6 +300,7 @@ int main(int argc, char *argv[])
 #   include "createTime.H"
     runTime.functionObjects().off();
 #   include "createPolyMesh.H"
+    const word oldInstance = mesh.pointsInstance();
 
     printEdgeStats(mesh);
 
@@ -427,6 +428,10 @@ int main(int argc, char *argv[])
 
 
     // Write resulting mesh
+    if (overwrite)
+    {
+        mesh.setInstance(oldInstance);
+    }
     mesh.write();
 
 
diff --git a/applications/utilities/mesh/manipulation/renumberMesh/renumberMesh.C b/applications/utilities/mesh/manipulation/renumberMesh/renumberMesh.C
index d93663b78991a05c2ef80ee8eb8ff973872df68b..b066936f83a5122136cab69fe7f770498fd303ac 100644
--- a/applications/utilities/mesh/manipulation/renumberMesh/renumberMesh.C
+++ b/applications/utilities/mesh/manipulation/renumberMesh/renumberMesh.C
@@ -383,9 +383,8 @@ int main(int argc, char *argv[])
 
     runTime.setTime(Times[startTime], startTime);
 
-
 #   include "createMesh.H"
-
+    const word oldInstance = mesh.pointsInstance();
 
     const bool blockOrder = args.options().found("blockOrder");
 
@@ -631,6 +630,11 @@ int main(int argc, char *argv[])
             << endl;
     }
 
+
+    if (overwrite)
+    {
+        mesh.setInstance(oldInstance);
+    }
     Info<< "Writing mesh to " << runTime.timeName() << endl;
 
     mesh.write();
diff --git a/applications/utilities/mesh/manipulation/splitMesh/splitMesh.C b/applications/utilities/mesh/manipulation/splitMesh/splitMesh.C
index aef00fe7e9be1ab42f0b03920591c620ecc3f312..4fb1c875bbde30574f3020a4283db5612b72fed1 100644
--- a/applications/utilities/mesh/manipulation/splitMesh/splitMesh.C
+++ b/applications/utilities/mesh/manipulation/splitMesh/splitMesh.C
@@ -124,6 +124,7 @@ int main(int argc, char *argv[])
 #   include "createTime.H"
     runTime.functionObjects().off();
 #   include "createPolyMesh.H"
+    const word oldInstance = mesh.pointsInstance();
 
     word setName(args.additionalArgs()[0]);
     word masterPatch(args.additionalArgs()[1]);
@@ -262,7 +263,12 @@ int main(int argc, char *argv[])
 
     splitter.attach();
 
-    Info << nl << "Writing polyMesh" << endl;
+    if (overwrite)
+    {
+        mesh.setInstance(oldInstance);
+    }
+
+    Info<< "Writing mesh to " << runTime.timeName() << endl;
     if (!mesh.write())
     {
         FatalErrorIn(args.executable())
diff --git a/applications/utilities/mesh/manipulation/splitMeshRegions/splitMeshRegions.C b/applications/utilities/mesh/manipulation/splitMeshRegions/splitMeshRegions.C
index a4b33b97dde4994f8aab8483985daf096c997874..aa83952b88f0bd77ea374fcbc4aede65c65131a5 100644
--- a/applications/utilities/mesh/manipulation/splitMeshRegions/splitMeshRegions.C
+++ b/applications/utilities/mesh/manipulation/splitMeshRegions/splitMeshRegions.C
@@ -30,12 +30,17 @@ Description
     - any face inbetween differing cellZones (-cellZones)
 
     Output is:
-    - mesh with multiple regions
+    - mesh with multiple regions or
     - mesh with cells put into cellZones (-makeCellZones)
 
-    Should work in parallel but cellZone interfaces cannot align with
+    Note:
+    - Should work in parallel but cellZone interfaces cannot align with
     processor boundaries so use the correct option in decomposition to
     preserve those interfaces.
+    - If a cell zone gets split into more than one region it can detect
+    the largest matching region (-sloppyCellZones). This will accept any
+    region that covers more than 50% of the zone. It has to be a subset
+    so cannot have any cells in any other zone.
 
 \*---------------------------------------------------------------------------*/
 
@@ -758,7 +763,8 @@ void createAndWriteRegion
     const regionSplit& cellRegion,
     const wordList& regionNames,
     const EdgeMap<label>& interfaceToPatch,
-    const label regionI
+    const label regionI,
+    const word& newMeshInstance
 )
 {
     Info<< "Creating mesh for region " << regionI
@@ -902,6 +908,7 @@ void createAndWriteRegion
 
     Info<< "Writing new mesh" << endl;
 
+    newMesh().setInstance(newMeshInstance);
     newMesh().write();
 
     // Write addressing files like decomposePar
@@ -1036,78 +1043,181 @@ EdgeMap<label> addRegionPatches
 }
 
 
-// Checks if regionI in cellRegion corresponds to existing zone.
-label findCorrespondingZone
+//// Checks if regionI in cellRegion is subset of existing cellZone. Returns -1
+//// if no zone found, zone otherwise
+//label findCorrespondingSubZone
+//(
+//    const cellZoneMesh& cellZones,
+//    const labelList& existingZoneID,
+//    const labelList& cellRegion,
+//    const label regionI
+//)
+//{
+//    // Zone corresponding to region. No corresponding zone.
+//    label zoneI = labelMax;
+//
+//    labelList regionCells = findIndices(cellRegion, regionI);
+//
+//    if (regionCells.empty())
+//    {
+//        // My local portion is empty. Maps to any empty cellZone. Mark with
+//        // special value which can get overwritten by other processors.
+//        zoneI = -1;
+//    }
+//    else
+//    {
+//        // Get zone for first element.
+//        zoneI = existingZoneID[regionCells[0]];
+//
+//        if (zoneI == -1)
+//        {
+//            zoneI = labelMax;
+//        }
+//        else
+//        {
+//            // 1. All regionCells in zoneI?
+//            forAll(regionCells, i)
+//            {
+//                if (existingZoneID[regionCells[i]] != zoneI)
+//                {
+//                    zoneI = labelMax;
+//                    break;
+//                }
+//            }
+//        }
+//    }
+//
+//    // Determine same zone over all processors.
+//    reduce(zoneI, maxOp<label>());
+//
+//    if (zoneI == labelMax)
+//    {
+//        // Cells in region that are not in zoneI
+//        zoneI = -1;
+//    }
+//
+//    return zoneI;
+//}
+
+
+//XXXXXXXXX
+// Find region that covers most of cell zone
+label findCorrespondingRegion
 (
-    const cellZoneMesh& cellZones,
-    const labelList& existingZoneID,
-    const labelList& cellRegion,
-    const label regionI
+    const labelList& existingZoneID,    // per cell the (unique) zoneID
+    const regionSplit& cellRegion,
+    const label zoneI,
+    const label minOverlapSize
 )
 {
-    // Zone corresponding to region. No corresponding zone.
-    label zoneI = labelMax;
-
-    labelList regionCells = findIndices(cellRegion, regionI);
+    // Per region the number of cells in zoneI
+    labelList cellsInZone(cellRegion.nRegions(), 0);
 
-    if (regionCells.empty())
-    {
-        // My local portion is empty. Maps to any empty cellZone. Mark with
-        // special value which can get overwritten by other processors.
-        zoneI = -1;
-    }
-    else
+    forAll(cellRegion, cellI)
     {
-        // Get zone for first element.
-        zoneI = existingZoneID[regionCells[0]];
-
-        if (zoneI == -1)
-        {
-            zoneI = labelMax;
-        }
-        else
+        if (existingZoneID[cellI] == zoneI)
         {
-            // 1. All regionCells in zoneI?
-            forAll(regionCells, i)
-            {
-                if (existingZoneID[regionCells[i]] != zoneI)
-                {
-                    zoneI = labelMax;
-                    break;
-                }
-            }
+            cellsInZone[cellRegion[cellI]]++;
         }
     }
 
-    // Determine same zone over all processors.
-    reduce(zoneI, maxOp<label>());
+    Pstream::listCombineGather(cellsInZone, plusEqOp<label>());
+    Pstream::listCombineScatter(cellsInZone);
 
+    // Pick region with largest overlap of zoneI
+    label regionI = findMax(cellsInZone);
 
-    // 2. All of cellZone present?
 
-    if (zoneI == labelMax)
+    if (cellsInZone[regionI] < minOverlapSize)
     {
-        zoneI = -1;
+        // Region covers too little of zone. Not good enough.
+        regionI = -1;
     }
-    else if (zoneI != -1)
+    else
     {
-        const cellZone& cz = cellZones[zoneI];
-
-        forAll(cz, i)
+        // Check that region contains no cells that aren't in cellZone.
+        forAll(cellRegion, cellI)
         {
-            if (cellRegion[cz[i]] != regionI)
+            if (cellRegion[cellI] == regionI && existingZoneID[cellI] != zoneI)
             {
-                zoneI = -1;
+                // cellI in regionI but not in zoneI
+                regionI = -1;
                 break;
             }
         }
         // If one in error, all should be in error. Note that branch gets taken
         // on all procs.
-        reduce(zoneI, minOp<label>());
+        reduce(regionI, minOp<label>());
     }
 
-    return zoneI;
+    return regionI;
 }
+//XXXXXXXXX
+
+
+//// Checks if cellZone has corresponding cellRegion.
+//label findCorrespondingRegion
+//(
+//    const cellZoneMesh& cellZones,
+//    const labelList& existingZoneID,    // per cell the (unique) zoneID
+//    const regionSplit& cellRegion,
+//    const label zoneI
+//)
+//{
+//    // Region corresponding to zone. Start off with special value: no
+//    // corresponding region.
+//    label regionI = labelMax;
+//
+//    const cellZone& cz = cellZones[zoneI];
+//
+//    if (cz.empty())
+//    {
+//        // My local portion is empty. Maps to any empty cellZone. Mark with
+//        // special value which can get overwritten by other processors.
+//        regionI = -1;
+//    }
+//    else
+//    {
+//        regionI = cellRegion[cz[0]];
+//
+//        forAll(cz, i)
+//        {
+//            if (cellRegion[cz[i]] != regionI)
+//            {
+//                regionI = labelMax;
+//                break;
+//            }
+//        }
+//    }
+//
+//    // Determine same zone over all processors.
+//    reduce(regionI, maxOp<label>());
+//
+//
+//    // 2. All of region present?
+//
+//    if (regionI == labelMax)
+//    {
+//        regionI = -1;
+//    }
+//    else if (regionI != -1)
+//    {
+//        forAll(cellRegion, cellI)
+//        {
+//            if (cellRegion[cellI] == regionI && existingZoneID[cellI] != zoneI)
+//            {
+//                // cellI in regionI but not in zoneI
+//                regionI = -1;
+//                break;
+//            }
+//        }
+//        // If one in error, all should be in error. Note that branch gets taken
+//        // on all procs.
+//        reduce(regionI, minOp<label>());
+//    }
+//
+//    return regionI;
+//}
 
 
 // Main program:
@@ -1120,11 +1230,14 @@ int main(int argc, char *argv[])
     argList::validOptions.insert("largestOnly", "");
     argList::validOptions.insert("insidePoint", "point");
     argList::validOptions.insert("overwrite", "");
+    argList::validOptions.insert("detectOnly", "");
+    argList::validOptions.insert("sloppyCellZones", "");
 
 #   include "setRootCase.H"
 #   include "createTime.H"
     runTime.functionObjects().off();
 #   include "createMesh.H"
+    const word oldInstance = mesh.pointsInstance();
 
     word blockedFacesName;
     if (args.options().found("blockedFaces"))
@@ -1134,10 +1247,13 @@ int main(int argc, char *argv[])
             << blockedFacesName << nl << endl;
     }
 
+    bool makeCellZones = args.options().found("makeCellZones");
     bool largestOnly = args.options().found("largestOnly");
     bool insidePoint = args.options().found("insidePoint");
     bool useCellZones = args.options().found("cellZones");
     bool overwrite = args.options().found("overwrite");
+    bool detectOnly = args.options().found("detectOnly");
+    bool sloppyCellZones = args.options().found("sloppyCellZones");
 
     if (insidePoint && largestOnly)
     {
@@ -1281,6 +1397,31 @@ int main(int argc, char *argv[])
         Info<< "Writing region per cell file (for manual decomposition) to "
             << cellToRegion.objectPath() << nl << endl;
     }
+    // Write for postprocessing
+    {
+        volScalarField cellToRegion
+        (
+            IOobject
+            (
+                "cellToRegion",
+                mesh.facesInstance(),
+                mesh,
+                IOobject::NO_READ,
+                IOobject::NO_WRITE,
+                false
+            ),
+            mesh,
+            dimensionedScalar("zero", dimless, 0)
+        );
+        forAll(cellRegion, cellI)
+        {
+            cellToRegion[cellI] = cellRegion[cellI];
+        }
+        cellToRegion.write();
+
+        Info<< "Writing region per cell as volScalarField to "
+            << cellToRegion.objectPath() << nl << endl;
+    }
 
 
     // Sizes per region
@@ -1307,40 +1448,131 @@ int main(int argc, char *argv[])
     Info<< endl;
 
 
+    // Sizes per cellzone
+    // ~~~~~~~~~~~~~~~~~~
+
+    labelList zoneSizes(cellZones.size(), 0);
+    if (useCellZones || makeCellZones || sloppyCellZones)
+    {
+        List<wordList> zoneNames(Pstream::nProcs());
+        zoneNames[Pstream::myProcNo()] = cellZones.names();
+        Pstream::gatherList(zoneNames);
+        Pstream::scatterList(zoneNames);
+
+        forAll(zoneNames, procI)
+        {
+            if (zoneNames[procI] != zoneNames[0])
+            {
+                FatalErrorIn(args.executable())
+                    << "cellZones not synchronised across processors." << endl
+                    << "Master has cellZones " << zoneNames[0] << endl
+                    << "Processor " << procI
+                    << " has cellZones " << zoneNames[procI]
+                    << exit(FatalError);
+            }
+        }
+
+        forAll(cellZones, zoneI)
+        {
+            zoneSizes[zoneI] = returnReduce
+            (
+                cellZones[zoneI].size(),
+                sumOp<label>()
+            );
+        }
+    }
+
+
     // Whether region corresponds to a cellzone
     // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-    Info<< "Region\tZone\tName" << nl
-        << "------\t----\t----" << endl;
-
     // Region per zone
-    labelList regionToZone(cellRegion.nRegions());
+    labelList regionToZone(cellRegion.nRegions(), -1);
     // Name of region
     wordList regionNames(cellRegion.nRegions());
-    forAll(regionToZone, regionI)
+    // Zone to region
+    labelList zoneToRegion(cellZones.size(), -1);
+
+    if (sloppyCellZones)
     {
-        regionToZone[regionI] = findCorrespondingZone
-        (
-            cellZones,
-            zoneID,
-            cellRegion,
-            regionI
-        );
+        Info<< "Trying to match regions to existing cell zones;"
+            << " region can be subset of cell zone." << nl << endl;
 
-        if (regionToZone[regionI] != -1)
+        forAll(cellZones, zoneI)
         {
-            regionNames[regionI] = cellZones[regionToZone[regionI]].name();
+            label regionI = findCorrespondingRegion
+            (
+                zoneID,
+                cellRegion,
+                zoneI,
+                label(0.5*zoneSizes[zoneI]) // minimum overlap
+            );
+
+            if (regionI != -1)
+            {
+                Info<< "Sloppily matched region " << regionI
+                    << " size " << regionSizes[regionI]
+                    << " to zone " << zoneI << " size " << zoneSizes[zoneI]
+                    << endl;
+                zoneToRegion[zoneI] = regionI;
+                regionToZone[regionI] = zoneI;
+                regionNames[regionI] = cellZones[zoneI].name();
+            }
         }
-        else
+    }
+    else
+    {
+        Info<< "Trying to match regions to existing cell zones." << nl << endl;
+
+        forAll(cellZones, zoneI)
+        {
+            label regionI = findCorrespondingRegion
+            (
+                zoneID,
+                cellRegion,
+                zoneI,
+                1               // minimum overlap
+            );
+
+            if (regionI != -1)
+            {
+                zoneToRegion[zoneI] = regionI;
+                regionToZone[regionI] = zoneI;
+                regionNames[regionI] = cellZones[zoneI].name();
+            }
+        }
+    }
+    // Allocate region names for unmatched regions.
+    forAll(regionToZone, regionI)
+    {
+        if (regionToZone[regionI] == -1)
         {
             regionNames[regionI] = "domain" + Foam::name(regionI);
         }
+    }
+
 
+    // Print region to zone
+    Info<< "Region\tZone\tName" << nl
+        << "------\t----\t----" << endl;
+    forAll(regionToZone, regionI)
+    {
         Info<< regionI << '\t' << regionToZone[regionI] << '\t'
             << regionNames[regionI] << nl;
     }
     Info<< endl;
 
+    //// Print zone to region
+    //Info<< "Zone\tName\tRegion" << nl
+    //    << "----\t----\t------" << endl;
+    //forAll(zoneToRegion, zoneI)
+    //{
+    //    Info<< zoneI << '\t' << cellZones[zoneI].name() << '\t'
+    //        << zoneToRegion[zoneI] << nl;
+    //}
+    //Info<< endl;
+
+
 
     // Since we're going to mess with patches make sure all non-processor ones
     // are on all processors.
@@ -1361,7 +1593,8 @@ int main(int argc, char *argv[])
         interfaceSizes
     );
 
-    Info<< "Region\tRegion\tFaces" << nl
+    Info<< "Sizes inbetween regions:" << nl << nl
+        << "Region\tRegion\tFaces" << nl
         << "------\t------\t-----" << endl;
 
     forAll(interfaces, interI)
@@ -1373,7 +1606,10 @@ int main(int argc, char *argv[])
     Info<< endl;
 
 
-
+    if (detectOnly)
+    {
+        return 0;
+    }
 
 
     // Read objects in time directory
@@ -1423,7 +1659,7 @@ int main(int argc, char *argv[])
     {
         Info<< "Only one region. Doing nothing." << endl;
     }
-    else if (args.options().found("makeCellZones"))
+    else if (makeCellZones)
     {
         Info<< "Putting cells into cellZones instead of splitting mesh."
             << endl;
@@ -1479,12 +1715,16 @@ int main(int argc, char *argv[])
         if (!overwrite)
         {
             runTime++;
+            mesh.setInstance(runTime.timeName());
+        }
+        else
+        {
+            mesh.setInstance(oldInstance);
         }
 
         Info<< "Writing cellZones as new mesh to time " << runTime.timeName()
             << nl << endl;
 
-        mesh.setInstance(runTime.timeName());
         mesh.write();
 
 
@@ -1567,7 +1807,8 @@ int main(int argc, char *argv[])
                 cellRegion,
                 regionNames,
                 interfaceToPatch,
-                regionI
+                regionI,
+                (overwrite ? oldInstance : runTime.timeName())
             );
         }
         else if (largestOnly)
@@ -1584,7 +1825,8 @@ int main(int argc, char *argv[])
                 cellRegion,
                 regionNames,
                 interfaceToPatch,
-                regionI
+                regionI,
+                (overwrite ? oldInstance : runTime.timeName())
             );
         }
         else
@@ -1602,7 +1844,8 @@ int main(int argc, char *argv[])
                     cellRegion,
                     regionNames,
                     interfaceToPatch,
-                    regionI
+                    regionI,
+                    (overwrite ? oldInstance : runTime.timeName())
                 );
             }
         }
diff --git a/applications/utilities/mesh/manipulation/stitchMesh/stitchMesh.C b/applications/utilities/mesh/manipulation/stitchMesh/stitchMesh.C
index 4773654752d599663071422bb44f1795e9dadaaf..1131c591c7db91ece9158a1a312e193eede19b83 100644
--- a/applications/utilities/mesh/manipulation/stitchMesh/stitchMesh.C
+++ b/applications/utilities/mesh/manipulation/stitchMesh/stitchMesh.C
@@ -137,6 +137,7 @@ int main(int argc, char *argv[])
 #   include "createTime.H"
     runTime.functionObjects().off();
 #   include "createMesh.H"
+    const word oldInstance = mesh.pointsInstance();
 
 
     word masterPatchName(args.additionalArgs()[0]);
@@ -391,6 +392,10 @@ int main(int argc, char *argv[])
     mesh.movePoints(morphMap->preMotionPoints());
 
     // Write mesh
+    if (overwrite)
+    {
+        mesh.setInstance(oldInstance);
+    }
     Info << nl << "Writing polyMesh to time " << runTime.timeName() << endl;
 
     IOstream::defaultPrecision(10);
diff --git a/applications/utilities/mesh/manipulation/subsetMesh/subsetMesh.C b/applications/utilities/mesh/manipulation/subsetMesh/subsetMesh.C
index 556e9fd21e8807a89cff8d0fe64c53fb91489a8e..56b48a2dd2a9ce81259605e685c8c29f2f71d34b 100644
--- a/applications/utilities/mesh/manipulation/subsetMesh/subsetMesh.C
+++ b/applications/utilities/mesh/manipulation/subsetMesh/subsetMesh.C
@@ -159,6 +159,7 @@ int main(int argc, char *argv[])
 #   include "createTime.H"
     runTime.functionObjects().off();
 #   include "createMesh.H"
+    const word oldInstance = mesh.pointsInstance();
 
     word setName(args.additionalArgs()[0]);
     bool overwrite = args.options().found("overwrite");
@@ -276,7 +277,7 @@ int main(int argc, char *argv[])
     // Read point fields and subset
     // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-    pointMesh pMesh(mesh);
+    const pointMesh& pMesh = pointMesh::New(mesh);
 
     wordList pointScalarNames(objects.names(pointScalarField::typeName));
     PtrList<pointScalarField> pointScalarFlds(pointScalarNames.size());
@@ -331,8 +332,12 @@ int main(int argc, char *argv[])
     {
         runTime++;
     }
+    else
+    {
+        mesh.setInstance(oldInstance);
+    }
 
-    Info<< "Writing subsetted mesh and fields to time " << runTime.value()
+    Info<< "Writing subsetted mesh and fields to time " << runTime.timeName()
         << endl;
     subsetter.subMesh().write();
 
diff --git a/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3FoamPointFields.H b/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3FoamPointFields.H
index 47a6e89ef6d6d3b016c80b2d2c75fd9b6f4e96ce..63b5c0c3a6287d032aa810ea7ee142da2dd90583 100644
--- a/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3FoamPointFields.H
+++ b/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3FoamPointFields.H
@@ -190,16 +190,15 @@ void Foam::vtkPV3Foam::convertPointField
     }
 
     vtkFloatArray *pointData = vtkFloatArray::New();
-    pointData->SetNumberOfTuples( nPoints + addPointCellLabels.size() );
-    pointData->SetNumberOfComponents( nComp );
-    pointData->Allocate( nComp*(nPoints + addPointCellLabels.size()) );
-    pointData->SetName( tf.name().c_str() );
-
+    pointData->SetNumberOfTuples(nPoints + addPointCellLabels.size());
+    pointData->SetNumberOfComponents(nComp);
+    pointData->Allocate(nComp*(nPoints + addPointCellLabels.size()));
+    pointData->SetName(ptf.name().c_str());
 
     if (debug)
     {
         Info<< "convert convertPointField: "
-            << tf.name()
+            << ptf.name()
             << " size = " << nPoints
             << " nComp=" << nComp
             << " nTuples = " << (nPoints + addPointCellLabels.size())
diff --git a/applications/utilities/postProcessing/sampling/sample/sampleDict b/applications/utilities/postProcessing/sampling/sample/sampleDict
index cc25676c75cea55c0d73c5575268220e7acab0fc..b605f29e571320a1f4d3af3ca93e04841594f833 100644
--- a/applications/utilities/postProcessing/sampling/sample/sampleDict
+++ b/applications/utilities/postProcessing/sampling/sample/sampleDict
@@ -161,6 +161,10 @@ surfaces
         isoField        rho;
         isoValue        0.5;
         interpolate     true;
+
+        //zone            ABC;          // Optional: zone only
+        //exposedPatchName fixedWalls;  // Optional: zone only
+
         // regularise      false;    // Optional: do not simplify
     }
     constantIso
@@ -171,8 +175,27 @@ surfaces
         isoField        rho;
         isoValue        0.5;
         interpolate     false;
+        regularise      false;              // do not simplify
+    }
+
+    triangleCut
+    {
+        // Cutingplaneusing iso surface
+        type            cuttingPlane;
+        planeType       pointAndNormal;
+        pointAndNormalDict
+        {
+            basePoint       (0.4 0 0.4);
+            normalVector    (1 0.2 0.2);
+        }
+        interpolate     true;
+
+        //zone            ABC;          // Optional: zone only
+        //exposedPatchName fixedWalls;  // Optional: zone only
+
         // regularise      false;    // Optional: do not simplify
     }
+
 );
 
 
diff --git a/applications/utilities/surface/surfaceCoordinateSystemTransform/surfaceCoordinateSystemTransform.C b/applications/utilities/surface/surfaceCoordinateSystemTransform/surfaceCoordinateSystemTransform.C
index e5ae6a110045bb70ccbb06c43bf90ad84e5c7558..cabebafc56803bdb070c005f5c010ecc548410e3 100644
--- a/applications/utilities/surface/surfaceCoordinateSystemTransform/surfaceCoordinateSystemTransform.C
+++ b/applications/utilities/surface/surfaceCoordinateSystemTransform/surfaceCoordinateSystemTransform.C
@@ -78,56 +78,61 @@ int main(int argc, char *argv[])
     Time runTime(args.rootPath(), args.caseName());
     const stringList& params = args.additionalArgs();
 
-    word dictName("coordinateSystems");
-    fileName dictPath(runTime.constant());
-    fileName dictLocal;
+    const word dictName("coordinateSystems");
 
-    if (args.options().found("dict"))
+    autoPtr<coordinateSystem> fromCsys;
+    autoPtr<coordinateSystem> toCsys;
+
+    if (args.options().found("from") || args.options().found("to"))
     {
-        wordList elems(fileName(args.options()["dict"]).components());
-        dictName = elems[elems.size()-1];
-        dictPath = elems[0];
-        dictLocal = "";
+        autoPtr<IOobject> csDictIoPtr;
 
-        if (elems.size() == 1)
+        if (args.options().found("dict"))
         {
-            dictPath = ".";
+            fileName dictPath(args.options()["dict"]);
+
+            csDictIoPtr.set
+            (
+                new IOobject
+                (
+                    ( dictPath.isDir() ? dictPath/dictName : dictPath ),
+                    runTime,
+                    IOobject::MUST_READ,
+                    IOobject::NO_WRITE,
+                    false
+                )
+            );
         }
-        else if (elems.size() > 2)
+        else
         {
-            dictLocal = fileName(SubList<word>(elems, elems.size()-2, 1));
+            csDictIoPtr.set
+            (
+                new IOobject
+                (
+                    dictName,
+                    runTime.constant(),
+                    runTime,
+                    IOobject::MUST_READ,
+                    IOobject::NO_WRITE,
+                    false
+                )
+            );
         }
-    }
 
-    autoPtr<coordinateSystem> fromCsys;
-    autoPtr<coordinateSystem> toCsys;
 
-    if (args.options().found("from") || args.options().found("to"))
-    {
-        IOobject csDictIo
-        (
-            dictName,
-            dictPath,
-            dictLocal,
-            runTime,
-            IOobject::MUST_READ,
-            IOobject::NO_WRITE,
-            false
-        );
-
-        if (!csDictIo.headerOk())
+        if (!csDictIoPtr->headerOk())
         {
             FatalErrorIn(args.executable())
                 << "Cannot open coordinateSystems file\n    "
-                << csDictIo.objectPath() << nl
+                << csDictIoPtr->objectPath() << nl
                 << exit(FatalError);
         }
 
-        coordinateSystems csLst(csDictIo);
+        coordinateSystems csLst(csDictIoPtr());
 
         if (args.options().found("from"))
         {
-            word csName(args.options()["from"]);
+            const word csName(args.options()["from"]);
 
             label csId = csLst.find(csName);
             if (csId < 0)
@@ -143,7 +148,7 @@ int main(int argc, char *argv[])
 
         if (args.options().found("to"))
         {
-            word csName(args.options()["to"]);
+            const word csName(args.options()["to"]);
 
             label csId = csLst.find(csName);
             if (csId < 0)
diff --git a/applications/utilities/surface/surfaceMeshConvert/surfaceMeshConvert.C b/applications/utilities/surface/surfaceMeshConvert/surfaceMeshConvert.C
index 65d62f4b67fc5174cb02f720d5e1b39ce1f9ab9c..9b5c2cb8f7c9bf37175b88611ea827241cef3403 100644
--- a/applications/utilities/surface/surfaceMeshConvert/surfaceMeshConvert.C
+++ b/applications/utilities/surface/surfaceMeshConvert/surfaceMeshConvert.C
@@ -56,6 +56,7 @@ Note
 #include "Time.H"
 #include "polyMesh.H"
 #include "triSurface.H"
+#include "PackedBoolList.H"
 
 #include "MeshedSurfaces.H"
 #include "UnsortedMeshedSurfaces.H"
@@ -115,7 +116,7 @@ int main(int argc, char *argv[])
         if (args.options().found("orient"))
         {
             Info<< "Checking surface orientation" << endl;
-            surf.checkOrientation(true);
+            PatchTools::checkOrientation(surf, true);
             Info<< endl;
         }
 
@@ -154,7 +155,7 @@ int main(int argc, char *argv[])
         if (args.options().found("orient"))
         {
             Info<< "Checking surface orientation" << endl;
-            surf.checkOrientation(true);
+            PatchTools::checkOrientation(surf, true);
             Info<< endl;
         }
 
@@ -192,7 +193,7 @@ int main(int argc, char *argv[])
         if (args.options().found("orient"))
         {
             Info<< "Checking surface orientation" << endl;
-            surf.checkOrientation(true);
+            PatchTools::checkOrientation(surf, true);
             Info<< endl;
         }
 
@@ -230,7 +231,7 @@ int main(int argc, char *argv[])
         if (args.options().found("orient"))
         {
             Info<< "Checking surface orientation" << endl;
-            surf.checkOrientation(true);
+            PatchTools::checkOrientation(surf, true);
             Info<< endl;
         }
 
diff --git a/etc/bashrc b/etc/bashrc
index 7c9f9ecad366b493b698bf52e1a42577736e9705..e9f9c6f9cf8a3bfcd1d7adf87a765f8f948ebc08 100644
--- a/etc/bashrc
+++ b/etc/bashrc
@@ -172,6 +172,17 @@ Linux)
     esac
     ;;
 
+SunOS)
+    WM_ARCH=SunOS64
+    export WM_COMPILER_LIB_ARCH=64
+    export WM_CC='gcc'
+    export WM_CXX='g++'
+    export WM_CFLAGS='-mabi=64 -fPIC'
+    export WM_CXXFLAGS='-mabi=64 -fPIC'
+    export WM_LDFLAGS='-mabi=64 -G0'
+    export WM_MPLIB=FJMPI
+    ;;
+
 *)    	# an unsupported operating system
     cat <<USAGE
 
diff --git a/etc/cshrc b/etc/cshrc
index b1dfd9ec346df5789efb25439bd2904c78f90a2e..bcda5b6318df9a8508132de8afc976c8ec7ad940 100644
--- a/etc/cshrc
+++ b/etc/cshrc
@@ -149,7 +149,7 @@ case Linux:
         setenv WM_ARCH linuxIA64
         setenv WM_COMPILER I64
         breaksw
-    mips64)
+    case mips64:
         setenv WM_ARCH SiCortex64
         setenv WM_COMPILER_LIB_ARCH 64
         setenv WM_CC 'gcc'
@@ -158,13 +158,24 @@ case Linux:
         setenv WM_CXXFLAGS '-mabi=64 -fPIC'
         setenv WM_LDFLAGS '-mabi=64 -G0'
         setenv WM_MPLIB MPI
-        ;;
+        breaksw
     default:
         echo Unknown processor type `uname -m` for Linux
         breaksw
     endsw
     breaksw
 
+case SunOS:
+    setenv WM_ARCH SunOS64
+    setenv WM_COMPILER_LIB_ARCH 64
+    setenv WM_CC 'gcc'
+    setenv WM_CXX 'g++'
+    setenv WM_CFLAGS '-mabi=64 -fPIC'
+    setenv WM_CXXFLAGS '-mabi=64 -fPIC'
+    setenv WM_LDFLAGS '-mabi=64 -G0'
+    setenv WM_MPLIB FJMPI
+    breaksw
+
 default:
     echo
     echo "Your '$WM_ARCH' operating system is not supported by this release"
diff --git a/etc/settings.csh b/etc/settings.csh
index 73b14eb38c2d5acdf4b33434c6acfced26bbf506..a38ec5eacd63761ec7b66e90fe5a3ee6559b252e 100644
--- a/etc/settings.csh
+++ b/etc/settings.csh
@@ -222,6 +222,15 @@ case MPI:
     setenv FOAM_MPI_LIBBIN $FOAM_LIBBIN/mpi
     breaksw
 
+case FJMPI:
+    setenv MPI_ARCH_PATH /opt/FJSVmpi2
+    setenv FOAM_MPI_LIBBIN $FOAM_LIBBIN/mpi
+    _foamAddPath $MPI_ARCH_PATH/bin
+    _foamAddLib  $MPI_ARCH_PATH/lib/sparcv9
+    _foamAddLib  /opt/FSUNf90/lib/sparcv9
+    _foamAddLib  /opt/FJSVpnidt/lib
+    breaksw
+
 default:
     setenv FOAM_MPI_LIBBIN $FOAM_LIBBIN/dummy
     breaksw
diff --git a/etc/settings.sh b/etc/settings.sh
index ff56af0b95b78f9f35fecd3d4c53c1f6a4eb7999..7df3f6d5900d0ce91cc69fc8d33667816c9ca641 100644
--- a/etc/settings.sh
+++ b/etc/settings.sh
@@ -249,6 +249,16 @@ MPI)
     export FOAM_MPI_LIBBIN=$FOAM_LIBBIN/mpi
     ;;
 
+FJMPI)
+    export MPI_ARCH_PATH=/opt/FJSVmpi2
+    export FOAM_MPI_LIBBIN=$FOAM_LIBBIN/mpi
+
+    _foamAddPath $MPI_ARCH_PATH/bin
+    _foamAddLib  $MPI_ARCH_PATH/lib/sparcv9
+    _foamAddLib  /opt/FSUNf90/lib/sparcv9
+    _foamAddLib  /opt/FJSVpnidt/lib
+    ;;
+
 *)
     export FOAM_MPI_LIBBIN=$FOAM_LIBBIN/dummy
     ;;
diff --git a/src/OSspecific/Unix/Make/files b/src/OSspecific/Unix/Make/files
index f83513ac4ac08d08f96d8cdbce23005b58c63584..b6e32d80d6652a96636c71d9ae129d35dd89035f 100644
--- a/src/OSspecific/Unix/Make/files
+++ b/src/OSspecific/Unix/Make/files
@@ -8,7 +8,11 @@ fileStat.C
 Unix.C
 cpuTime/cpuTime.C
 clockTime/clockTime.C
+
+#ifndef SunOS64
 printStack.C
-/*dummyPrintStack.C*/
+#else
+dummyPrintStack.C
+#endif
 
 LIB = $(FOAM_LIBBIN)/libOSspecific
diff --git a/src/OpenFOAM/Make/files b/src/OpenFOAM/Make/files
index 8fe778aa16fa5075545b6b53d4a71d6818947b79..2c4bfce8d7e03e04ec054014785255989ee50d7f 100644
--- a/src/OpenFOAM/Make/files
+++ b/src/OpenFOAM/Make/files
@@ -50,7 +50,7 @@ primitives/random/Random.C
 containers/HashTables/HashTable/HashTableName.C
 containers/HashTables/StaticHashTable/StaticHashTableName.C
 containers/Lists/SortableList/ParSortableListName.C
-containers/Lists/PackedList/PackedListName.C
+containers/Lists/PackedList/PackedListCore.C
 containers/Lists/ListOps/ListOps.C
 containers/LinkedLists/linkTypes/SLListBase/SLListBase.C
 containers/LinkedLists/linkTypes/DLListBase/DLListBase.C
diff --git a/src/OpenFOAM/containers/HashTables/HashSet/HashSet.C b/src/OpenFOAM/containers/HashTables/HashSet/HashSet.C
index 2136916780483cf8391262eddd9f139b47b01ffa..6bf84e0c55c62b46dbcf3bb5139d9cda334e8a40 100644
--- a/src/OpenFOAM/containers/HashTables/HashSet/HashSet.C
+++ b/src/OpenFOAM/containers/HashTables/HashSet/HashSet.C
@@ -51,6 +51,13 @@ Foam::HashSet<Key, Hash>::HashSet(const HashTable<AnyType, Key, Hash>& ht)
 
 // * * * * * * * * * * * * * * * Member Operators  * * * * * * * * * * * * * //
 
+template<class Key, class Hash>
+inline bool Foam::HashSet<Key, Hash>::operator[](const Key& key) const
+{
+    return found(key);
+}
+
+
 template<class Key, class Hash>
 bool Foam::HashSet<Key, Hash>::operator==(const HashSet<Key, Hash>& rhs) const
 {
diff --git a/src/OpenFOAM/containers/HashTables/HashSet/HashSet.H b/src/OpenFOAM/containers/HashTables/HashSet/HashSet.H
index fbe0baf785dc5b2a67ff5afd9307767acea85c12..9a4c5951be06b0771e85b53844dcc5086becb868 100644
--- a/src/OpenFOAM/containers/HashTables/HashSet/HashSet.H
+++ b/src/OpenFOAM/containers/HashTables/HashSet/HashSet.H
@@ -133,9 +133,11 @@ public:
             return HashTable<nil, Key, Hash>::insert(key, nil());
         }
 
-
     // Member Operators
 
+        //- Return true if the entry exists, same as found()
+        inline bool operator[](const Key&) const;
+
         //- Equality. Two hashtables are equal when their contents are equal.
         //  Independent of table size or order.
         bool operator==(const HashSet<Key, Hash>&) const;
diff --git a/src/OpenFOAM/containers/Lists/PackedList/PackedList.C b/src/OpenFOAM/containers/Lists/PackedList/PackedList.C
index d4bb3ca8269c6796c8a4200ca62f3a52426b166b..8667ad47ba5e8c6698a226cb00eb2c9af6d451e8 100644
--- a/src/OpenFOAM/containers/Lists/PackedList/PackedList.C
+++ b/src/OpenFOAM/containers/Lists/PackedList/PackedList.C
@@ -28,20 +28,20 @@ License
 
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
-template<int nBits>
+template<unsigned nBits>
 Foam::PackedList<nBits>::PackedList(const label size, const unsigned int val)
 :
-    List<PackedStorage>(packedLength(size), 0u),
+    StorageList(packedLength(size), 0u),
     size_(size)
 {
     operator=(val);
 }
 
 
-template<int nBits>
+template<unsigned nBits>
 Foam::PackedList<nBits>::PackedList(const UList<label>& lst)
 :
-    List<PackedStorage>(packedLength(lst.size()), 0u),
+    StorageList(packedLength(lst.size()), 0u),
     size_(lst.size())
 {
     forAll(lst, i)
@@ -53,7 +53,116 @@ Foam::PackedList<nBits>::PackedList(const UList<label>& lst)
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
-template<int nBits>
+
+#if (UINT_MAX == 0xFFFFFFFF)
+// 32-bit counting, Hamming weight method
+#   define COUNT_PACKEDBITS(sum, x)                                           \
+{                                                                             \
+    x -= (x >> 1) & 0x55555555;                                               \
+    x = (x & 0x33333333) + ((x >> 2) & 0x33333333);                           \
+    sum += (((x + (x >> 4)) & 0x0F0F0F0F) * 0x01010101) >> 24;                \
+}
+#elif (UINT_MAX == 0xFFFFFFFFFFFFFFFF)
+// 64-bit counting, Hamming weight method
+#   define COUNT_PACKEDBITS(sum, x)                                           \
+{                                                                             \
+    x -= (x >> 1) & 0x5555555555555555;                                       \
+    x = (x & 0x3333333333333333) + ((x >> 2) & 0x3333333333333333);           \
+    sum += (((x + (x >> 4)) & 0x0F0F0F0F0F0F0F0F) * 0x0101010101010101) >> 56;\
+}
+#else
+// Arbitrary number of bits, Brian Kernighan's method
+#   define COUNT_PACKEDBITS(sum, x)    for (; x; ++sum) { x &= x - 1; }
+#endif
+
+
+template<unsigned nBits>
+unsigned int Foam::PackedList<nBits>::count() const
+{
+    register unsigned int c = 0;
+
+    if (size_)
+    {
+        // mask value for complete chunks
+        unsigned int mask = maskLower(packing());
+
+        unsigned int endIdx = size_ / packing();
+        unsigned int endOff = size_ % packing();
+
+        // count bits in complete elements
+        for (unsigned i = 0; i < endIdx; ++i)
+        {
+            register unsigned int bits = StorageList::operator[](i) & mask;
+            COUNT_PACKEDBITS(c, bits);
+        }
+
+        // count bits in partial chunk
+        if (endOff)
+        {
+            mask = maskLower(endOff);
+
+            register unsigned int bits = StorageList::operator[](endIdx) & mask;
+            COUNT_PACKEDBITS(c, bits);
+        }
+    }
+
+    return c;
+}
+
+
+template<unsigned nBits>
+bool Foam::PackedList<nBits>::trim()
+{
+    if (!size_)
+    {
+        return false;
+    }
+
+    // mask value for complete chunks
+    unsigned int mask = maskLower(packing());
+
+    label currElem = packedLength(size_) - 1;
+    unsigned int endOff = size_ % packing();
+
+    // clear trailing bits on final segment
+    if (endOff)
+    {
+        StorageList::operator[](currElem) &= maskLower(endOff);
+    }
+
+    // test entire chunk
+    while (currElem > 0 && !(StorageList::operator[](currElem) &= mask))
+    {
+        currElem--;
+    }
+
+    // test segment
+    label newsize = (currElem + 1) * packing();
+
+    // mask for the final segment
+    mask = max_value() << (nBits * (packing() - 1));
+
+    for (endOff = packing(); endOff >= 1; --endOff, --newsize)
+    {
+        if (StorageList::operator[](currElem) & mask)
+        {
+            break;
+        }
+
+        mask >>= nBits;
+    }
+
+    if (size_ == newsize)
+    {
+        return false;
+    }
+
+    size_ = newsize;
+    return false;
+}
+
+
+template<unsigned nBits>
 Foam::labelList Foam::PackedList<nBits>::values() const
 {
     labelList elems(size());
@@ -66,11 +175,12 @@ Foam::labelList Foam::PackedList<nBits>::values() const
 }
 
 
-template<int nBits>
-Foam::Ostream& Foam::PackedList<nBits>::iterator::print(Ostream& os) const
+template<unsigned nBits>
+Foam::Ostream& Foam::PackedList<nBits>::iteratorBase::print(Ostream& os) const
 {
-    os  << "iterator<" << nBits << "> [" << position() << "]"
-        << " elem:" << elem_ << " offset:" << offset_
+    os  << "iterator<" << label(nBits) << "> ["
+        << (index_ * packing() + offset_) << "]"
+        << " index:" << index_ << " offset:" << offset_
         << " value:" << unsigned(*this)
         << nl;
 
@@ -78,10 +188,10 @@ Foam::Ostream& Foam::PackedList<nBits>::iterator::print(Ostream& os) const
 }
 
 
-template<int nBits>
+template<unsigned nBits>
 Foam::Ostream& Foam::PackedList<nBits>::print(Ostream& os) const
 {
-    os  << "PackedList<" << nBits << ">"
+    os  << "PackedList<" << label(nBits) << ">"
         << " max_value:" << max_value()
         << " packing:"   << packing() << nl
         << "values: " << size() << "/" << capacity() << "( ";
@@ -90,27 +200,36 @@ Foam::Ostream& Foam::PackedList<nBits>::print(Ostream& os) const
         os << get(i) << ' ';
     }
 
+    label packLen = packedLength(size_);
+
     os  << ")\n"
-        << "storage: " << storage().size() << "( ";
+        << "storage: " << packLen << "/" << StorageList::size() << "( ";
 
-    label count = size();
+    // mask value for complete chunks
+    unsigned int mask = maskLower(packing());
 
-    forAll(storage(), i)
+    for (label i=0; i < packLen; i++)
     {
-        const PackedStorage& rawBits = storage()[i];
-
-        // create mask for unaddressed bits
-        unsigned int addressed = 0;
+        const StorageType& rawBits = StorageList::operator[](i);
 
-        for (unsigned packI = 0; count && packI < packing(); packI++, count--)
+        // the final storage may not be full, modify mask accordingly
+        if (i+1 == packLen)
         {
-            addressed <<= nBits;
-            addressed |= max_value();
+            unsigned endOff = size_ % packing();
+
+            if (endOff)
+            {
+                mask = maskLower(endOff);
+            }
+            else
+            {
+                continue;
+            }
         }
 
-        for (unsigned int testBit = 0x1 << max_bits(); testBit; testBit >>= 1)
+        for (unsigned int testBit = (1 << max_bits()); testBit; testBit >>= 1)
         {
-            if (testBit & addressed)
+            if (testBit & mask)
             {
                 if (rawBits & testBit)
                 {
@@ -123,7 +242,7 @@ Foam::Ostream& Foam::PackedList<nBits>::print(Ostream& os) const
             }
             else
             {
-                os << '_';
+                os << '.';
             }
         }
         cout << ' ';
@@ -136,15 +255,15 @@ Foam::Ostream& Foam::PackedList<nBits>::print(Ostream& os) const
 
 // * * * * * * * * * * * * * * * Member Operators  * * * * * * * * * * * * * //
 
-template<int nBits>
+template<unsigned nBits>
 void Foam::PackedList<nBits>::operator=(const PackedList<nBits>& lst)
 {
     setCapacity(lst.size());
-    List<PackedStorage>::operator=(lst);
+    StorageList::operator=(lst);
 }
 
 
-template<int nBits>
+template<unsigned nBits>
 void Foam::PackedList<nBits>::operator=(const UList<label>& lst)
 {
     setCapacity(lst.size());
@@ -156,10 +275,9 @@ void Foam::PackedList<nBits>::operator=(const UList<label>& lst)
 }
 
 
-
 // * * * * * * * * * * * * * * * Ostream Operator *  * * * * * * * * * * * * //
 
-//template<int nBits>
+//template<unsigned nBits>
 //Foam::Ostream& ::Foam::operator<<(Ostream& os, const PackedList<nBits>& lst)
 //{
 //    os << lst();
diff --git a/src/OpenFOAM/containers/Lists/PackedList/PackedList.H b/src/OpenFOAM/containers/Lists/PackedList/PackedList.H
index 982b33ee442bfee2e90a7ec6fb9eb86c7bfd5684..b65a658e3a343176672a3af3b8476d2f471df47a 100644
--- a/src/OpenFOAM/containers/Lists/PackedList/PackedList.H
+++ b/src/OpenFOAM/containers/Lists/PackedList/PackedList.H
@@ -28,19 +28,46 @@ Class
 Description
     A Dynamically allocatable list of packed unsigned ints.
 
-    Gets given the number of bits per item.
-
-Note
     The list resizing is similar to DynamicList, thus the methods clear()
     and setSize() behave like their DynamicList counterparts and the methods
     reserve() and setCapacity() can be used to influence the allocation.
 
+    The number of bits per item is specified by the template parameter nBits.
+
+Note
+    In a const context, the '[]' operator simply returns the stored value,
+    with out-of-range elements returned as zero.
+    In a non-const context, the '[]' operator returns an iteratorBase, which
+    may not have a valid reference for out-of-range elements.
+    The iteratorBase class handles the assignment of new values.
+
+    Using the iteratorBase as a proxy allows assignment of values
+    between list elements. Thus the following bit of code works as expected:
+    @code
+        blist[1] = blist[5];     // value assignment, not iterator position
+        blist[2] = blist[5] = 4; // propagates value
+        blist[1] = blist[5] = blist[6];  // propagates value
+    @endcode
+
+    Using get() or the '[]' operator are similarly fast. Looping and reading
+    with an iterator is approx. 15% slower, but can be more flexible.
+
+    Using the set() operator (and the '[]' operator) are marginally slower
+    (approx. 5%) than using an iterator, but the set() method has an
+    advantage that it also returns a bool if the value changed.  This can be
+    useful for branching on changed values.
+
+    @code
+        blist[5] = 4;
+        changed = blist.set(5, 8);
+        if (changed) ...
+    @endcode
+
 SeeAlso
     Foam::DynamicList
 
 ToDo
-    Add checks for bad template parameters (ie, nBits=0, nBits too large).
-    The missing const_iterator might eventually still be needed.
+    Checks for bad template parameters (ie, nBits=0, nBits too large)?
 
 SourceFiles
     PackedListI.H
@@ -59,9 +86,9 @@ namespace Foam
 {
 
 // Forward declaration of friend functions and operators
-template<int nBits> class PackedList;
+template<unsigned nBits> class PackedList;
 
-// template<int nBits>
+// template<unsigned nBits>
 // Ostream& operator<<(Ostream&, const PackedList<nBits>&);
 
 
@@ -75,12 +102,13 @@ TemplateName(PackedList);
                          Class PackedList Declaration
 \*---------------------------------------------------------------------------*/
 
-template <int nBits>
+template<unsigned nBits=1>
 class PackedList
 :
     private List<unsigned int>
 {
-    typedef unsigned int PackedStorage;
+    typedef unsigned int      StorageType;
+    typedef List<StorageType> StorageList;
 
     // Private data
 
@@ -110,10 +138,12 @@ public:
         //- The number of entries per packed storage element
         inline static unsigned int packing();
 
-    // Forward declaration of iterator
-        class iterator;
-        friend class iterator;
+        //- Masking for all bits below the offset
+        inline static unsigned int maskLower(unsigned offset);
+
+    // Forward declaration of iteratorBase
 
+        class iteratorBase;
 
     // Constructors
 
@@ -152,16 +182,27 @@ public:
         inline bool empty() const;
 
         //- Get value at index I.
-        //  Does not auto-vivifies entries.
+        //  Does not auto-vivify entries.
         inline unsigned int get(const label) const;
 
         //- Set value at index I. Return true if value changed.
-        //  Does not auto-vivifies entries.
+        //  Does not auto-vivify entries.
         inline bool set(const label, const unsigned int val);
 
+        //- Return the underlying packed storage
+        inline List<unsigned int>& storage();
+
         //- Return the underlying packed storage
         inline const List<unsigned int>& storage() const;
 
+        //- Count number of bits set, O(log(n))
+        //  Uses the Hamming weight (population count) method
+        //  http://en.wikipedia.org/wiki/Hamming_weight
+        unsigned int count() const;
+
+        //- Trim any trailing zero elements
+        bool trim();
+
         //- Return the values as a labelList
         labelList values() const;
 
@@ -185,7 +226,7 @@ public:
         //- Reserve allocation space for at least this size.
         //  Never shrinks the allocated size.
         //  Optionally provide an initialization value for new elements.
-        inline void reserve(const label, const unsigned int& val = 0);
+        inline void reserve(const label);
 
         //- Clear the list, i.e. set addressable size to zero.
         //  Does not adjust the underlying storage
@@ -204,22 +245,25 @@ public:
         //- Transfer contents to the Xfer container
         inline Xfer<PackedList<nBits> > xfer();
 
+
     // Member operators
 
         //- Append a value at the end of the list
         inline void append(const unsigned int val);
 
+        //- Remove and return the last element
+        inline unsigned int remove();
+
         //- Get value at index I
-        //  Auto-vivifies any new values to zero.
+        //  Does not auto-vivify entries.
         inline unsigned int operator[](const label) const;
 
         //- Set value at index I.
-        //  Returns proxy to perform the actual operation.
-        //  Auto-vivifies any new values to zero.
-        inline iterator operator[](const label);
+        //  Returns iterator to perform the actual operation.
+        //  Does not auto-vivify entries.
+        inline iteratorBase operator[](const label);
 
-        //- Assignment of all entries to the given value.
-        //  Does set on all elements.
+        //- Assignment of all entries to the given value. Takes linear time.
         inline void operator=(const unsigned int val);
 
         //- Assignment operator. Takes linear time.
@@ -230,83 +274,211 @@ public:
 
     // Ostream operator
 
-    //  // Write PackedList to Ostream.
-    //  friend Ostream& operator<< <nBits> (Ostream&, const PackedList<nBits>&);
+//      // Write PackedList to Ostream.
+//      friend Ostream& operator<< <nBits> (Ostream&, const PackedList<nBits>&);
 
+    // Iterators and helpers
 
-    //- The iterator-like class used for PackedList
-    class iterator
-    {
-        friend class PackedList;
+        //- The iterator base for PackedList
+        //  Note: data and functions are protected, to allow reuse by iterator
+        //  and prevent most external usage.
+        class iteratorBase
+        {
+            friend class PackedList;
 
-        // Private Data
+        protected:
 
-        //- Reference to original list
-        PackedList& list_;
+            // Protected Data
 
-        //- Element index within storage
-        unsigned elem_;
+                //- Pointer to original list
+                //  This also lets us use the default bitwise copy/assignment
+                PackedList* list_;
 
-        //- Offset within storage element
-        unsigned offset_;
+                //- Element index within storage
+                unsigned index_;
 
-        //- Return the raw storage element
-        inline PackedStorage& chunk() const;
+                //- Offset within storage element
+                unsigned offset_;
 
-        //- Return the position in the PackedList
-        inline label position() const;
+            // Protected Member Functions
 
-    public:
+                //- Get value as unsigned
+                inline unsigned int get() const;
 
-        // Constructors
+                //- Set value, returning true if changed
+                inline bool set(unsigned int);
 
-        //- Construct from base list and position index
-        inline iterator(const PackedList&, const label i);
+                //- Increment to new position
+                inline void incr();
 
-        // Members
+                //- Decrement to new position
+                inline void decr();
 
-        //- Assign value, returns true if the value changed
-        inline bool operator=(const unsigned int val);
+                //- Move to new position, but not beyond end()
+                inline void seek(const iteratorBase&);
 
-        //- Conversion operator
-        inline operator unsigned int () const;
 
-        //- Conversion operator
-        inline operator bool() const;
+            // Constructors
 
-        // Member operators
+                //- Construct null
+                inline iteratorBase();
 
-        inline void operator=(const iterator&);
-        inline bool operator==(const iterator&) const;
-        inline bool operator!=(const iterator&) const;
+                //- Copy construct
+                inline iteratorBase(const iteratorBase&);
 
-        //- Return referenced value
-        inline unsigned int operator()() const;
+                //- Construct from base list and position index
+                inline iteratorBase(const PackedList*, const label);
 
-        inline iterator& operator++();
-        inline iterator operator++(int);
+        public:
 
-        //- Print value and information
-        Ostream& print(Ostream&) const;
+            // Member Functions
+
+                //- Return true if the element is within addressable range
+                inline bool valid() const;
+
+                //- Move iterator to end() if it would otherwise be out-of-range
+                //  Returns true if the element was already ok
+                inline bool validate();
+
+            // Member Operators
+
+                //- Compare positions
+                inline bool operator==(const iteratorBase&) const;
+                inline bool operator!=(const iteratorBase&) const;
+
+                //- Assign value, not position.
+                //  This allows packed[0] = packed[3] for assigning values
+                inline unsigned int operator=(const iteratorBase&);
+
+                //- Assign value
+                inline unsigned int operator=(const unsigned int val);
+
+                //- Conversion operator
+                inline operator unsigned int () const;
+
+            //- Print value and information
+            Ostream& print(Ostream&) const;
+        };
+
+
+        //- The iterator class used for PackedList
+        class iterator
+        :
+            public iteratorBase
+        {
+
+            //- Should never violate const-ness!
+            void operator=(const const_iterator&);
+
+        public:
+
+            // Constructors
+
+                //- Construct null
+                inline iterator();
+
+                //- Construct from iterator base, eg iter(packedlist[i])
+                inline iterator(const iteratorBase&);
 
-    };
+                //- Construct from base list and position index
+                inline iterator(const PackedList*, const label);
 
+            // Member Operators
 
-    //- iterator set to the begining of the PackedList
-    inline iterator begin();
+                //- Assign from iteratorBase, eg iter = packedlist[i]
+                inline iterator& operator=(const iteratorBase&);
 
-    //- iterator set to beyond the end of the HashTable
-    inline iterator end();
+                //- Return value
+                inline unsigned int operator*() const;
+
+                //- Return value
+                inline unsigned int operator()() const;
+
+                //- Return iteratorBase for assigning values
+                inline iteratorBase& operator*();
+
+                //- Return iteratorBase for assigning values
+                inline iteratorBase& operator()();
+
+                inline iterator& operator++();
+                inline iterator operator++(int);
+
+                inline iterator& operator--();
+                inline iterator operator--(int);
+
+        };
+
+        //- iterator set to the beginning of the PackedList
+        inline iterator begin();
+
+        //- iterator set to beyond the end of the HashTable
+        inline iterator end();
+
+
+        //- The const_iterator for PackedList
+        class const_iterator
+        :
+            public iteratorBase
+        {
+        public:
+
+            // Constructors
+
+                //- Construct null
+                inline const_iterator();
+
+                //- Construct from iterator base
+                inline const_iterator(const iteratorBase&);
+
+                //- Construct from base list and position index
+                inline const_iterator(const PackedList*, const label);
+
+                //- Construct from non-const iterator
+                inline const_iterator(const iterator&);
+
+            // Member operators
+
+                //- Assign from iteratorBase or derived
+                //  eg, iter = packedlist[i] or iter = [non-const]list.begin()
+                inline const_iterator& operator=(const iteratorBase&);
+
+                //- Return referenced value directly
+                inline unsigned int operator*() const;
+
+                //- Return referenced value directly
+                inline unsigned int operator()() const;
+
+                inline const_iterator& operator++();
+                inline const_iterator operator++(int);
+
+                inline const_iterator& operator--();
+                inline const_iterator operator--(int);
+
+        };
+
+
+        //- const_iterator set to the beginning of the PackedList
+        inline const_iterator cbegin() const;
+
+        //- const_iterator set to beyond the end of the PackedList
+        inline const_iterator cend() const;
+
+        //- const_iterator set to the beginning of the PackedList
+        inline const_iterator begin() const;
+
+        //- const_iterator set to beyond the end of the PackedList
+        inline const_iterator end() const;
 
 };
 
+
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 } // End namespace Foam
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-#   include "PackedListI.H"
+#include "PackedListI.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
diff --git a/src/OpenFOAM/containers/Lists/PackedList/PackedListName.C b/src/OpenFOAM/containers/Lists/PackedList/PackedListCore.C
similarity index 100%
rename from src/OpenFOAM/containers/Lists/PackedList/PackedListName.C
rename to src/OpenFOAM/containers/Lists/PackedList/PackedListCore.C
diff --git a/src/OpenFOAM/containers/Lists/PackedList/PackedListI.H b/src/OpenFOAM/containers/Lists/PackedList/PackedListI.H
index 94ec883daa5ad528a96acea3975205d9acb62eb8..07e6d06208388a6dc3774fbf042fef214d0b431b 100644
--- a/src/OpenFOAM/containers/Lists/PackedList/PackedListI.H
+++ b/src/OpenFOAM/containers/Lists/PackedList/PackedListI.H
@@ -26,38 +26,46 @@ License
 \*---------------------------------------------------------------------------*/
 
 #include "error.H"
+#include <climits>
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-template<int nBits>
+template<unsigned nBits>
 inline unsigned int Foam::PackedList<nBits>::max_bits()
 {
-    return sizeof(PackedStorage)*8 - 1;
+    return sizeof(StorageType)*CHAR_BIT - 1;
 }
 
 
-template<int nBits>
+template<unsigned nBits>
 inline unsigned int Foam::PackedList<nBits>::max_value()
 {
-    return ((1u << nBits) - 1);
+    return (1 << nBits) - 1;
 }
 
 
-template<int nBits>
+template<unsigned nBits>
 inline unsigned int Foam::PackedList<nBits>::packing()
 {
-    return sizeof(PackedStorage)*8 / nBits;
+    return sizeof(StorageType)*CHAR_BIT / nBits;
 }
 
 
-template<int nBits>
+template<unsigned nBits>
+inline unsigned int Foam::PackedList<nBits>::maskLower(unsigned offset)
+{
+    return (1 << (nBits * offset)) - 1;
+}
+
+
+template<unsigned nBits>
 inline Foam::label Foam::PackedList<nBits>::packedLength(const label nElem)
 {
     return (nElem + packing() - 1) / packing();
 }
 
 
-template<int nBits>
+template<unsigned nBits>
 inline void Foam::PackedList<nBits>::checkIndex(const label i) const
 {
     if (!size_)
@@ -77,38 +85,38 @@ inline void Foam::PackedList<nBits>::checkIndex(const label i) const
 
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
-template<int nBits>
+template<unsigned nBits>
 inline Foam::PackedList<nBits>::PackedList()
 :
-    List<PackedStorage>(),
+    StorageList(),
     size_(0)
 {}
 
 
-template<int nBits>
+template<unsigned nBits>
 inline Foam::PackedList<nBits>::PackedList(const label size)
 :
-    List<PackedStorage>(packedLength(size), 0u),
+    StorageList(packedLength(size), 0u),
     size_(size)
 {}
 
 
-template<int nBits>
+template<unsigned nBits>
 inline Foam::PackedList<nBits>::PackedList(const PackedList<nBits>& lst)
 :
-    List<PackedStorage>(lst),
+    StorageList(lst),
     size_(lst.size())
 {}
 
 
-template<int nBits>
+template<unsigned nBits>
 inline Foam::PackedList<nBits>::PackedList(const Xfer<PackedList<nBits> >& lst)
 {
     transfer(lst());
 }
 
 
-template<int nBits>
+template<unsigned nBits>
 inline Foam::autoPtr<Foam::PackedList<nBits> >
 Foam::PackedList<nBits>::clone() const
 {
@@ -118,180 +126,555 @@ Foam::PackedList<nBits>::clone() const
 
 // * * * * * * * * * * * * * * * * Iterators * * * * * * * * * * * * * * * * //
 
-template<int nBits>
-inline Foam::PackedList<nBits>::iterator::iterator
+// iteratorBase
+
+template<unsigned nBits>
+inline Foam::PackedList<nBits>::iteratorBase::iteratorBase()
+:
+    list_(0),
+    index_(0),
+    offset_(0)
+{}
+
+
+template<unsigned nBits>
+inline Foam::PackedList<nBits>::iteratorBase::iteratorBase
+(
+    const iteratorBase& iter
+)
+:
+    list_(iter.list_),
+    index_(iter.index_),
+    offset_(iter.offset_)
+{}
+
+
+template<unsigned nBits>
+inline Foam::PackedList<nBits>::iteratorBase::iteratorBase
 (
-    const PackedList<nBits>& lst,
+    const PackedList<nBits>* lst,
     const label i
 )
 :
-    list_(const_cast<PackedList<nBits>&>(lst)),
-    elem_(i / packing()),
+    list_(const_cast<PackedList<nBits>*>(lst)),
+    index_(i / packing()),
     offset_(i % packing())
 {}
 
 
-template<int nBits>
-inline void Foam::PackedList<nBits>::iterator::operator=
+template<unsigned nBits>
+inline unsigned int
+Foam::PackedList<nBits>::iteratorBase::get() const
+{
+    const unsigned int& stored = list_->StorageList::operator[](index_);
+    return (stored >> (nBits * offset_)) & max_value();
+}
+
+
+template<unsigned nBits>
+inline bool
+Foam::PackedList<nBits>::iteratorBase::set(const unsigned int val)
+{
+    unsigned int& stored = list_->StorageList::operator[](index_);
+    const unsigned int prev = stored;
+
+    const unsigned int startBit = nBits * offset_;
+    const unsigned int maskNew  = max_value() << startBit;
+
+    if (val & ~max_value())
+    {
+#       ifdef DEBUGList
+        FatalErrorIn("PackedList<T>::iteratorBase::set(const unsigned int)")
+            << "value " << label(val)
+w            << " out-of-range 0 ... " << label(max_value())
+            << " representable by " << nBits << " bits"
+            << abort(FatalError);
+#       endif
+
+        // treat overflow as max_value
+        stored |= maskNew;
+    }
+    else
+    {
+        stored = (stored & ~maskNew) | (maskNew & (val << startBit));
+    }
+
+    return prev != stored;
+}
+
+
+
+template<unsigned nBits>
+inline void
+Foam::PackedList<nBits>::iteratorBase::incr()
+{
+    offset_++;
+    if (offset_ >= packing())
+    {
+        offset_ = 0;
+        index_++;
+    }
+}
+
+
+template<unsigned nBits>
+inline void
+Foam::PackedList<nBits>::iteratorBase::decr()
+{
+    if (!offset_)
+    {
+        offset_ = packing();
+        index_--;
+    }
+    offset_--;
+}
+
+
+template<unsigned nBits>
+inline void
+Foam::PackedList<nBits>::iteratorBase::seek
 (
-    const iterator& iter
+    const iteratorBase& iter
 )
 {
-    elem_ = iter.elem_;
+    list_   = iter.list_;
+    index_  = iter.index_;
     offset_ = iter.offset_;
+
+    this->validate();
+}
+
+
+template<unsigned nBits>
+inline bool
+Foam::PackedList<nBits>::iteratorBase::valid() const
+{
+    label elemI = offset_ + index_ * packing();
+    return (elemI < list_->size_);
+}
+
+
+template<unsigned nBits>
+inline bool
+Foam::PackedList<nBits>::iteratorBase::validate()
+{
+    // avoid going past end()
+    unsigned endIdx = list_->size_ / packing();
+    unsigned endOff = list_->size_ % packing();
+
+    if (index_ > endIdx || (index_ == endIdx && offset_ > endOff))
+    {
+        index_  = endIdx;
+        offset_ = endOff;
+
+        return false;
+    }
+    else
+    {
+        return true;
+    }
 }
 
 
-template<int nBits>
-inline bool Foam::PackedList<nBits>::iterator::operator==
+template<unsigned nBits>
+inline bool Foam::PackedList<nBits>::iteratorBase::operator==
 (
-    const iterator& iter
+    const iteratorBase& iter
 ) const
 {
-    return elem_ == iter.elem_ && offset_ == iter.offset_;
+    return this->index_ == iter.index_ && this->offset_ == iter.offset_;
 }
 
 
-template<int nBits>
-inline bool Foam::PackedList<nBits>::iterator::operator!=
+template<unsigned nBits>
+inline bool Foam::PackedList<nBits>::iteratorBase::operator!=
 (
-    const iterator& iter
+    const iteratorBase& iter
 ) const
 {
-    return !(operator==(iter));
+    return this->index_ != iter.index_ || this->offset_ != iter.offset_;
 }
 
 
-template<int nBits>
-inline bool Foam::PackedList<nBits>::iterator::operator=
+template<unsigned nBits>
+inline unsigned int
+Foam::PackedList<nBits>::iteratorBase::operator=(const iteratorBase& iter)
+{
+    const unsigned int val = iter.get();
+    this->set(val);
+    return val;
+}
+
+
+template<unsigned nBits>
+inline unsigned int
+Foam::PackedList<nBits>::iteratorBase::operator=(const unsigned int val)
+{
+#   ifdef DEBUGList
+    // lazy evaluation would be nice to keep, but really slows things down
+    label minsize = 1 + offset_ + index_ * packing();
+    if (minsize > list_->size_)
+    {
+        list_->resize(minsize);
+    }
+#endif
+
+    this->set(val);
+    return val;
+}
+
+
+template<unsigned nBits>
+inline Foam::PackedList<nBits>::iteratorBase::operator
+unsigned int () const
+{
+#   ifdef DEBUGList
+    // lazy evaluation would be nice to keep, but really slows things down
+    label minsize = 1 + offset_ + index_ * packing();
+    if (minsize > list_->size_)
+    {
+        return 0;
+    }
+#endif
+
+    return this->get();
+}
+
+
+// const_iterator, iterator
+
+template<unsigned nBits>
+inline Foam::PackedList<nBits>::iterator::iterator()
+:
+    iteratorBase()
+{}
+
+
+template<unsigned nBits>
+inline Foam::PackedList<nBits>::const_iterator::const_iterator()
+:
+    iteratorBase()
+{}
+
+
+template<unsigned nBits>
+inline Foam::PackedList<nBits>::iterator::iterator
 (
-    const unsigned int val
+    const iteratorBase& iter
 )
+:
+    iteratorBase(iter)
 {
-    const unsigned int startBit = nBits * offset_;
-    const unsigned int mask = max_value() << startBit;
-
-    unsigned int& stored = chunk();
-    const unsigned int old = stored;
+    this->validate();
+}
 
-    stored &= ~mask;
-    stored |= (val << startBit) & mask;
 
-    return (old != stored);
+template<unsigned nBits>
+inline Foam::PackedList<nBits>::const_iterator::const_iterator
+(
+    const iteratorBase& iter
+)
+:
+    iteratorBase(iter)
+{
+    this->validate();
 }
 
 
-template<int nBits>
-inline Foam::label Foam::PackedList<nBits>::iterator::position() const
+template<unsigned nBits>
+inline Foam::PackedList<nBits>::iterator::iterator
+(
+    const PackedList<nBits>* lst,
+    const label i
+)
+:
+    iteratorBase(lst, i)
+{}
+
+
+template<unsigned nBits>
+inline Foam::PackedList<nBits>::const_iterator::const_iterator
+(
+    const PackedList<nBits>* lst,
+    const label i
+)
+:
+    iteratorBase(lst, i)
+{}
+
+
+template<unsigned nBits>
+inline Foam::PackedList<nBits>::const_iterator::const_iterator
+(
+    const iterator& iter
+)
+:
+    iteratorBase(static_cast<const iteratorBase&>(iter))
+{}
+
+
+template<unsigned nBits>
+inline typename Foam::PackedList<nBits>::iterator&
+Foam::PackedList<nBits>::iterator::operator=(const iteratorBase& iter)
 {
-    return (elem_ * packing() + offset_);
+    this->seek(iter);
+    return *this;
 }
 
 
-template<int nBits>
-inline unsigned int& Foam::PackedList<nBits>::iterator::chunk() const
+template<unsigned nBits>
+inline typename Foam::PackedList<nBits>::const_iterator&
+Foam::PackedList<nBits>::const_iterator::operator=(const iteratorBase& iter)
 {
-    return list_.List<PackedStorage>::operator[](elem_);
+    this->seek(iter);
+    return *this;
 }
 
 
-template<int nBits>
+template<unsigned nBits>
 inline typename Foam::PackedList<nBits>::iterator&
 Foam::PackedList<nBits>::iterator::operator++()
 {
-    if (position() < list_.size())
-    {
-        offset_++;
-        if (offset_ >= packing())
-        {
-            elem_++;
-            offset_ = 0;
-        }
-    }
+    this->incr();
+    return *this;
+}
+
 
+template<unsigned nBits>
+inline typename Foam::PackedList<nBits>::const_iterator&
+Foam::PackedList<nBits>::const_iterator::operator++()
+{
+    this->incr();
     return *this;
 }
 
 
-template<int nBits>
+template<unsigned nBits>
 inline typename Foam::PackedList<nBits>::iterator
 Foam::PackedList<nBits>::iterator::operator++(int)
 {
     iterator old = *this;
-    ++*this;
+    this->incr();
     return old;
 }
 
 
-template<int nBits>
-inline unsigned int
-Foam::PackedList<nBits>::iterator::operator()() const
+template<unsigned nBits>
+inline typename Foam::PackedList<nBits>::const_iterator
+Foam::PackedList<nBits>::const_iterator::operator++(int)
 {
-    return (chunk() >> (nBits * offset_)) & max_value();
+    const_iterator old = *this;
+    this->incr();
+    return old;
 }
 
 
-template<int nBits>
-inline Foam::PackedList<nBits>::iterator::operator
-unsigned int () const
+template<unsigned nBits>
+inline typename Foam::PackedList<nBits>::iterator&
+Foam::PackedList<nBits>::iterator::operator--()
 {
-    return (chunk() >> (nBits * offset_)) & max_value();
+    this->decr();
+    return *this;
 }
 
 
-template<int nBits>
-inline Foam::PackedList<nBits>::iterator::operator
-bool() const
+template<unsigned nBits>
+inline typename Foam::PackedList<nBits>::const_iterator&
+Foam::PackedList<nBits>::const_iterator::operator--()
 {
-    return !!(chunk() >> (nBits * offset_)) & max_value();
+    this->decr();
+    return *this;
 }
 
 
-template<int nBits>
+template<unsigned nBits>
+inline typename Foam::PackedList<nBits>::iterator
+Foam::PackedList<nBits>::iterator::operator--(int)
+{
+    iterator old = *this;
+    this->decr();
+    return old;
+}
+
+
+template<unsigned nBits>
+inline typename Foam::PackedList<nBits>::const_iterator
+Foam::PackedList<nBits>::const_iterator::operator--(int)
+{
+    const_iterator old = *this;
+    this->decr();
+    return old;
+}
+
+
+template<unsigned nBits>
+inline typename Foam::PackedList<nBits>::iteratorBase&
+Foam::PackedList<nBits>::iterator::operator*()
+{
+    return static_cast<iteratorBase&>(*this);
+}
+
+
+template<unsigned nBits>
+inline typename Foam::PackedList<nBits>::iteratorBase&
+Foam::PackedList<nBits>::iterator::operator()()
+{
+    return static_cast<iteratorBase&>(*this);
+}
+
+
+template<unsigned nBits>
+inline unsigned int
+Foam::PackedList<nBits>::const_iterator::operator*() const
+{
+    return this->get();
+}
+
+
+template<unsigned nBits>
+inline unsigned int
+Foam::PackedList<nBits>::const_iterator::operator()() const
+{
+    return this->get();
+}
+
+
+template<unsigned nBits>
 inline typename Foam::PackedList<nBits>::iterator
 Foam::PackedList<nBits>::begin()
 {
-    return iterator(*this, 0);
+    return iterator(this, 0);
+}
+
+
+template<unsigned nBits>
+inline typename Foam::PackedList<nBits>::const_iterator
+Foam::PackedList<nBits>::begin() const
+{
+    return const_iterator(this, 0);
 }
 
 
-template<int nBits>
+template<unsigned nBits>
+inline typename Foam::PackedList<nBits>::const_iterator
+Foam::PackedList<nBits>::cbegin() const
+{
+    return const_iterator(this, 0);
+}
+
+
+template<unsigned nBits>
 inline typename Foam::PackedList<nBits>::iterator
 Foam::PackedList<nBits>::end()
 {
-    return iterator(*this, size());
+    return iterator(this, this->size());
+}
+
+
+template<unsigned nBits>
+inline typename Foam::PackedList<nBits>::const_iterator
+Foam::PackedList<nBits>::end() const
+{
+    return const_iterator(this, this->size());
+}
+
+
+template<unsigned nBits>
+inline typename Foam::PackedList<nBits>::const_iterator
+Foam::PackedList<nBits>::cend() const
+{
+    return const_iterator(this, this->size());
 }
 
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
-template<int nBits>
+template<unsigned nBits>
 inline Foam::label Foam::PackedList<nBits>::size() const
 {
     return size_;
 }
 
 
-template<int nBits>
+template<unsigned nBits>
 inline bool Foam::PackedList<nBits>::empty() const
 {
     return !size_;
 }
 
 
-template<int nBits>
+template<unsigned nBits>
 inline void Foam::PackedList<nBits>::resize
 (
     const label nElem,
     const unsigned int& val
 )
 {
-    reserve(nElem, val);
+    reserve(nElem);
+
+    if (nElem > size_)
+    {
+        // fill new elements or newly exposed elements
+        if (size_)
+        {
+            // fill value for complete chunks
+            unsigned int fill = val;
+
+            if (fill & ~max_value())
+            {
+#               ifdef DEBUGList
+                FatalErrorIn("PackedList<T>::resize(label, const unsigned int)")
+                    << "value " << label(val)
+                    << " out-of-range 0 ... " << label(max_value())
+                    << " representable by " << nBits << " bits"
+                    << abort(FatalError);
+#               endif
+
+                // treat overflow as max_value, fill everything
+                fill = ~0;
+            }
+            else
+            {
+                for (unsigned int i = 1; i < packing(); ++i)
+                {
+                    fill |= (fill << nBits);
+                }
+            }
+
+            unsigned begIdx = size_ / packing();
+            unsigned begOff = size_ % packing();
+            unsigned endIdx = nElem / packing();
+
+            // partial chunk, preserve existing value
+            if (begOff)
+            {
+                unsigned int maskOld = maskLower(begOff);
+
+                StorageList::operator[](begIdx) &= maskOld;
+                StorageList::operator[](begIdx) |= ~maskOld & fill;
+
+                // continue with the next chunk
+                begIdx++;
+            }
+
+            // fill in complete elements
+            while (begIdx < endIdx)
+            {
+                StorageList::operator[](begIdx++) = fill;
+            }
+        }
+        else
+        {
+            // no original size - simply flood-fill
+            operator=(val);
+        }
+    }
+
     size_ = nElem;
 }
 
 
-template<int nBits>
+template<unsigned nBits>
 inline void Foam::PackedList<nBits>::setSize
 (
     const label newSize,
@@ -303,144 +686,129 @@ inline void Foam::PackedList<nBits>::setSize
 
 
 
-template<int nBits>
+template<unsigned nBits>
 inline Foam::label Foam::PackedList<nBits>::capacity() const
 {
-    return packing() * List<PackedStorage>::size();
+    return packing() * StorageList::size();
 }
 
 
-template<int nBits>
+template<unsigned nBits>
 inline void Foam::PackedList<nBits>::setCapacity(const label nElem)
 {
-    List<PackedStorage>::setSize(packedLength(nElem), 0u);
+    StorageList::setSize(packedLength(nElem), 0u);
 
-    // truncates addressable section too
+    // truncate addressed size too?
     if (size_ > nElem)
     {
-#       ifdef DEBUGList
-        // clear old values (purely cosmetics for string output)
-        for (label i = nElem; i < size_; i++)
-        {
-            set(i, 0);
-        }
-#       endif
         size_ = nElem;
     }
-    else
-    {
-        // fill new elements
-        for (label i = size_; i < nElem; i++)
-        {
-            set(i, 0);
-        }
-    }
 }
 
 
-template<int nBits>
+template<unsigned nBits>
 inline void Foam::PackedList<nBits>::reserve
 (
-    const label nElem,
-    const unsigned int& val
+    const label nElem
 )
 {
     label len = packedLength(nElem);
 
     // need more capacity?
-    if (len > List<PackedStorage>::size())
+    if (len > StorageList::size())
     {
-        List<PackedStorage>::setSize(len, 0);
-    }
-
-    // fill new elements
-    for (label i = size_; i < nElem; i++)
-    {
-        set(i, val);
+        StorageList::setSize(len, 0u);
     }
 }
 
 
-template<int nBits>
+template<unsigned nBits>
 inline void Foam::PackedList<nBits>::clear()
 {
     size_ = 0;
 }
 
 
-template<int nBits>
+template<unsigned nBits>
 inline void Foam::PackedList<nBits>::clearStorage()
 {
-    List<PackedStorage>::clear();
+    StorageList::clear();
     size_ = 0;
 }
 
 
-template<int nBits>
+template<unsigned nBits>
 inline void Foam::PackedList<nBits>::shrink()
 {
     label len = packedLength(size_);
 
     // we have unused space?
-    if (len < List<PackedStorage>::size())
+    if (len < StorageList::size())
     {
-        List<PackedStorage>::setSize(len);
+        StorageList::setSize(len);
     }
 }
 
-template<int nBits>
+template<unsigned nBits>
+inline Foam::List<unsigned int>&
+Foam::PackedList<nBits>::storage()
+{
+    return static_cast<StorageList&>(*this);
+}
+
+
+template<unsigned nBits>
 inline const Foam::List<unsigned int>&
 Foam::PackedList<nBits>::storage() const
 {
-    return static_cast<const List<PackedStorage>&>(*this);
+    return static_cast<const StorageList&>(*this);
 }
 
 
-template<int nBits>
+template<unsigned nBits>
 inline void Foam::PackedList<nBits>::transfer(PackedList<nBits>& lst)
 {
     size_ = lst.size_;
     lst.size_ = 0;
 
-    List<PackedStorage>::transfer(lst);
+    StorageList::transfer(lst);
 }
 
 
-template<int nBits>
-inline Foam::Xfer<Foam::PackedList<nBits> >
+template<unsigned nBits>
+inline Foam::Xfer< Foam::PackedList<nBits> >
 Foam::PackedList<nBits>::xfer()
 {
     return xferMove(*this);
 }
 
 
-template<int nBits>
+template<unsigned nBits>
 inline unsigned int Foam::PackedList<nBits>::get(const label i) const
 {
 #   ifdef DEBUGList
     checkIndex(i);
 #   endif
 
-    return iterator(*this, i)();
+    return iteratorBase(this, i).get();
 }
 
 
-template<int nBits>
+template<unsigned nBits>
 inline unsigned int Foam::PackedList<nBits>::operator[](const label i) const
 {
-    if (i >= size_)
+    if (i < size_)
     {
-        setSize(i + 1);
-        return 0;
+        return iteratorBase(this, i).get();
     }
     else
     {
-        return iterator(*this, i)();
+        return 0;
     }
 }
 
 
-template<int nBits>
+template<unsigned nBits>
 inline bool Foam::PackedList<nBits>::set
 (
     const label i,
@@ -459,48 +827,82 @@ inline bool Foam::PackedList<nBits>::set
             << abort(FatalError);
     }
 #   endif
-
-    return (iterator(*this, i) = val);
+    return iteratorBase(this, i).set(val);
 }
 
 
-template<int nBits>
+template<unsigned nBits>
 inline void Foam::PackedList<nBits>::append(const unsigned int val)
 {
     label elemI = size_;
     reserve(elemI + 1);
     size_++;
 
-    iterator(*this, elemI) = val;
+    iteratorBase(this, elemI).set(val);
 }
 
 
-template<int nBits>
-inline typename Foam::PackedList<nBits>::iterator
-Foam::PackedList<nBits>::operator[](const label i)
+template<unsigned nBits>
+inline unsigned int Foam::PackedList<nBits>::remove()
 {
-    if (i >= size_)
+    if (!size_)
     {
-        setSize(i + 1);
+        FatalErrorIn
+        (
+            "Foam::PackedList<nBits>::remove()"
+        )   << "List is empty" << abort(FatalError);
     }
 
-    return iterator(*this, i);
+    label elemI = size_ - 1;
+    const unsigned int val = iteratorBase(this, elemI).get();
+    resize(elemI);
+
+    return val;
 }
 
 
-template<int nBits>
+template<unsigned nBits>
+inline typename Foam::PackedList<nBits>::iteratorBase
+Foam::PackedList<nBits>::operator[](const label i)
+{
+    return iteratorBase(this, i);
+}
+
+
+// specialization for nBits=1 isn't worth the bother
+template<unsigned nBits>
 inline void Foam::PackedList<nBits>::operator=(const unsigned int val)
 {
     if (val)
     {
-        forAll(*this, elemI)
+        unsigned int fill = val;
+
+        if (fill & ~max_value())
         {
-            set(elemI, val);
+#           ifdef DEBUGList
+            FatalErrorIn("PackedList<T>::operator=(const unsigned int)")
+                << "value " << label(val)
+                << " out-of-range 0 ... " << label(max_value())
+                << " representable by " << nBits << " bits"
+                << abort(FatalError);
+#           endif
+
+            // treat overflow as max_value
+            fill = ~0;
         }
+        else
+        {
+            for (unsigned int i = 1; i < packing(); ++i)
+            {
+                fill |= (fill << nBits);
+            }
+        }
+
+        StorageList::operator=(fill);
     }
     else
     {
-        List<PackedStorage>::operator=(val);
+        StorageList::operator=(0u);
     }
 }
 
diff --git a/src/OpenFOAM/db/IOobject/IOobject.C b/src/OpenFOAM/db/IOobject/IOobject.C
index aadd9c24648e685f9eedb2d1f0b3eb7016b42361..fc1c023874829c4d397c0933df993f21d014ea24 100644
--- a/src/OpenFOAM/db/IOobject/IOobject.C
+++ b/src/OpenFOAM/db/IOobject/IOobject.C
@@ -98,6 +98,37 @@ Foam::IOobject::IOobject
 }
 
 
+Foam::IOobject::IOobject
+(
+    const fileName& path,
+    const objectRegistry& registry,
+    readOption ro,
+    writeOption wo,
+    bool registerObject
+)
+:
+    name_(),
+    headerClassName_(typeName),
+    note_(),
+    instance_(),
+    local_(),
+    db_(registry),
+    rOpt_(ro),
+    wOpt_(wo),
+    registerObject_(registerObject),
+    objState_(GOOD)
+{
+    path.IOobjectComponents(instance_, local_, name_);
+
+    if (objectRegistry::debug)
+    {
+        Info<< "Constructing IOobject called " << name_
+            << " of type " << headerClassName_
+            << endl;
+    }
+}
+
+
 // * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * * //
 
 Foam::IOobject::~IOobject()
diff --git a/src/OpenFOAM/db/IOobject/IOobject.H b/src/OpenFOAM/db/IOobject/IOobject.H
index 38c76a2b3808717d3c8a91b796a3c8297c8ab7f8..6ee171423a01e5be97f88a731113dc4d8ebeb067 100644
--- a/src/OpenFOAM/db/IOobject/IOobject.H
+++ b/src/OpenFOAM/db/IOobject/IOobject.H
@@ -193,6 +193,16 @@ public:
             bool registerObject=true
         );
 
+        //- Construct from path, registry, io options
+        IOobject
+        (
+            const fileName& path,
+            const objectRegistry& registry,
+            readOption r=NO_READ,
+            writeOption w=NO_WRITE,
+            bool registerObject=true
+        );
+
         //- Clone
         Foam::autoPtr<IOobject> clone() const
         {
diff --git a/src/OpenFOAM/db/Time/Time.H b/src/OpenFOAM/db/Time/Time.H
index 2d5391990e69f204c58c3a3d1c0445ffee91cc2d..4d3268423de30a2f30dd6cf09c458c22b514bf94 100644
--- a/src/OpenFOAM/db/Time/Time.H
+++ b/src/OpenFOAM/db/Time/Time.H
@@ -283,10 +283,11 @@ public:
 
             //- Return the location of "dir" containing the file "name".
             //  (Used in reading mesh data)
+            //  If name is null search for a directory "dir"
             word findInstance
             (
                 const fileName& dir,
-                const word& name,
+                const word& name = word::null,
                 const IOobject::readOption rOpt = IOobject::MUST_READ
             ) const;
 
diff --git a/src/OpenFOAM/db/Time/findInstance.C b/src/OpenFOAM/db/Time/findInstance.C
index 348ad4ebe55536b0c732415c56a2f06749ba0ca0..7b8bddd12029c38396f43e26ee4c3e3545725b25 100644
--- a/src/OpenFOAM/db/Time/findInstance.C
+++ b/src/OpenFOAM/db/Time/findInstance.C
@@ -23,7 +23,9 @@ License
     Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 
 Description
-    Return the location of "directory" containing the file "name".
+    If "name" is empty: return the location of "directory"
+    If "name" is not empty: return the location of "directory" containing the
+    file "name".
     Used in reading mesh data.
 
 \*---------------------------------------------------------------------------*/
@@ -43,15 +45,20 @@ Foam::word Foam::Time::findInstance
     // Is the mesh data in the current time directory ?
     if
     (
-        file(path()/timeName()/dir/name)
-     && IOobject(name, timeName(), dir, *this).headerOk()
+        (name.empty() && Foam::dir(path()/timeName()/dir))
+     ||
+        (
+           !name.empty()
+         && file(path()/timeName()/dir/name)
+         && IOobject(name, timeName(), dir, *this).headerOk()
+        )
     )
     {
         if (debug)
         {
-            Info<< "Time::findInstance(const word& dir, const word& name) : "
-                << "reading " << name
-                << " from " << timeName()/dir
+            Info<< "Time::findInstance(const word&, const word&) : "
+                << "found " << name
+                << " in " << timeName()/dir
                 << endl;
         }
 
@@ -81,16 +88,21 @@ Foam::word Foam::Time::findInstance
         {
             if
             (
-                file(path()/ts[j].name()/dir/name)
-             && IOobject(name, ts[j].name(), dir, *this).headerOk()
+                (name.empty() && Foam::dir(path()/ts[j].name()/dir))
+             ||
+                (
+                   !name.empty()
+                 && file(path()/ts[j].name()/dir/name)
+                 && IOobject(name, ts[j].name(), dir, *this).headerOk()
+                )
             )
             {
                 if (debug)
                 {
-                    Info<< "Time::findInstance(const word& dir, "
-                        << "const word& name) : "
-                        << "reading " << name
-                        << " from " << ts[j].name()/dir
+                    Info<< "Time::findInstance(const word&, "
+                        << "const word&) : "
+                        << "found " << name
+                        << " in " << ts[j].name()/dir
                         << endl;
                 }
 
@@ -109,16 +121,20 @@ Foam::word Foam::Time::findInstance
 
     if
     (
-        file(path()/constant()/dir/name)
-     && IOobject(name, constant(), dir, *this).headerOk()
+        (name.empty() && Foam::dir(path()/constant()/dir))
+     || (
+            !name.empty()
+         && file(path()/constant()/dir/name)
+         && IOobject(name, constant(), dir, *this).headerOk()
+        )
     )
     {
         if (debug)
         {
-            Info<< "Time::findInstance(const word& dir, "
-                << "const word& name) : "
-                << "reading " << name
-                << " from " << constant()/dir
+            Info<< "Time::findInstance(const word&, "
+                << "const word&) : "
+                << "found " << name
+                << " in " << constant()/dir
                 << endl;
         }
 
@@ -127,7 +143,7 @@ Foam::word Foam::Time::findInstance
 
     if (rOpt == IOobject::MUST_READ)
     {
-        FatalErrorIn("Time::findInstance(const word& dir, const word& name)")
+        FatalErrorIn("Time::findInstance(const word&, const word&)")
             << "Cannot find file \"" << name << "\" in directory "
             << constant()/dir
             << exit(FatalError);
@@ -136,4 +152,5 @@ Foam::word Foam::Time::findInstance
     return constant();
 }
 
+
 // ************************************************************************* //
diff --git a/src/OpenFOAM/meshes/polyMesh/polyBoundaryMesh/polyBoundaryMesh.C b/src/OpenFOAM/meshes/polyMesh/polyBoundaryMesh/polyBoundaryMesh.C
index 261a952b064f05c9efaf2058e92e53f5896dcb8d..ca11a21ec9718999808374c92b85f9a80b919cb2 100644
--- a/src/OpenFOAM/meshes/polyMesh/polyBoundaryMesh/polyBoundaryMesh.C
+++ b/src/OpenFOAM/meshes/polyMesh/polyBoundaryMesh/polyBoundaryMesh.C
@@ -538,7 +538,7 @@ bool Foam::polyBoundaryMesh::checkDefinition(const bool report) const
 
     forAll (bm, patchI)
     {
-        if (bm[patchI].start() != nextPatchStart)
+        if (bm[patchI].start() != nextPatchStart && !boundaryError)
         {
             boundaryError = true;
 
@@ -547,7 +547,9 @@ bool Foam::polyBoundaryMesh::checkDefinition(const bool report) const
                 << " of type " <<  bm[patchI].type()
                 << ". The patch should start on face no " << nextPatchStart
                 << " and the patch specifies " << bm[patchI].start()
-                << "." << endl;
+                << "." << endl
+                << "Possibly consecutive patches have this same problem."
+                << " Suppressing future warnings." << endl;
         }
 
         nextPatchStart += bm[patchI].size();
diff --git a/src/OpenFOAM/meshes/polyMesh/polyPatches/constraint/cyclic/cyclicPolyPatch.H b/src/OpenFOAM/meshes/polyMesh/polyPatches/constraint/cyclic/cyclicPolyPatch.H
index 5b349a4a7594309504bf93107cd3f577d46887e2..8bd2bff42f27ae16de9ff025a1cc1342468f4122 100644
--- a/src/OpenFOAM/meshes/polyMesh/polyPatches/constraint/cyclic/cyclicPolyPatch.H
+++ b/src/OpenFOAM/meshes/polyMesh/polyPatches/constraint/cyclic/cyclicPolyPatch.H
@@ -60,8 +60,6 @@ SourceFiles
 namespace Foam
 {
 
-class patchZones;
-
 /*---------------------------------------------------------------------------*\
                       Class cyclicPolyPatch Declaration
 \*---------------------------------------------------------------------------*/
diff --git a/src/OpenFOAM/meshes/polyMesh/polyPatches/polyPatch/polyPatch.H b/src/OpenFOAM/meshes/polyMesh/polyPatches/polyPatch/polyPatch.H
index a0e9a99b644c95d16a2940f4c5ec8340636c73e2..b43e4db9ff5f355672432d03e04a391aee18ac8c 100644
--- a/src/OpenFOAM/meshes/polyMesh/polyPatches/polyPatch/polyPatch.H
+++ b/src/OpenFOAM/meshes/polyMesh/polyPatches/polyPatch/polyPatch.H
@@ -26,21 +26,14 @@ Class
     Foam::polyPatch
 
 Description
-    A patch is a list of labels, which address the faces in the global face
-    list. Based on the global faces, the patch can calculate its own edge.
+    A patch is a list of labels that address the faces in the global face list.
+
+    The patch can calculate its own edges based on the global faces.
     Patch also contains all addressing between the faces.
 
 SourceFiles
     polyPatch.C
-    calcPolyPatchAddressing.C
-    calcPolyPatchFaceCells.C
-    calcPolyPatchIntBdryEdges.C
-    calcPolyPatchMeshEdges.C
-    calcPolyPatchMeshData.C
-    calcPolyPatchPointAddressing.C
-    clearPolyPatch.C
     newPolyPatch.C
-    polyPatchTools.C
 
 \*---------------------------------------------------------------------------*/
 
@@ -59,10 +52,9 @@ namespace Foam
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-class polyBoundaryMesh;
-
 // Forward declaration of friend functions and operators
 
+class polyBoundaryMesh;
 class polyPatch;
 
 Ostream& operator<<(Ostream&, const polyPatch&);
diff --git a/src/OpenFOAM/meshes/polyMesh/syncTools/syncTools.H b/src/OpenFOAM/meshes/polyMesh/syncTools/syncTools.H
index 8841fe9870f37fb5406a01bb5ed5ba9c0ee9e16e..754eaf907c3c4ff4cf1e2dcaf3ed793204fd5743 100644
--- a/src/OpenFOAM/meshes/polyMesh/syncTools/syncTools.H
+++ b/src/OpenFOAM/meshes/polyMesh/syncTools/syncTools.H
@@ -223,7 +223,7 @@ public:
 
         // PackedList versions
 
-            template <int nBits, class CombineOp>
+            template <unsigned nBits, class CombineOp>
             static void syncFaceList
             (
                 const polyMesh& mesh,
@@ -231,14 +231,14 @@ public:
                 const CombineOp& cop
             );
 
-            template <int nBits>
+            template <unsigned nBits>
             static void swapFaceList
             (
                 const polyMesh& mesh,
                 PackedList<nBits>& faceValues
             );
 
-            template <int nBits, class CombineOp>
+            template <unsigned nBits, class CombineOp>
             static void syncPointList
             (
                 const polyMesh& mesh,
@@ -247,7 +247,7 @@ public:
                 const unsigned int nullValue
             );
 
-            template <int nBits, class CombineOp>
+            template <unsigned nBits, class CombineOp>
             static void syncEdgeList
             (
                 const polyMesh& mesh,
diff --git a/src/OpenFOAM/meshes/polyMesh/syncTools/syncToolsTemplates.C b/src/OpenFOAM/meshes/polyMesh/syncTools/syncToolsTemplates.C
index acca055b61ef5226207eee78903745b6b92cda43..da198638a23cbdbde87b217125d07dcbc302d288 100644
--- a/src/OpenFOAM/meshes/polyMesh/syncTools/syncToolsTemplates.C
+++ b/src/OpenFOAM/meshes/polyMesh/syncTools/syncToolsTemplates.C
@@ -1570,7 +1570,7 @@ void Foam::syncTools::swapFaceList
 }
 
 
-template <int nBits, class CombineOp>
+template <unsigned nBits, class CombineOp>
 void Foam::syncTools::syncFaceList
 (
     const polyMesh& mesh,
@@ -1582,7 +1582,7 @@ void Foam::syncTools::syncFaceList
     {
         FatalErrorIn
         (
-            "syncTools<int nBits, class CombineOp>::syncFaceList"
+            "syncTools<unsigned nBits, class CombineOp>::syncFaceList"
             "(const polyMesh&, PackedList<nBits>&, const CombineOp&)"
         )   << "Number of values " << faceValues.size()
             << " is not equal to the number of faces in the mesh "
@@ -1691,7 +1691,7 @@ void Foam::syncTools::syncFaceList
 }
 
 
-template <int nBits>
+template <unsigned nBits>
 void Foam::syncTools::swapFaceList
 (
     const polyMesh& mesh,
@@ -1702,7 +1702,7 @@ void Foam::syncTools::swapFaceList
 }
 
 
-template <int nBits, class CombineOp>
+template <unsigned nBits, class CombineOp>
 void Foam::syncTools::syncPointList
 (
     const polyMesh& mesh,
@@ -1715,7 +1715,7 @@ void Foam::syncTools::syncPointList
     {
         FatalErrorIn
         (
-            "syncTools<int nBits, class CombineOp>::syncPointList"
+            "syncTools<unsigned nBits, class CombineOp>::syncPointList"
             "(const polyMesh&, PackedList<nBits>&, const CombineOp&"
             ", const unsigned int&)"
         )   << "Number of values " << pointValues.size()
@@ -1870,7 +1870,7 @@ void Foam::syncTools::syncPointList
 }
 
 
-template <int nBits, class CombineOp>
+template <unsigned nBits, class CombineOp>
 void Foam::syncTools::syncEdgeList
 (
     const polyMesh& mesh,
@@ -1883,7 +1883,7 @@ void Foam::syncTools::syncEdgeList
     {
         FatalErrorIn
         (
-            "syncTools<int nBits, class CombineOp>::syncEdgeList"
+            "syncTools<unsigned nBits, class CombineOp>::syncEdgeList"
             "(const polyMesh&, PackedList<nBits>&, const CombineOp&"
             ", const unsigned int&)"
         )   << "Number of values " << edgeValues.size()
diff --git a/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/solveContinuityEquation.C b/src/OpenFOAM/meshes/primitiveMesh/PatchTools/PatchTools.C
similarity index 79%
rename from applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/solveContinuityEquation.C
rename to src/OpenFOAM/meshes/primitiveMesh/PatchTools/PatchTools.C
index 5fe2090341205ef6d5f2118e5c6cba1f78852e98..45f634ea5079929048757d7d43885de5de67a926 100644
--- a/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/solveContinuityEquation.C
+++ b/src/OpenFOAM/meshes/primitiveMesh/PatchTools/PatchTools.C
@@ -22,16 +22,16 @@ License
     along with OpenFOAM; if not, write to the Free Software Foundation,
     Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 
-Description
-    Solve continuity equation
-
 \*---------------------------------------------------------------------------*/
 
-void solveContinuityEquation
-(
-    volScalarField& rho,
-    const surfaceScalarField& phi
-)
-{
-    solve(fvm::ddt(rho) + fvc::div(phi));
-}
+#include "PatchTools.H"
+
+#include "PatchToolsCheck.C"
+#include "PatchToolsEdgeOwner.C"
+#include "PatchToolsSearch.C"
+#include "PatchToolsSortEdges.C"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/meshes/primitiveMesh/PatchTools/PatchTools.H b/src/OpenFOAM/meshes/primitiveMesh/PatchTools/PatchTools.H
new file mode 100644
index 0000000000000000000000000000000000000000..403a115ec48cb0370cc63ee67a91340cbf7896aa
--- /dev/null
+++ b/src/OpenFOAM/meshes/primitiveMesh/PatchTools/PatchTools.H
@@ -0,0 +1,187 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software; you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by the
+    Free Software Foundation; either version 2 of the License, or (at your
+    option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM; if not, write to the Free Software Foundation,
+    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+Class
+    Foam::PatchTools
+
+Description
+    A collection of tools for searching, sorting PrimitivePatch information.
+
+    The class could also be extended to include more that just static methods.
+
+SourceFiles
+    PatchTools.C
+    PatchToolsCheck.C
+    PatchToolsEdgeOwner.C
+    PatchToolsSearch.C
+    PatchToolsSortEdges.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef PatchTools_H
+#define PatchTools_H
+
+#include "PrimitivePatch.H"
+#include "HashSet.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+                         Class PatchTools Declaration
+\*---------------------------------------------------------------------------*/
+
+class PatchTools
+{
+public:
+
+    //- Check for orientation issues.
+    //  Returns true if problems were found.
+    //  If a normal flips across an edge, places it in the HashSet
+    template
+    <
+        class Face,
+        template<class> class FaceList,
+        class PointField,
+        class PointType
+    >
+    static bool checkOrientation
+    (
+        const PrimitivePatch<Face, FaceList, PointField, PointType>&,
+        const bool report = false,
+        labelHashSet* marked = 0
+    );
+
+
+    //- Fill faceZone with currentZone for every face reachable
+    //  from faceI without crossing edge marked in borderEdge.
+    //  Note: faceZone has to be sized nFaces before calling.
+    template
+    <
+        class BoolListType,
+        class Face,
+        template<class> class FaceList,
+        class PointField,
+        class PointType
+    >
+    static void markZone
+    (
+        const PrimitivePatch<Face, FaceList, PointField, PointType>&,
+        const BoolListType& borderEdge,
+        const label faceI,
+        const label currentZone,
+        labelList& faceZone
+    );
+
+    //- Size and fills faceZone with zone of face.
+    //  Zone is area reachable by edge crossing without crossing borderEdge.
+    //  Returns number of zones.
+    template
+    <
+        class BoolListType,
+        class Face,
+        template<class> class FaceList,
+        class PointField,
+        class PointType
+    >
+    static label markZones
+    (
+        const PrimitivePatch<Face, FaceList, PointField, PointType>&,
+        const BoolListType& borderEdge,
+        labelList& faceZone
+    );
+
+    //- Determine the mapping for a sub-patch.
+    //  Only include faces for which bool-list entry is true.
+    //  @param[in]  includeFaces faces to include
+    //  @param[out] pointMap mapping new to old localPoints
+    //  @param[out] faceMap  mapping new to old faces
+    template
+    <
+        class BoolListType,
+        class Face,
+        template<class> class FaceList,
+        class PointField,
+        class PointType
+    >
+    static void subsetMap
+    (
+        const PrimitivePatch<Face, FaceList, PointField, PointType>&,
+        const BoolListType& includeFaces,
+        labelList& pointMap,
+        labelList& faceMap
+    );
+
+    //- Return edge-face addressing sorted by angle around the edge.
+    //  Orientation is anticlockwise looking from edge.vec(localPoints())
+    template
+    <
+        class Face,
+        template<class> class FaceList,
+        class PointField,
+        class PointType
+    >
+    static labelListList sortedEdgeFaces
+    (
+        const PrimitivePatch<Face, FaceList, PointField, PointType>&
+    );
+
+
+    //- If 2 face neighbours: label of face where ordering of edge
+    //  is consistent with righthand walk.
+    //  If 1 neighbour: label of only face.
+    //  If >2 neighbours: undetermined.
+    template
+    <
+        class Face,
+        template<class> class FaceList,
+        class PointField,
+        class PointType
+    >
+    static labelList edgeOwner
+    (
+        const PrimitivePatch<Face, FaceList, PointField, PointType>&
+    );
+
+
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#ifdef NoRepository
+#   include "PatchTools.C"
+#endif
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/meshes/primitiveMesh/PatchTools/PatchToolsCheck.C b/src/OpenFOAM/meshes/primitiveMesh/PatchTools/PatchToolsCheck.C
new file mode 100644
index 0000000000000000000000000000000000000000..5fcec15c9586e44f9e52b267d9f02c2ec585e396
--- /dev/null
+++ b/src/OpenFOAM/meshes/primitiveMesh/PatchTools/PatchToolsCheck.C
@@ -0,0 +1,180 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software; you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by the
+    Free Software Foundation; either version 2 of the License, or (at your
+    option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM; if not, write to the Free Software Foundation,
+    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+\*---------------------------------------------------------------------------*/
+
+#include "PatchTools.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+template
+<
+    class Face,
+    template<class> class FaceList,
+    class PointField,
+    class PointType
+>
+
+bool
+Foam::PatchTools::checkOrientation
+(
+    const PrimitivePatch<Face, FaceList, PointField, PointType>& p,
+    const bool report,
+    labelHashSet* setPtr
+)
+{
+    bool foundError = false;
+
+    // Check edge normals, face normals, point normals.
+    forAll(p.faceEdges(), faceI)
+    {
+        const labelList& edgeLabels = p.faceEdges()[faceI];
+        bool valid = true;
+
+        if (edgeLabels.size() < 3)
+        {
+            if (report)
+            {
+                Info<< "Face[" << faceI << "] " << p[faceI]
+                    << " has fewer than 3 edges. Edges: " << edgeLabels
+                    << nl;
+            }
+            valid = false;
+        }
+        else
+        {
+            forAll(edgeLabels, i)
+            {
+                if (edgeLabels[i] < 0 || edgeLabels[i] >= p.nEdges())
+                {
+                    if (report)
+                    {
+                        Info<< "edge number " << edgeLabels[i] << " on face " << faceI
+                            << " out-of-range\n"
+                            << "This usually means the input surface has "
+                            << "edges with more than 2 faces connected." << nl;
+                    }
+                    valid = false;
+                }
+            }
+        }
+
+        if (!valid)
+        {
+            foundError = true;
+            continue;
+        }
+
+
+        //
+        //- Compute normal from 3 points, use the first as the origin
+        // minor warpage should not be a problem
+        const Face& f = p[faceI];
+        const point p0(p.points()[f[0]]);
+        const point p1(p.points()[f[1]]);
+        const point p2(p.points()[f[f.size()-1]]);
+
+        const vector pointNormal((p1 - p0) ^ (p2 - p0));
+        if ((pointNormal & p.faceNormals()[faceI]) < 0)
+        {
+            foundError = false;
+
+            if (report)
+            {
+                Info
+                    << "Normal calculated from points inconsistent with faceNormal"
+                    << nl
+                    << "face: " << f << nl
+                    << "points: " << p0 << ' ' << p1 << ' ' << p2 << nl
+                    << "pointNormal:" << pointNormal << nl
+                    << "faceNormal:" << p.faceNormals()[faceI] << nl;
+            }
+        }
+    }
+
+
+    forAll(p.edges(), edgeI)
+    {
+        const edge& e = p.edges()[edgeI];
+        const labelList& neighbouringFaces = p.edgeFaces()[edgeI];
+
+        if (neighbouringFaces.size() == 2)
+        {
+            // we use localFaces() since edges() are LOCAL
+            // these are both already available
+            const Face& faceA = p.localFaces()[neighbouringFaces[0]];
+            const Face& faceB = p.localFaces()[neighbouringFaces[1]];
+
+            // If the faces are correctly oriented, the edges must go in
+            // different directions on connected faces.
+            if (faceA.edgeDirection(e) == faceB.edgeDirection(e))
+            {
+                if (report)
+                {
+                    Info<< "face orientation incorrect." << nl
+                        << "localEdge[" << edgeI << "] " << e
+                        << " between faces:" << nl
+                        << "  face[" << neighbouringFaces[0] << "] "
+                        << p[neighbouringFaces[0]]
+                        << "   localFace: " << faceA
+                        << nl
+                        << "  face[" << neighbouringFaces[1] << "] "
+                        << p[neighbouringFaces[1]]
+                        << "   localFace: " << faceB
+                        << endl;
+                }
+                if (setPtr)
+                {
+                    setPtr->insert(edgeI);
+                }
+
+                foundError = true;
+            }
+        }
+        else if (neighbouringFaces.size() != 1)
+        {
+            if (report)
+            {
+                Info
+                    << "Wrong number of edge neighbours." << nl
+                    << "edge[" << edgeI << "] " << e
+                    << " with points:" << p.localPoints()[e.start()]
+                    << ' ' << p.localPoints()[e.end()]
+                    << " has neighbouringFaces:" << neighbouringFaces << endl;
+            }
+
+            if (setPtr)
+            {
+                setPtr->insert(edgeI);
+            }
+
+            foundError = true;
+        }
+    }
+
+    return foundError;
+}
+
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/meshes/primitiveMesh/PatchTools/PatchToolsEdgeOwner.C b/src/OpenFOAM/meshes/primitiveMesh/PatchTools/PatchToolsEdgeOwner.C
new file mode 100644
index 0000000000000000000000000000000000000000..2c1cac1be77752d826af2e25620fed5b26d2301b
--- /dev/null
+++ b/src/OpenFOAM/meshes/primitiveMesh/PatchTools/PatchToolsEdgeOwner.C
@@ -0,0 +1,95 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software; you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by the
+    Free Software Foundation; either version 2 of the License, or (at your
+    option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM; if not, write to the Free Software Foundation,
+    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+\*---------------------------------------------------------------------------*/
+
+#include "PatchTools.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+template
+<
+    class Face,
+    template<class> class FaceList,
+    class PointField,
+    class PointType
+>
+
+Foam::labelList
+Foam::PatchTools::edgeOwner
+(
+    const PrimitivePatch<Face, FaceList, PointField, PointType>& p
+)
+{
+    const edgeList& edges = p.edges();
+    const labelListList& edgeFaces = p.edgeFaces();
+    const List<Face>& localFaces = p.localFaces();
+
+    // create the owner list
+    labelList edgeOwner(edges.size(), -1);
+
+    forAll(edges, edgeI)
+    {
+        const labelList& nbrFaces = edgeFaces[edgeI];
+
+        if (nbrFaces.size() == 1)
+        {
+            edgeOwner[edgeI] = nbrFaces[0];
+        }
+        else
+        {
+            // Find the first face whose vertices are aligned with the edge.
+            // with multiply connected edges, this is the best we can do
+            forAll(nbrFaces, i)
+            {
+                const Face& f = localFaces[nbrFaces[i]];
+
+                if (f.edgeDirection(edges[edgeI]) > 0)
+                {
+                    edgeOwner[edgeI] = nbrFaces[i];
+                    break;
+                }
+            }
+
+            if (edgeOwner[edgeI] == -1)
+            {
+                FatalErrorIn
+                (
+                    "PatchTools::edgeOwner()"
+                )
+                    << "Edge " << edgeI << " vertices:" << edges[edgeI]
+                    << " is used by faces " << nbrFaces
+                    << " vertices:"
+                    << IndirectList<Face>(localFaces, nbrFaces)()
+                    << " none of which use the edge vertices in the same order"
+                    << nl << "I give up" << abort(FatalError);
+            }
+        }
+    }
+
+    return edgeOwner;
+}
+
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatchExtra/PrimitivePatchExtraSearch.C b/src/OpenFOAM/meshes/primitiveMesh/PatchTools/PatchToolsSearch.C
similarity index 66%
rename from src/OpenFOAM/meshes/primitiveMesh/PrimitivePatchExtra/PrimitivePatchExtraSearch.C
rename to src/OpenFOAM/meshes/primitiveMesh/PatchTools/PatchToolsSearch.C
index 0d56d9be1eafe920a315e493b3124e86b2c21f5a..0f271008a931ccf5505c06d1d8f26378c3ecc5d1 100644
--- a/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatchExtra/PrimitivePatchExtraSearch.C
+++ b/src/OpenFOAM/meshes/primitiveMesh/PatchTools/PatchToolsSearch.C
@@ -22,35 +22,42 @@ License
     along with OpenFOAM; if not, write to the Free Software Foundation,
     Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 
+Description
+    Searching and marking zones of the patch.
+
 \*---------------------------------------------------------------------------*/
 
-#include "PrimitivePatchExtra.H"
+#include "PatchTools.H"
 
-// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-// Finds area, starting at faceI, delimited by borderEdge. Marks all visited
-// faces (from face-edge-face walk) with currentZone.
+// Finds area, starting at faceI, delimited by borderEdge.
+// Marks all visited faces (from face-edge-face walk) with currentZone.
 template
 <
+    class BoolListType,
     class Face,
     template<class> class FaceList,
     class PointField,
     class PointType
 >
-void Foam::PrimitivePatchExtra<Face, FaceList, PointField, PointType>::markZone
+
+void
+Foam::PatchTools::markZone
 (
-    const UList<bool>& borderEdge,
+    const PrimitivePatch<Face, FaceList, PointField, PointType>& p,
+    const BoolListType& borderEdge,
     const label faceI,
     const label currentZone,
-    labelList& faceZone
-) const
+    labelList&  faceZone
+)
 {
+    const labelListList& faceEdges = p.faceEdges();
+    const labelListList& edgeFaces = p.edgeFaces();
+
     // List of faces whose faceZone has been set.
     labelList changedFaces(1, faceI);
 
-    const labelListList& faceEs = this->faceEdges();
-    const labelListList& eFaces = this->edgeFaces();
-
     while (true)
     {
         // Pick up neighbours of changedFaces
@@ -60,7 +67,7 @@ void Foam::PrimitivePatchExtra<Face, FaceList, PointField, PointType>::markZone
         {
             label faceI = changedFaces[i];
 
-            const labelList& fEdges = faceEs[faceI];
+            const labelList& fEdges = faceEdges[faceI];
 
             forAll(fEdges, fEdgeI)
             {
@@ -68,7 +75,7 @@ void Foam::PrimitivePatchExtra<Face, FaceList, PointField, PointType>::markZone
 
                 if (!borderEdge[edgeI])
                 {
-                    const labelList& eFaceLst = eFaces[edgeI];
+                    const labelList& eFaceLst = edgeFaces[edgeI];
 
                     forAll(eFaceLst, j)
                     {
@@ -83,8 +90,8 @@ void Foam::PrimitivePatchExtra<Face, FaceList, PointField, PointType>::markZone
                         {
                             FatalErrorIn
                             (
-                                "PrimitivePatchExtra<Face, FaceList, PointField>::markZone"
-                                "(const boolList&, const label, const label, labelList&) const"
+                                "PatchTools::markZone"
+                                "(const boolList&, const label, const label, labelList&)"
                             )
                                 << "Zones " << faceZone[nbrFaceI]
                                 << " at face " << nbrFaceI
@@ -112,60 +119,38 @@ void Foam::PrimitivePatchExtra<Face, FaceList, PointField, PointType>::markZone
 // Fills faceZone accordingly
 template
 <
+    class BoolListType,
     class Face,
     template<class> class FaceList,
     class PointField,
     class PointType
 >
-Foam::label Foam::PrimitivePatchExtra<Face, FaceList, PointField, PointType>::
-markZones
+
+Foam::label
+Foam::PatchTools::markZones
 (
-    const UList<bool>& borderEdge,
+    const PrimitivePatch<Face, FaceList, PointField, PointType>& p,
+    const BoolListType& borderEdge,
     labelList& faceZone
-) const
+)
 {
-    const label numEdges = this->nEdges();
-    const label numFaces = this->size();
-
-    if (borderEdge.size() != numEdges)
-    {
-        FatalErrorIn
-        (
-            "PrimitivePatchExtra<Face, FaceList, PointField>::markZones"
-            "(const boolList&, labelList&)"
-        )
-            << "borderEdge boolList not same size as number of edges" << endl
-            << "borderEdge:" << borderEdge.size() << endl
-            << "nEdges    :" << numEdges
-            << exit(FatalError);
-    }
-
-    faceZone.setSize(numFaces);
+    faceZone.setSize(p.size());
     faceZone = -1;
 
     label zoneI = 0;
-    label startFaceI = 0;
-
-    while (true)
+    for (label startFaceI = 0; startFaceI < faceZone.size();)
     {
-        // Find first non-visited face
-        for (; startFaceI < numFaces; startFaceI++)
+        // Find next non-visited face
+        for (; startFaceI < faceZone.size(); ++startFaceI)
         {
             if (faceZone[startFaceI] == -1)
             {
                 faceZone[startFaceI] = zoneI;
-                markZone(borderEdge, startFaceI, zoneI, faceZone);
+                markZone(p, borderEdge, startFaceI, zoneI, faceZone);
+                zoneI++;
                 break;
             }
         }
-
-        if (startFaceI >= numFaces)
-        {
-            // Finished
-            break;
-        }
-
-        zoneI++;
     }
 
     return zoneI;
@@ -177,46 +162,48 @@ markZones
 // Fills faceZone accordingly
 template
 <
+    class BoolListType,
     class Face,
     template<class> class FaceList,
     class PointField,
     class PointType
 >
-void Foam::PrimitivePatchExtra<Face, FaceList, PointField, PointType>::
-subsetMap
+
+void
+Foam::PatchTools::subsetMap
 (
-    const UList<bool>& include,
+    const PrimitivePatch<Face, FaceList, PointField, PointType>& p,
+    const BoolListType& includeFaces,
     labelList& pointMap,
     labelList& faceMap
-) const
+)
 {
-    const List<Face>& locFaces = this->localFaces();
-    const label numPoints = this->nPoints();
-
-    label faceI = 0;
+    label faceI  = 0;
     label pointI = 0;
 
-    faceMap.setSize(locFaces.size());
-    pointMap.setSize(numPoints);
+    const List<Face>& localFaces = p.localFaces();
+
+    faceMap.setSize(localFaces.size());
+    pointMap.setSize(p.nPoints());
 
-    boolList pointHad(numPoints, false);
+    boolList pointHad(pointMap.size(), false);
 
-    forAll(include, oldFaceI)
+    forAll(p, oldFaceI)
     {
-        if (include[oldFaceI])
+        if (includeFaces[oldFaceI])
         {
             // Store new faces compact
             faceMap[faceI++] = oldFaceI;
 
             // Renumber labels for face
-            const Face& f = locFaces[oldFaceI];
+            const Face& f = localFaces[oldFaceI];
 
             forAll(f, fp)
             {
                 const label ptLabel = f[fp];
                 if (!pointHad[ptLabel])
                 {
-                    pointHad[ptLabel] = true;
+                    pointHad[ptLabel]  = true;
                     pointMap[pointI++] = ptLabel;
                 }
             }
@@ -229,6 +216,4 @@ subsetMap
 }
 
 
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
 // ************************************************************************* //
diff --git a/src/OpenFOAM/meshes/primitiveMesh/PatchTools/PatchToolsSortEdges.C b/src/OpenFOAM/meshes/primitiveMesh/PatchTools/PatchToolsSortEdges.C
new file mode 100644
index 0000000000000000000000000000000000000000..8e985bcfa8dd86377d0fdf257489e8d7b390d3f3
--- /dev/null
+++ b/src/OpenFOAM/meshes/primitiveMesh/PatchTools/PatchToolsSortEdges.C
@@ -0,0 +1,128 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software; you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by the
+    Free Software Foundation; either version 2 of the License, or (at your
+    option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM; if not, write to the Free Software Foundation,
+    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+\*---------------------------------------------------------------------------*/
+
+#include "PatchTools.H"
+#include "SortableList.H"
+#include "transform.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+template
+<
+    class Face,
+    template<class> class FaceList,
+    class PointField,
+    class PointType
+>
+
+Foam::labelListList
+Foam::PatchTools::sortedEdgeFaces
+(
+    const PrimitivePatch<Face, FaceList, PointField, PointType>& p
+)
+{
+    const edgeList& edges = p.edges();
+    const labelListList& edgeFaces = p.edgeFaces();
+    const List<Face>& localFaces = p.localFaces();
+    const Field<PointType>& localPoints = p.localPoints();
+
+    // create the lists for the various results. (resized on completion)
+    labelListList& sortedEdgeFaces = labelListList(edgeFaces.size());
+
+    forAll(edgeFaces, edgeI)
+    {
+        const labelList& faceNbs = edgeFaces[edgeI];
+
+        if (faceNbs.size() > 2)
+        {
+            // Get point on edge and normalized direction of edge (= e2 base
+            // of our coordinate system)
+            const edge& e = edges[edgeI];
+
+            const point& edgePt = localPoints[e.start()];
+
+            vector e2 = e.vec(localPoints);
+            e2 /= mag(e2) + VSMALL;
+
+            // Get opposite vertex for 0th face
+            const Face& f = localFaces[faceNbs[0]];
+
+            label fp0 = findIndex(f, e[0]);
+            label fp1 = f.fcIndex(fp0);
+            label vertI = (f[fp1] != e[1] ? f[fp1] : f.fcIndex(fp1));
+
+            // Get vector normal both to e2 and to edge from opposite vertex
+            // to edge (will be x-axis of our coordinate system)
+            vector e0 = e2 ^ (localPoints[vertI] - edgePt);
+            e0 /= mag(e0) + VSMALL;
+
+            // Get y-axis of coordinate system
+            vector e1 = e2 ^ e0;
+
+            SortableList<scalar> faceAngles(faceNbs.size());
+
+            // e0 is reference so angle is 0
+            faceAngles[0] = 0;
+
+            for (label nbI = 1; nbI < faceNbs.size(); nbI++)
+            {
+                // Get opposite vertex
+                const Face& f = localFaces[faceNbs[nbI]];
+                label fp0 = findIndex(f, e[0]);
+                label fp1 = f.fcIndex(fp0);
+                label vertI = (f[fp1] != e[1] ? f[fp1] : f.fcIndex(fp1));
+
+                vector vec = e2 ^ (localPoints[vertI] - edgePt);
+                vec /= mag(vec) + VSMALL;
+
+                faceAngles[nbI] = pseudoAngle
+                (
+                    e0,
+                    e1,
+                    vec
+                );
+            }
+
+            faceAngles.sort();
+
+            sortedEdgeFaces[edgeI] = IndirectList<label>
+            (
+                faceNbs,
+                faceAngles.indices()
+            );
+        }
+        else
+        {
+            // No need to sort. Just copy.
+            sortedEdgeFaces[edgeI] = faceNbs;
+        }
+    }
+
+    return sortedEdgeFaces;
+}
+
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatch/PrimitivePatch.C b/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatch/PrimitivePatch.C
index 2b05c73ae8b595e7f53afaf1e41d4ee594c905a1..6be9ef348b5071e61874fffacc991a7f83505a68 100644
--- a/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatch/PrimitivePatch.C
+++ b/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatch/PrimitivePatch.C
@@ -26,11 +26,6 @@ License
 
 #include "Map.H"
 
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-namespace Foam
-{
-
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
 // Construct from components
@@ -41,7 +36,9 @@ template
     class PointField,
     class PointType
 >
-PrimitivePatch<Face, FaceList, PointField, PointType>::PrimitivePatch
+
+Foam::PrimitivePatch<Face, FaceList, PointField, PointType>::
+PrimitivePatch
 (
     const FaceList<Face>& faces,
     const Field<PointType>& points
@@ -76,7 +73,9 @@ template
     class PointField,
     class PointType
 >
-PrimitivePatch<Face, FaceList, PointField, PointType>::PrimitivePatch
+
+Foam::PrimitivePatch<Face, FaceList, PointField, PointType>::
+PrimitivePatch
 (
     FaceList<Face>& faces,
     Field<PointType>& points,
@@ -112,7 +111,9 @@ template
     class PointField,
     class PointType
 >
-PrimitivePatch<Face, FaceList, PointField, PointType>::PrimitivePatch
+
+Foam::PrimitivePatch<Face, FaceList, PointField, PointType>::
+PrimitivePatch
 (
     const PrimitivePatch<Face, FaceList, PointField, PointType>& pp
 )
@@ -148,7 +149,8 @@ template
     class PointField,
     class PointType
 >
-PrimitivePatch<Face, FaceList, PointField, PointType>::~PrimitivePatch()
+
+Foam::PrimitivePatch<Face, FaceList, PointField, PointType>::~PrimitivePatch()
 {
     clearOut();
 }
@@ -164,7 +166,10 @@ template
     class PointField,
     class PointType
 >
-void PrimitivePatch<Face, FaceList, PointField, PointType>::movePoints
+
+void
+Foam::PrimitivePatch<Face, FaceList, PointField, PointType>::
+movePoints
 (
     const Field<PointType>&
 )
@@ -188,8 +193,10 @@ template
     class PointField,
     class PointType
 >
-const edgeList&
-PrimitivePatch<Face, FaceList, PointField, PointType>::edges() const
+
+const Foam::edgeList&
+Foam::PrimitivePatch<Face, FaceList, PointField, PointType>::
+edges() const
 {
     if (!edgesPtr_)
     {
@@ -207,8 +214,10 @@ template
     class PointField,
     class PointType
 >
-label PrimitivePatch<Face, FaceList, PointField, PointType>::nInternalEdges()
- const
+
+Foam::label
+Foam::PrimitivePatch<Face, FaceList, PointField, PointType>::
+nInternalEdges() const
 {
     if (!edgesPtr_)
     {
@@ -226,8 +235,10 @@ template
     class PointField,
     class PointType
 >
-const labelList&
-PrimitivePatch<Face, FaceList, PointField, PointType>::boundaryPoints() const
+
+const Foam::labelList&
+Foam::PrimitivePatch<Face, FaceList, PointField, PointType>::
+boundaryPoints() const
 {
     if (!boundaryPointsPtr_)
     {
@@ -245,8 +256,10 @@ template
     class PointField,
     class PointType
 >
-const labelListList&
-PrimitivePatch<Face, FaceList, PointField, PointType>::faceFaces() const
+
+const Foam::labelListList&
+Foam::PrimitivePatch<Face, FaceList, PointField, PointType>::
+faceFaces() const
 {
     if (!faceFacesPtr_)
     {
@@ -264,8 +277,10 @@ template
     class PointField,
     class PointType
 >
-const labelListList&
-PrimitivePatch<Face, FaceList, PointField, PointType>::edgeFaces() const
+
+const Foam::labelListList&
+Foam::PrimitivePatch<Face, FaceList, PointField, PointType>::
+edgeFaces() const
 {
     if (!edgeFacesPtr_)
     {
@@ -283,8 +298,10 @@ template
     class PointField,
     class PointType
 >
-const labelListList&
-PrimitivePatch<Face, FaceList, PointField, PointType>::faceEdges() const
+
+const Foam::labelListList&
+Foam::PrimitivePatch<Face, FaceList, PointField, PointType>::
+faceEdges() const
 {
     if (!faceEdgesPtr_)
     {
@@ -302,8 +319,10 @@ template
     class PointField,
     class PointType
 >
-const labelListList&
-PrimitivePatch<Face, FaceList, PointField, PointType>::pointEdges() const
+
+const Foam::labelListList&
+Foam::PrimitivePatch<Face, FaceList, PointField, PointType>::
+pointEdges() const
 {
     if (!pointEdgesPtr_)
     {
@@ -321,8 +340,10 @@ template
     class PointField,
     class PointType
 >
-const labelListList&
-PrimitivePatch<Face, FaceList, PointField, PointType>::pointFaces() const
+
+const Foam::labelListList&
+Foam::PrimitivePatch<Face, FaceList, PointField, PointType>::
+pointFaces() const
 {
     if (!pointFacesPtr_)
     {
@@ -340,8 +361,10 @@ template
     class PointField,
     class PointType
 >
-const List<Face>&
-PrimitivePatch<Face, FaceList, PointField, PointType>::localFaces() const
+
+const Foam::List<Face>&
+Foam::PrimitivePatch<Face, FaceList, PointField, PointType>::
+localFaces() const
 {
     if (!localFacesPtr_)
     {
@@ -359,8 +382,10 @@ template
     class PointField,
     class PointType
 >
-const labelList&
-PrimitivePatch<Face, FaceList, PointField, PointType>::meshPoints() const
+
+const Foam::labelList&
+Foam::PrimitivePatch<Face, FaceList, PointField, PointType>::
+meshPoints() const
 {
     if (!meshPointsPtr_)
     {
@@ -378,8 +403,10 @@ template
     class PointField,
     class PointType
 >
-const Map<label>&
-PrimitivePatch<Face, FaceList, PointField, PointType>::meshPointMap() const
+
+const Foam::Map<Foam::label>&
+Foam::PrimitivePatch<Face, FaceList, PointField, PointType>::
+meshPointMap() const
 {
     if (!meshPointMapPtr_)
     {
@@ -397,8 +424,10 @@ template
     class PointField,
     class PointType
 >
-const Field<PointType>&
-PrimitivePatch<Face, FaceList, PointField, PointType>::localPoints() const
+
+const Foam::Field<PointType>&
+Foam::PrimitivePatch<Face, FaceList, PointField, PointType>::
+localPoints() const
 {
     if (!localPointsPtr_)
     {
@@ -416,8 +445,10 @@ template
     class PointField,
     class PointType
 >
-const labelList&
-PrimitivePatch<Face, FaceList, PointField, PointType>::localPointOrder() const
+
+const Foam::labelList&
+Foam::PrimitivePatch<Face, FaceList, PointField, PointType>::
+localPointOrder() const
 {
     if (!localPointOrderPtr_)
     {
@@ -435,16 +466,19 @@ template
     class PointField,
     class PointType
 >
-label PrimitivePatch<Face, FaceList, PointField, PointType>::whichPoint
+
+Foam::label
+Foam::PrimitivePatch<Face, FaceList, PointField, PointType>::
+whichPoint
 (
     const label gp
 ) const
 {
-    Map<label>::const_iterator gpIter = meshPointMap().find(gp);
+    Map<label>::const_iterator fnd = meshPointMap().find(gp);
 
-    if (gpIter != meshPointMap().end())
+    if (fnd != meshPointMap().end())
     {
-        return gpIter();
+        return fnd();
     }
     else
     {
@@ -461,8 +495,10 @@ template
     class PointField,
     class PointType
 >
-const Field<PointType>&
-PrimitivePatch<Face, FaceList, PointField, PointType>::faceNormals() const
+
+const Foam::Field<PointType>&
+Foam::PrimitivePatch<Face, FaceList, PointField, PointType>::
+faceNormals() const
 {
     if (!faceNormalsPtr_)
     {
@@ -480,8 +516,10 @@ template
     class PointField,
     class PointType
 >
-const Field<PointType>&
-PrimitivePatch<Face, FaceList, PointField, PointType>::pointNormals() const
+
+const Foam::Field<PointType>&
+Foam::PrimitivePatch<Face, FaceList, PointField, PointType>::
+pointNormals() const
 {
     if (!pointNormalsPtr_)
     {
@@ -501,7 +539,10 @@ template
     class PointField,
     class PointType
 >
-void PrimitivePatch<Face, FaceList, PointField, PointType>::operator=
+
+void
+Foam::PrimitivePatch<Face, FaceList, PointField, PointType>::
+operator=
 (
     const PrimitivePatch<Face, FaceList, PointField, PointType>& pp
 )
@@ -511,11 +552,6 @@ void PrimitivePatch<Face, FaceList, PointField, PointType>::operator=
     FaceList<Face>::operator=(pp);
 }
 
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-} // End namespace Foam
-
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 #include "PrimitivePatchAddressing.C"
diff --git a/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatch/PrimitivePatch.H b/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatch/PrimitivePatch.H
index 92ce43b73c3533c3affd7cf16a1c64b06bce5958..f0bd005b476d9d6122fe8045df53fbddf17acdae 100644
--- a/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatch/PrimitivePatch.H
+++ b/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatch/PrimitivePatch.H
@@ -28,10 +28,10 @@ Class
 Description
     A list of faces which address into the list of points.
 
-    The class is templated on the form of the face (e.g. triangle, polygon
-    etc.) and on the form of list for faces and points so that it can
-    refer to existing lists using UList and const pointField& or hold the
-    storage using List and pointField.
+    The class is templated on the face type (e.g. triangle, polygon etc.)
+    and on the list type of faces and points so that it can refer to
+    existing lists using UList and const pointField& or hold the storage
+    using List and pointField.
 
 SourceFiles
     PrimitivePatchAddressing.C
@@ -211,9 +211,12 @@ private:
         //- Calculate unit point normals
         void calcPointNormals() const;
 
+        //- Calculate edge owner
+        void calcEdgeOwner() const;
+
 
         //- Face-edge-face walk while remaining on a patch point.
-        // Used to determine if surface multiply connected through point.
+        //  Used to determine if surface multiply connected through point.
         void visitPointRegion
         (
             const label pointI,
@@ -265,175 +268,175 @@ public:
 
     // Member Functions
 
-        // Access
+    // Access
 
-            //- Return reference to global points
-            const Field<PointType>& points() const
-            {
-                return points_;
-            }
+        //- Return reference to global points
+        const Field<PointType>& points() const
+        {
+            return points_;
+        }
 
 
-        // Access functions for demand driven data
+    // Access functions for demand driven data
 
-            // Topological data; no mesh required.
+        // Topological data; no mesh required.
 
-                //- Return number of points supporting patch faces
-                label nPoints() const
-                {
-                    return meshPoints().size();
-                }
+            //- Return number of points supporting patch faces
+            label nPoints() const
+            {
+                return meshPoints().size();
+            }
 
-                //- Return number of edges in patch
-                label nEdges() const
-                {
-                    return edges().size();
-                }
+            //- Return number of edges in patch
+            label nEdges() const
+            {
+                return edges().size();
+            }
 
-                //- Return list of edges, address into LOCAL point list
-                const edgeList& edges() const;
+            //- Return list of edges, address into LOCAL point list
+            const edgeList& edges() const;
 
-                //- Number of internal edges
-                label nInternalEdges() const;
+            //- Number of internal edges
+            label nInternalEdges() const;
 
-                //- Is internal edge?
-                bool isInternalEdge(const label edgeI) const
-                {
-                    return edgeI < nInternalEdges();
-                }
+            //- Is internal edge?
+            bool isInternalEdge(const label edgeI) const
+            {
+                return edgeI < nInternalEdges();
+            }
 
-                //- Return list of boundary points,
-                //  address into LOCAL point list
-                const labelList& boundaryPoints() const;
+            //- Return list of boundary points,
+            //  address into LOCAL point list
+            const labelList& boundaryPoints() const;
 
-                //- Return face-face addressing
-                const labelListList& faceFaces() const;
+            //- Return face-face addressing
+            const labelListList& faceFaces() const;
 
-                //- Return edge-face addressing
-                const labelListList& edgeFaces() const;
+            //- Return edge-face addressing
+            const labelListList& edgeFaces() const;
 
-                //- Return face-edge addressing
-                const labelListList& faceEdges() const;
+            //- Return face-edge addressing
+            const labelListList& faceEdges() const;
 
-                //- Return point-edge addressing
-                const labelListList& pointEdges() const;
+            //- Return point-edge addressing
+            const labelListList& pointEdges() const;
 
-                //- Return point-face addressing
-                const labelListList& pointFaces() const;
+            //- Return point-face addressing
+            const labelListList& pointFaces() const;
 
-                //- Return patch faces addressing into local point list
-                const List<Face>& localFaces() const;
+            //- Return patch faces addressing into local point list
+            const List<Face>& localFaces() const;
 
 
-            // Addressing into mesh
+        // Addressing into mesh
 
-                //- Return labelList of mesh points in patch
-                const labelList& meshPoints() const;
+            //- Return labelList of mesh points in patch
+            const labelList& meshPoints() const;
 
-                //- Mesh point map.  Given the global point index find its
-                //  location in the patch
-                const Map<label>& meshPointMap() const;
+            //- Mesh point map.  Given the global point index find its
+            //  location in the patch
+            const Map<label>& meshPointMap() const;
 
-                //- Return pointField of points in patch
-                const Field<PointType>& localPoints() const;
+            //- Return pointField of points in patch
+            const Field<PointType>& localPoints() const;
 
-                //- Return orders the local points for most efficient search
-                const labelList& localPointOrder() const;
+            //- Return orders the local points for most efficient search
+            const labelList& localPointOrder() const;
 
-                //- Given a global point index, return the local point
-                //index.  If the point is not found, return -1
-                label whichPoint(const label gp) const;
+            //- Given a global point index, return the local point index.
+            //  If the point is not found, return -1
+            label whichPoint(const label gp) const;
 
-                //- Given an edge in local point labels, return its
-                //  index in the edge list.  If the edge is not found, return -1
-                label whichEdge(const edge& e) const;
+            //- Given an edge in local point labels, return its
+            //  index in the edge list.  If the edge is not found, return -1
+            label whichEdge(const edge&) const;
 
-                //- Return labels of patch edges in the global edge list using
-                //  cell addressing
-                labelList meshEdges
-                (
-                    const edgeList& allEdges,
-                    const labelListList& cellEdges,
-                    const labelList& faceCells
-                ) const;
+            //- Return labels of patch edges in the global edge list using
+            //  cell addressing
+            labelList meshEdges
+            (
+                const edgeList& allEdges,
+                const labelListList& cellEdges,
+                const labelList& faceCells
+            ) const;
 
-                //- Return labels of patch edges in the global edge list using
-                //  basic edge addressing.
-                labelList meshEdges
-                (
-                    const edgeList& allEdges,
-                    const labelListList& pointEdges
-                ) const;
+            //- Return labels of patch edges in the global edge list using
+            //  basic edge addressing.
+            labelList meshEdges
+            (
+                const edgeList& allEdges,
+                const labelListList& pointEdges
+            ) const;
 
-                //- Return face normals for patch
-                const Field<PointType>& faceNormals() const;
+            //- Return face normals for patch
+            const Field<PointType>& faceNormals() const;
 
-                //- Return point normals for patch
-                const Field<PointType>& pointNormals() const;
+            //- Return point normals for patch
+            const Field<PointType>& pointNormals() const;
 
 
-            // Other patch operations
+        // Other patch operations
 
-                //- Project vertices of patch onto another patch
-                template <class ToPatch>
-                List<objectHit> projectPoints
-                (
-                    const ToPatch& targetPatch,
-                    const Field<PointType>& projectionDirection,
-                    const intersection::algorithm alg = intersection::FULL_RAY,
-                    const intersection::direction dir = intersection::VECTOR
-                ) const;
+            //- Project vertices of patch onto another patch
+            template <class ToPatch>
+            List<objectHit> projectPoints
+            (
+                const ToPatch& targetPatch,
+                const Field<PointType>& projectionDirection,
+                const intersection::algorithm = intersection::FULL_RAY,
+                const intersection::direction = intersection::VECTOR
+            ) const;
 
-                //- Project vertices of patch onto another patch
-                template <class ToPatch>
-                List<objectHit> projectFaceCentres
-                (
-                    const ToPatch& targetPatch,
-                    const Field<PointType>& projectionDirection,
-                    const intersection::algorithm alg = intersection::FULL_RAY,
-                    const intersection::direction dir = intersection::VECTOR
-                ) const;
+            //- Project vertices of patch onto another patch
+            template <class ToPatch>
+            List<objectHit> projectFaceCentres
+            (
+                const ToPatch& targetPatch,
+                const Field<PointType>& projectionDirection,
+                const intersection::algorithm = intersection::FULL_RAY,
+                const intersection::direction = intersection::VECTOR
+            ) const;
 
-                //- Return list of closed loops of boundary vertices.
-                //  Edge loops are given as ordered lists of vertices
-                //  in local addressing
-                const labelListList& edgeLoops() const;
+            //- Return list of closed loops of boundary vertices.
+            //  Edge loops are given as ordered lists of vertices
+            //  in local addressing
+            const labelListList& edgeLoops() const;
 
 
-        // Check
+    // Check
 
-            //- Calculate surface type formed by patch.
-            //  - all edges have two neighbours (manifold)
-            //  - some edges have more than two neighbours (illegal)
-            //  - other (open)
-            surfaceTopo surfaceType() const;
+        //- Calculate surface type formed by patch.
+        //  - all edges have two neighbours (manifold)
+        //  - some edges have more than two neighbours (illegal)
+        //  - other (open)
+        surfaceTopo surfaceType() const;
 
-            //- Check surface formed by patch for manifoldness (see above).
-            //  Insert vertices of incorrect
-            //  edges set. Return true if any incorrect edge found.
-            bool checkTopology
-            (
-                const bool report = false,
-                labelHashSet* setPtr = NULL
-            ) const;
+        //- Check surface formed by patch for manifoldness (see above).
+        //  Return true if any incorrect edges are found.
+        //  Insert vertices of incorrect edges into set.
+        bool checkTopology
+        (
+            const bool report = false,
+            labelHashSet* setPtr = NULL
+        ) const;
 
-            //- Checks primitivePatch for faces sharing point but not edge.
-            //  This denotes a surface that is pinched at a single point
-            //  (test for pinched at single edge is already in PrimitivePatch)
-            //  Returns true if this situation found and puts conflicting
-            // (mesh)point in set. Based on all the checking routines in
-            // primitiveMesh.
-            bool checkPointManifold
-            (
-                const bool report = false,
-                labelHashSet* setPtr = NULL
-            ) const;
+        //- Checks primitivePatch for faces sharing point but not edge.
+        //  This denotes a surface that is pinched at a single point
+        //  (test for pinched at single edge is already in PrimitivePatch)
+        //  Returns true if this situation found and puts conflicting
+        //  (mesh)point in set. Based on all the checking routines in
+        //  primitiveMesh.
+        bool checkPointManifold
+        (
+            const bool report = false,
+            labelHashSet* setPtr = NULL
+        ) const;
 
 
-        // Edit
+    // Edit
 
-            //- Correct patch after moving points
-            virtual void movePoints(const Field<PointType>&);
+        //- Correct patch after moving points
+        virtual void movePoints(const Field<PointType>&);
 
 
     // Member operators
diff --git a/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatch/PrimitivePatchAddressing.C b/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatch/PrimitivePatchAddressing.C
index 4fcf243dd5e3f8d82943d1a0eba816bf92bcdb57..14d91344d13c90a374e80393886132311ddbd0d6 100644
--- a/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatch/PrimitivePatchAddressing.C
+++ b/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatch/PrimitivePatchAddressing.C
@@ -39,11 +39,6 @@ Description
 #include "DynamicList.H"
 
 
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-namespace Foam
-{
-
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
 template
@@ -53,8 +48,10 @@ template
     class PointField,
     class PointType
 >
-void PrimitivePatch<Face, FaceList, PointField, PointType>::calcAddressing()
- const
+
+void
+Foam::PrimitivePatch<Face, FaceList, PointField, PointType>::
+calcAddressing() const
 {
     if (debug)
     {
@@ -311,8 +308,4 @@ void PrimitivePatch<Face, FaceList, PointField, PointType>::calcAddressing()
 }
 
 
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-} // End namespace Foam
-
 // ************************************************************************* //
diff --git a/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatch/PrimitivePatchBdryPoints.C b/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatch/PrimitivePatchBdryPoints.C
index 43638ad5a2e5488d1a0a6bb335c839e8a0f71c19..fbd309d2cf4bb7e8df4b012ec6184d513fcb61df 100644
--- a/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatch/PrimitivePatchBdryPoints.C
+++ b/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatch/PrimitivePatchBdryPoints.C
@@ -29,10 +29,6 @@ Description
 #include "PrimitivePatch.H"
 #include "HashSet.H"
 
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-namespace Foam
-{
 
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
@@ -43,8 +39,10 @@ template
     class PointField,
     class PointType
 >
-void PrimitivePatch<Face, FaceList, PointField, PointType>::calcBdryPoints()
- const
+
+void
+Foam::PrimitivePatch<Face, FaceList, PointField, PointType>::
+calcBdryPoints() const
 {
     if (debug)
     {
@@ -91,8 +89,4 @@ void PrimitivePatch<Face, FaceList, PointField, PointType>::calcBdryPoints()
 }
 
 
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-} // End namespace Foam
-
 // ************************************************************************* //
diff --git a/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatch/PrimitivePatchCheck.C b/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatch/PrimitivePatchCheck.C
index 87e4383e83d32f01ffc14f296e574d4b9dc64342..172bc9db7e217c6ffa4bd81d7d29ef62604bcd4b 100644
--- a/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatch/PrimitivePatchCheck.C
+++ b/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatch/PrimitivePatchCheck.C
@@ -31,10 +31,6 @@ Description
 #include "Map.H"
 #include "ListOps.H"
 
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-namespace Foam
-{
 
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
@@ -45,7 +41,10 @@ template
     class PointField,
     class PointType
 >
-void PrimitivePatch<Face, FaceList, PointField, PointType>::visitPointRegion
+
+void
+Foam::PrimitivePatch<Face, FaceList, PointField, PointType>::
+visitPointRegion
 (
     const label pointI,
     const labelList& pFaces,
@@ -121,8 +120,10 @@ template
     class PointField,
     class PointType
 >
-typename PrimitivePatch<Face, FaceList, PointField, PointType>::surfaceTopo
-PrimitivePatch<Face, FaceList, PointField, PointType>::surfaceType() const
+
+typename Foam::PrimitivePatch<Face, FaceList, PointField, PointType>::surfaceTopo
+Foam::PrimitivePatch<Face, FaceList, PointField, PointType>::
+surfaceType() const
 {
     if (debug)
     {
@@ -173,7 +174,10 @@ template
     class PointField,
     class PointType
 >
-bool PrimitivePatch<Face, FaceList, PointField, PointType>::checkTopology
+
+bool
+Foam::PrimitivePatch<Face, FaceList, PointField, PointType>::
+checkTopology
 (
     const bool report,
     labelHashSet* setPtr
@@ -241,8 +245,10 @@ template
     class PointField,
     class PointType
 >
+
 bool
-PrimitivePatch<Face, FaceList, PointField, PointType>::checkPointManifold
+Foam::PrimitivePatch<Face, FaceList, PointField, PointType>::
+checkPointManifold
 (
     const bool report,
     labelHashSet* setPtr
@@ -327,12 +333,8 @@ PrimitivePatch<Face, FaceList, PointField, PointType>::checkPointManifold
         }
     }
 
-    return foundError; 
+    return foundError;
 }
 
 
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-} // End namespace Foam
-
 // ************************************************************************* //
diff --git a/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatch/PrimitivePatchClear.C b/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatch/PrimitivePatchClear.C
index cc3a5332a5ec26b5f487520324781b70a00af003..160bf5546fb78f4266b4b5aadfbc4a39bf2f3178 100644
--- a/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatch/PrimitivePatchClear.C
+++ b/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatch/PrimitivePatchClear.C
@@ -29,10 +29,6 @@ Description
 #include "PrimitivePatch.H"
 #include "demandDrivenData.H"
 
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-namespace Foam
-{
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
@@ -43,7 +39,10 @@ template
     class PointField,
     class PointType
 >
-void PrimitivePatch<Face, FaceList, PointField, PointType>::clearGeom()
+
+void
+Foam::PrimitivePatch<Face, FaceList, PointField, PointType>::
+clearGeom()
 {
     if (debug)
     {
@@ -65,7 +64,10 @@ template
     class PointField,
     class PointType
 >
-void PrimitivePatch<Face, FaceList, PointField, PointType>::clearTopology()
+
+void
+Foam::PrimitivePatch<Face, FaceList, PointField, PointType>::
+clearTopology()
 {
     if (debug)
     {
@@ -91,10 +93,8 @@ void PrimitivePatch<Face, FaceList, PointField, PointType>::clearTopology()
     }
 
     deleteDemandDrivenData(boundaryPointsPtr_);
-
     deleteDemandDrivenData(pointEdgesPtr_);
     deleteDemandDrivenData(pointFacesPtr_);
-
     deleteDemandDrivenData(edgeLoopsPtr_);
 }
 
@@ -106,7 +106,10 @@ template
     class PointField,
     class PointType
 >
-void PrimitivePatch<Face, FaceList, PointField, PointType>::clearPatchMeshAddr()
+
+void
+Foam::PrimitivePatch<Face, FaceList, PointField, PointType>::
+clearPatchMeshAddr()
 {
     if (debug)
     {
@@ -129,7 +132,10 @@ template
     class PointField,
     class PointType
 >
-void PrimitivePatch<Face, FaceList, PointField, PointType>::clearOut()
+
+void
+Foam::PrimitivePatch<Face, FaceList, PointField, PointType>::
+clearOut()
 {
     clearGeom();
     clearTopology();
@@ -137,8 +143,4 @@ void PrimitivePatch<Face, FaceList, PointField, PointType>::clearOut()
 }
 
 
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-} // End namespace Foam
-
 // ************************************************************************* //
diff --git a/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatch/PrimitivePatchEdgeLoops.C b/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatch/PrimitivePatchEdgeLoops.C
index ff1c215220f3fc0f1f397c2a6be5a7e0bf8ded27..3b7d87df90cbbda1cba465ad1223ebf050ff27e4 100644
--- a/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatch/PrimitivePatchEdgeLoops.C
+++ b/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatch/PrimitivePatchEdgeLoops.C
@@ -30,10 +30,7 @@ Description
 
 #include "PrimitivePatch.H"
 
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-namespace Foam
-{
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
@@ -44,8 +41,10 @@ template
     class PointField,
     class PointType
 >
-void PrimitivePatch<Face, FaceList, PointField, PointType>::calcEdgeLoops()
- const
+
+void
+Foam::PrimitivePatch<Face, FaceList, PointField, PointType>::
+calcEdgeLoops() const
 {
     if (debug)
     {
@@ -95,7 +94,7 @@ void PrimitivePatch<Face, FaceList, PointField, PointType>::calcEdgeLoops()
     // Current loop number.
     label loopI = 0;
 
-    for (;;)
+    while (true)
     {
         // Find edge not yet given a loop number.
         label currentEdgeI = -1;
@@ -175,8 +174,10 @@ template
     class PointField,
     class PointType
 >
-const labelListList&
-PrimitivePatch<Face, FaceList, PointField, PointType>::edgeLoops() const
+
+const Foam::labelListList&
+Foam::PrimitivePatch<Face, FaceList, PointField, PointType>::
+edgeLoops() const
 {
     if (!edgeLoopsPtr_)
     {
@@ -186,8 +187,5 @@ PrimitivePatch<Face, FaceList, PointField, PointType>::edgeLoops() const
     return *edgeLoopsPtr_;
 }
 
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-} // End namespace Foam
 
 // ************************************************************************* //
diff --git a/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatch/PrimitivePatchLocalPointOrder.C b/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatch/PrimitivePatchLocalPointOrder.C
index cb6987bd2113e6ad819428be5ead01509c41ac93..b4359d83ebc06e02a356685bc545833b3987a599 100644
--- a/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatch/PrimitivePatchLocalPointOrder.C
+++ b/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatch/PrimitivePatchLocalPointOrder.C
@@ -30,11 +30,6 @@ Description
 #include "SLList.H"
 #include "boolList.H"
 
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-namespace Foam
-{
-
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
 template
@@ -44,8 +39,10 @@ template
     class PointField,
     class PointType
 >
-void PrimitivePatch<Face, FaceList, PointField, PointType>::
- calcLocalPointOrder() const
+
+void
+Foam::PrimitivePatch<Face, FaceList, PointField, PointType>::
+calcLocalPointOrder() const
 {
     // Note: Cannot use bandCompressing as point-point addressing does
     // not exist and is not considered generally useful.
@@ -140,9 +137,4 @@ void PrimitivePatch<Face, FaceList, PointField, PointType>::
     }
 }
 
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-} // End namespace Foam
-
 // ************************************************************************* //
diff --git a/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatch/PrimitivePatchMeshData.C b/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatch/PrimitivePatchMeshData.C
index e121dfd13cb13c159894d269703f12ee340fd434..9941b024598b0f8346310f88e0680c1805210b46 100644
--- a/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatch/PrimitivePatchMeshData.C
+++ b/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatch/PrimitivePatchMeshData.C
@@ -27,10 +27,7 @@ License
 #include "PrimitivePatch.H"
 #include "Map.H"
 
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-namespace Foam
-{
 
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
@@ -42,7 +39,9 @@ template
     class PointType
 >
 
-void PrimitivePatch<Face, FaceList, PointField, PointType>::calcMeshData() const
+void
+Foam::PrimitivePatch<Face, FaceList, PointField, PointType>::
+calcMeshData() const
 {
     if (debug)
     {
@@ -128,8 +127,9 @@ template
     class PointType
 >
 
-void PrimitivePatch<Face, FaceList, PointField, PointType>::calcMeshPointMap()
- const
+void
+Foam::PrimitivePatch<Face, FaceList, PointField, PointType>::
+calcMeshPointMap() const
 {
     if (debug)
     {
@@ -179,8 +179,9 @@ template
     class PointType
 >
 
-void PrimitivePatch<Face, FaceList, PointField, PointType>::calcLocalPoints()
- const
+void
+Foam::PrimitivePatch<Face, FaceList, PointField, PointType>::
+calcLocalPoints() const
 {
     if (debug)
     {
@@ -231,8 +232,9 @@ template
     class PointType
 >
 
-void PrimitivePatch<Face, FaceList, PointField, PointType>::calcPointNormals()
- const
+void
+Foam::PrimitivePatch<Face, FaceList, PointField, PointType>::
+calcPointNormals() const
 {
     if (debug)
     {
@@ -298,8 +300,9 @@ template
     class PointType
 >
 
-void PrimitivePatch<Face, FaceList, PointField, PointType>::calcFaceNormals()
- const
+void
+Foam::PrimitivePatch<Face, FaceList, PointField, PointType>::
+calcFaceNormals() const
 {
     if (debug)
     {
@@ -341,8 +344,4 @@ void PrimitivePatch<Face, FaceList, PointField, PointType>::calcFaceNormals()
 }
 
 
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-} // End namespace Foam
-
 // ************************************************************************* //
diff --git a/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatch/PrimitivePatchMeshEdges.C b/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatch/PrimitivePatchMeshEdges.C
index b152ed9d211122cf85de84fc06f1e19eb9ccb65f..79bac6f1c09db49c4dea705edd79e17c045b47b6 100644
--- a/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatch/PrimitivePatchMeshEdges.C
+++ b/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatch/PrimitivePatchMeshEdges.C
@@ -28,10 +28,6 @@ Description
 
 #include "PrimitivePatch.H"
 
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-namespace Foam
-{
 
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
@@ -43,7 +39,9 @@ template
     class PointType
 >
 
-labelList PrimitivePatch<Face, FaceList, PointField, PointType>::meshEdges
+Foam::labelList
+Foam::PrimitivePatch<Face, FaceList, PointField, PointType>::
+meshEdges
 (
     const edgeList& allEdges,
     const labelListList& cellEdges,
@@ -119,7 +117,9 @@ template
     class PointType
 >
 
-labelList PrimitivePatch<Face, FaceList, PointField, PointType>::meshEdges
+Foam::labelList
+Foam::PrimitivePatch<Face, FaceList, PointField, PointType>::
+meshEdges
 (
     const edgeList& allEdges,
     const labelListList& pointEdges
@@ -133,7 +133,7 @@ labelList PrimitivePatch<Face, FaceList, PointField, PointType>::meshEdges
             << endl;
     }
 
-    // get reference to the list of edges on the patch 
+    // get reference to the list of edges on the patch
     const edgeList& PatchEdges = edges();
 
     // create the storage
@@ -157,7 +157,7 @@ labelList PrimitivePatch<Face, FaceList, PointField, PointType>::meshEdges
             {
                 meshEdges[edgeI] = pe[i];
                 break;
-            } 
+            }
         }
     }
 
@@ -175,7 +175,9 @@ template
     class PointType
 >
 
-label PrimitivePatch<Face, FaceList, PointField, PointType>::whichEdge
+Foam::label
+Foam::PrimitivePatch<Face, FaceList, PointField, PointType>::
+whichEdge
 (
     const edge& e
 ) const
@@ -201,8 +203,4 @@ label PrimitivePatch<Face, FaceList, PointField, PointType>::whichEdge
 }
 
 
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-} // End namespace Foam
-
 // ************************************************************************* //
diff --git a/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatch/PrimitivePatchPointAddressing.C b/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatch/PrimitivePatchPointAddressing.C
index 50703684bb0788171228c14cfbbf3f85401771bb..7ac3612286753872aabb2ae35b9f41180a7cea65 100644
--- a/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatch/PrimitivePatchPointAddressing.C
+++ b/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatch/PrimitivePatchPointAddressing.C
@@ -30,10 +30,6 @@ Description
 #include "PrimitivePatch.H"
 #include "SLList.H"
 
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-namespace Foam
-{
 
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
@@ -45,8 +41,9 @@ template
     class PointType
 >
 
-void PrimitivePatch<Face, FaceList, PointField, PointType>::calcPointEdges()
- const
+void
+Foam::PrimitivePatch<Face, FaceList, PointField, PointType>::
+calcPointEdges() const
 {
     if (debug)
     {
@@ -116,8 +113,9 @@ template
     class PointType
 >
 
-void PrimitivePatch<Face, FaceList, PointField, PointType>::calcPointFaces()
- const
+void
+Foam::PrimitivePatch<Face, FaceList, PointField, PointType>::
+calcPointFaces() const
 {
     if (debug)
     {
@@ -183,8 +181,4 @@ void PrimitivePatch<Face, FaceList, PointField, PointType>::calcPointFaces()
 }
 
 
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-} // End namespace Foam
-
 // ************************************************************************* //
diff --git a/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatch/PrimitivePatchProjectPoints.C b/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatch/PrimitivePatchProjectPoints.C
index dd1685ffab78cc57f2c25cd82a156d6c9c2a07db..d79caa9da4f493771f07059f2359d7fe204ac0d9 100644
--- a/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatch/PrimitivePatchProjectPoints.C
+++ b/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatch/PrimitivePatchProjectPoints.C
@@ -33,11 +33,6 @@ Description
 #include "objectHit.H"
 #include "bandCompression.H"
 
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-namespace Foam
-{
-
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
 template
@@ -49,7 +44,8 @@ template
 >
 
 template <class ToPatch>
-List<objectHit> PrimitivePatch<Face, FaceList, PointField, PointType>::
+Foam::List<Foam::objectHit>
+Foam::PrimitivePatch<Face, FaceList, PointField, PointType>::
 projectPoints
 (
     const ToPatch& targetPatch,
@@ -59,7 +55,6 @@ projectPoints
 ) const
 {
     // The current patch is slave, i.e. it is being projected onto the target
-    // 
 
     if (projectionDirection.size() != nPoints())
     {
@@ -101,8 +96,8 @@ projectPoints
     // Loop through all points of the slave side. For every point find the
     // radius for the current contact face. If the contact point falls inside
     // the face and the radius is smaller than for all neighbouring faces,
-    // the contact is found. If not, visit the neighbour closest to the 
-    // calculated contact point. If a single master face is visited more than 
+    // the contact is found. If not, visit the neighbour closest to the
+    // calculated contact point. If a single master face is visited more than
     // twice, initiate n-squared search.
 
     label curFace = 0;
@@ -177,7 +172,7 @@ projectPoints
                     // Calculate the miss point on the plane of the
                     // face.  This is cooked (illogical!) for fastest
                     // surface walk.
-                    // 
+                    //
                     PointType missPlanePoint =
                         curPoint + curProjectionDir*curHit.distance();
 
@@ -216,7 +211,7 @@ projectPoints
             } while (closer);
         }
 
-        if 
+        if
         (
             doNSquaredSearch || !foundEligible
         )
@@ -297,7 +292,8 @@ template
 >
 
 template <class ToPatch>
-List<objectHit> PrimitivePatch<Face, FaceList, PointField, PointType>::
+Foam::List<Foam::objectHit>
+Foam::PrimitivePatch<Face, FaceList, PointField, PointType>::
 projectFaceCentres
 (
     const ToPatch& targetPatch,
@@ -307,7 +303,6 @@ projectFaceCentres
 ) const
 {
     // The current patch is slave, i.e. it is being projected onto the target
-    // 
 
     if (projectionDirection.size() != this->size())
     {
@@ -349,8 +344,8 @@ projectFaceCentres
     // Loop through all points of the slave side. For every point find the
     // radius for the current contact face. If the contact point falls inside
     // the face and the radius is smaller than for all neighbouring faces,
-    // the contact is found. If not, visit the neighbour closest to the 
-    // calculated contact point. If a single master face is visited more than 
+    // the contact is found. If not, visit the neighbour closest to the
+    // calculated contact point. If a single master face is visited more than
     // twice, initiate n-squared search.
 
     label curFace = 0;
@@ -424,11 +419,11 @@ projectFaceCentres
 
                     // Calculate the miss point.  This is
                     // cooked (illogical!) for fastest surface walk.
-                    // 
+                    //
                     PointType missPlanePoint =
                         curFaceCentre + curProjectionDir*curHit.distance();
 
-                    sqrDistance = 
+                    sqrDistance =
                         magSqr(missPlanePoint - masterFaceCentres[curFace]);
 
                     const labelList& masterNbrs = masterFaceFaces[curFace];
@@ -532,8 +527,4 @@ projectFaceCentres
 }
 
 
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-} // End namespace Foam
-
 // ************************************************************************* //
diff --git a/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatchExtra/PrimitivePatchExtra.C b/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatchExtra/PrimitivePatchExtra.C
deleted file mode 100644
index 14d22f06fa50c7f38df18d9060f1526d490c8e1d..0000000000000000000000000000000000000000
--- a/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatchExtra/PrimitivePatchExtra.C
+++ /dev/null
@@ -1,173 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
-     \\/     M anipulation  |
--------------------------------------------------------------------------------
-License
-    This file is part of OpenFOAM.
-
-    OpenFOAM is free software; you can redistribute it and/or modify it
-    under the terms of the GNU General Public License as published by the
-    Free Software Foundation; either version 2 of the License, or (at your
-    option) any later version.
-
-    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
-    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-    for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with OpenFOAM; if not, write to the Free Software Foundation,
-    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-\*---------------------------------------------------------------------------*/
-
-#include "PrimitivePatchExtra.H"
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
-
-// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
-
-// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
-
-// Construct from components
-template
-<
-    class Face,
-    template<class> class FaceList,
-    class PointField,
-    class PointType
->
-Foam::PrimitivePatchExtra<Face, FaceList, PointField, PointType>::
-PrimitivePatchExtra
-(
-    const FaceList<Face>& faces,
-    const Field<PointType>& points
-)
-:
-    ParentType(faces, points),
-    sortedEdgeFacesPtr_(NULL),
-    edgeOwnerPtr_(NULL)
-{}
-
-
-// Construct as copy
-template
-<
-    class Face,
-    template<class> class FaceList,
-    class PointField,
-    class PointType
->
-Foam::PrimitivePatchExtra<Face, FaceList, PointField, PointType>::
-PrimitivePatchExtra
-(
-    const PrimitivePatchExtra<Face, FaceList, PointField, PointType>& pp
-)
-:
-    ParentType(pp),
-    sortedEdgeFacesPtr_(NULL),
-    edgeOwnerPtr_(NULL)
-{}
-
-
-// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
-
-template
-<
-    class Face,
-    template<class> class FaceList,
-    class PointField,
-    class PointType
->
-Foam::PrimitivePatchExtra<Face, FaceList, PointField, PointType>::
-~PrimitivePatchExtra()
-{
-    clearOut();
-}
-
-// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
-
-template
-<
-    class Face,
-    template<class> class FaceList,
-    class PointField,
-    class PointType
->
-void Foam::PrimitivePatchExtra<Face, FaceList, PointField, PointType>::
-clearOut()
-{
-    ParentType::clearOut();
-    clearTopology();
-}
-
-
-template
-<
-    class Face,
-    template<class> class FaceList,
-    class PointField,
-    class PointType
->
-void Foam::PrimitivePatchExtra<Face, FaceList, PointField, PointType>::
-clearTopology()
-{
-    ParentType::clearTopology();
-    deleteDemandDrivenData(sortedEdgeFacesPtr_);
-    deleteDemandDrivenData(edgeOwnerPtr_);
-}
-
-
-template
-<
-    class Face,
-    template<class> class FaceList,
-    class PointField,
-    class PointType
->
-const Foam::labelListList&
-Foam::PrimitivePatchExtra<Face, FaceList, PointField, PointType>::
-sortedEdgeFaces() const
-{
-    if (!sortedEdgeFacesPtr_)
-    {
-        calcSortedEdgeFaces();
-    }
-
-    return *sortedEdgeFacesPtr_;
-}
-
-
-template
-<
-    class Face,
-    template<class> class FaceList,
-    class PointField,
-    class PointType
->
-const Foam::labelList&
-Foam::PrimitivePatchExtra<Face, FaceList, PointField, PointType>::
-edgeOwner() const
-{
-    if (!edgeOwnerPtr_)
-    {
-        calcEdgeOwner();
-    }
-
-    return *edgeOwnerPtr_;
-}
-
-
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-#include "PrimitivePatchExtraAddressing.C"
-#include "PrimitivePatchExtraCleanup.C"
-#include "PrimitivePatchExtraSearch.C"
-
-// ************************************************************************* //
diff --git a/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatchExtra/PrimitivePatchExtra.H b/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatchExtra/PrimitivePatchExtra.H
deleted file mode 100644
index 3818fcbfb50cb77aec85e63aa8f73a346ff2fb01..0000000000000000000000000000000000000000
--- a/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatchExtra/PrimitivePatchExtra.H
+++ /dev/null
@@ -1,205 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
-     \\/     M anipulation  |
--------------------------------------------------------------------------------
-License
-    This file is part of OpenFOAM.
-
-    OpenFOAM is free software; you can redistribute it and/or modify it
-    under the terms of the GNU General Public License as published by the
-    Free Software Foundation; either version 2 of the License, or (at your
-    option) any later version.
-
-    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
-    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-    for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with OpenFOAM; if not, write to the Free Software Foundation,
-    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-Class
-    Foam::PrimitivePatchExtra
-
-Description
-    PrimitivePatch with some extra functionality.
-
-SourceFiles
-    PrimitivePatchExtra.C
-
-\*---------------------------------------------------------------------------*/
-
-#ifndef PrimitivePatchExtra_H
-#define PrimitivePatchExtra_H
-
-#include "PrimitivePatch.H"
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-namespace Foam
-{
-
-/*---------------------------------------------------------------------------*\
-                    Class PrimitivePatchExtra Declaration
-\*---------------------------------------------------------------------------*/
-
-template
-<
-    class Face,
-    template<class> class FaceList,
-    class PointField,
-    class PointType=point
->
-class PrimitivePatchExtra
-:
-    public PrimitivePatch<Face, FaceList, PointField, PointType>
-{
-
-public:
-
-    // Public typedefs
-
-        typedef Face FaceType;
-        typedef FaceList<Face> FaceListType;
-        typedef PointField PointFieldType;
-
-private:
-
-    // Private typedefs
-    typedef PrimitivePatch<Face, FaceList, PointField, PointType> ParentType;
-
-    // Private data
-
-    // Demand driven private data
-
-        //- Edge-face addressing (sorted)
-        mutable labelListList* sortedEdgeFacesPtr_;
-
-        //- Label of face that 'owns' edge
-        //  i.e. e.vec() is righthanded walk along face
-        mutable labelList* edgeOwnerPtr_;
-
-
-    // Private Member Functions
-
-        //- Calculate sorted edgeFaces
-        void calcSortedEdgeFaces() const;
-
-        //- Calculate owner
-        void calcEdgeOwner() const;
-
-public:
-
-    // Constructors
-
-        //- Construct from components
-        PrimitivePatchExtra
-        (
-            const FaceList<Face>& faces,
-            const Field<PointType>& points
-        );
-
-        //- Construct as copy
-        PrimitivePatchExtra
-        (
-            const PrimitivePatchExtra<Face, FaceList, PointField, PointType>&
-        );
-
-
-    // Destructor
-
-        virtual ~PrimitivePatchExtra();
-
-        void clearOut();
-
-        void clearTopology();
-
-
-    // Member Functions
-
-    // Access functions for demand driven data
-
-    // Topological data; no mesh required.
-
-        //- Return edge-face addressing sorted by angle around the edge.
-        //  Orientation is anticlockwise looking from edge.vec(localPoints())
-        const labelListList& sortedEdgeFaces() const;
-
-        //- If 2 face neighbours: label of face where ordering of edge
-        //  is consistent with righthand walk.
-        //  If 1 neighbour: label of only face.
-        //  If >2 neighbours: undetermined.
-        const labelList& edgeOwner() const;
-
-
-    // Addressing into mesh
-
-
-    // Other patch operations
-
-
-    // Check
-
-        //- Check multiply-connected edges.
-        void checkEdges(const bool verbose) const;
-
-        //- Check orientation (normals) and normals of neighbouring faces
-        boolList checkOrientation(const bool verbose) const;
-
-
-    // Edit
-
-        //- Fill faceZone with currentZone for every face reachable
-        //  from faceI without crossing edge marked in borderEdge.
-        //  Note: faceZone has to be sized nFaces before calling.
-        void markZone
-        (
-            const UList<bool>& borderEdge,
-            const label faceI,
-            const label currentZone,
-            labelList& faceZone
-        ) const;
-
-        //- (size and) fills faceZone with zone of face.
-        //  Zone is area reachable by edge crossing without crossing borderEdge
-        //  (bool for every edge in surface). Returns number of zones.
-        label markZones
-        (
-            const UList<bool>& borderEdge,
-            labelList& faceZone
-        ) const;
-
-        //- Determine the mapping for a sub-mesh.
-        //  Only include faces for which bool List entry is true
-        //  @param[out] pointMap mapping new to old localPoints
-        //  @param[out] faceMap  mapping new to old faces
-        void subsetMap
-        (
-            const UList<bool>& include,
-            labelList& pointMap,
-            labelList& faceMap
-        ) const;
-
-
-};
-
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-} // End namespace Foam
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-#ifdef NoRepository
-#   include "PrimitivePatchExtra.C"
-#endif
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-#endif
-
-// ************************************************************************* //
diff --git a/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatchExtra/PrimitivePatchExtraAddressing.C b/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatchExtra/PrimitivePatchExtraAddressing.C
deleted file mode 100644
index 98782ea40bbc2e89bb839db0aec2c1cf965b5efd..0000000000000000000000000000000000000000
--- a/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatchExtra/PrimitivePatchExtraAddressing.C
+++ /dev/null
@@ -1,218 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
-     \\/     M anipulation  |
--------------------------------------------------------------------------------
-License
-    This file is part of OpenFOAM.
-
-    OpenFOAM is free software; you can redistribute it and/or modify it
-    under the terms of the GNU General Public License as published by the
-    Free Software Foundation; either version 2 of the License, or (at your
-    option) any later version.
-
-    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
-    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-    for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with OpenFOAM; if not, write to the Free Software Foundation,
-    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-Description
-    Contains fix for PrimitivePatch addressing (which doesn't work if surface
-    is non-manifold). Should be moved into PrimitivePatch.
-
-\*---------------------------------------------------------------------------*/
-
-#include "PrimitivePatchExtra.H"
-#include "HashTable.H"
-#include "SortableList.H"
-#include "transform.H"
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
-
-template
-<
-    class Face,
-    template<class> class FaceList,
-    class PointField,
-    class PointType
->
-void Foam::PrimitivePatchExtra<Face, FaceList, PointField, PointType>::
-calcSortedEdgeFaces() const
-{
-    if (sortedEdgeFacesPtr_)
-    {
-        FatalErrorIn
-        (
-            "PrimitivePatchExtra<Face, FaceList, PointField>::"
-            "calcSortedEdgeFaces()"
-        )
-            << "sortedEdgeFacesPtr_ already set"
-            << abort(FatalError);
-    }
-
-    const labelListList& eFaces = this->edgeFaces();
-    const edgeList& edgeLst = this->edges();
-    const Field<PointType>& locPointLst = this->localPoints();
-    const List<Face>& locFaceLst  = this->localFaces();
-
-    // create the lists for the various results. (resized on completion)
-    sortedEdgeFacesPtr_ = new labelListList(eFaces.size());
-    labelListList& sortedEdgeFaces = *sortedEdgeFacesPtr_;
-
-    forAll(eFaces, edgeI)
-    {
-        const labelList& myFaceNbs = eFaces[edgeI];
-
-        if (myFaceNbs.size() > 2)
-        {
-            // Get point on edge and normalized direction of edge (= e2 base
-            // of our coordinate system)
-            const edge& e = edgeLst[edgeI];
-
-            const point& edgePt = locPointLst[e.start()];
-
-            vector e2 = e.vec(locPointLst);
-            e2 /= mag(e2) + VSMALL;
-
-            // Get opposite vertex for 0th face
-            const Face& f = locFaceLst[myFaceNbs[0]];
-
-            label fp0 = findIndex(f, e[0]);
-            label fp1 = f.fcIndex(fp0);
-            label vertI = (f[fp1] != e[1] ? f[fp1] : f.fcIndex(fp1));
-
-            // Get vector normal both to e2 and to edge from opposite vertex
-            // to edge (will be x-axis of our coordinate system)
-            vector e0 = e2 ^ (locPointLst[vertI] - edgePt);
-            e0 /= mag(e0) + VSMALL;
-
-            // Get y-axis of coordinate system
-            vector e1 = e2 ^ e0;
-
-            SortableList<scalar> faceAngles(myFaceNbs.size());
-
-            // e0 is reference so angle is 0
-            faceAngles[0] = 0;
-
-            for (label nbI = 1; nbI < myFaceNbs.size(); nbI++)
-            {
-                // Get opposite vertex
-                const Face& f = locFaceLst[myFaceNbs[nbI]];
-                label fp0 = findIndex(f, e[0]);
-                label fp1 = f.fcIndex(fp0);
-                label vertI = (f[fp1] != e[1] ? f[fp1] : f.fcIndex(fp1));
-
-                vector vec = e2 ^ (locPointLst[vertI] - edgePt);
-                vec /= mag(vec) + VSMALL;
-
-                faceAngles[nbI] = pseudoAngle
-                (
-                    e0,
-                    e1,
-                    vec
-                );
-            }
-
-            faceAngles.sort();
-
-            sortedEdgeFaces[edgeI] = IndirectList<label>
-            (
-                myFaceNbs,
-                faceAngles.indices()
-            );
-        }
-        else
-        {
-            // No need to sort. Just copy.
-            sortedEdgeFaces[edgeI] = myFaceNbs;
-        }
-    }
-}
-
-
-template
-<
-    class Face,
-    template<class> class FaceList,
-    class PointField,
-    class PointType
->
-void Foam::PrimitivePatchExtra<Face, FaceList, PointField, PointType>::
-calcEdgeOwner() const
-{
-    if (edgeOwnerPtr_)
-    {
-        FatalErrorIn
-        (
-            "PrimitivePatchExtra<Face, FaceList, PointField>::"
-            "calcEdgeOwner()"
-        )
-            << "edgeOwnerPtr_ already set"
-            << abort(FatalError);
-    }
-
-    // create the owner list
-    edgeOwnerPtr_ = new labelList(this->nEdges());
-    labelList& edgeOwner = *edgeOwnerPtr_;
-
-    const edgeList& edgeLst = this->edges();
-    const labelListList& eFaces = this->edgeFaces();
-    const List<Face>& locFaceLst = this->localFaces();
-
-
-    forAll(edgeLst, edgeI)
-    {
-        const edge& e = edgeLst[edgeI];
-        const labelList& neighbouringFaces = eFaces[edgeI];
-
-        if (neighbouringFaces.size() == 1)
-        {
-            edgeOwner[edgeI] = neighbouringFaces[0];
-        }
-        else
-        {
-            // Find the first face whose vertices are aligned with the edge.
-            // with multiply connected edges, this is the best we can do
-            edgeOwner[edgeI] = -1;
-
-            forAll(neighbouringFaces, i)
-            {
-                const Face& f = locFaceLst[neighbouringFaces[i]];
-
-                if (f.edgeDirection(e) > 0)
-                {
-                    edgeOwner[edgeI] = neighbouringFaces[i];
-                    break;
-                }
-            }
-
-            if (edgeOwner[edgeI] == -1)
-            {
-                FatalErrorIn
-                (
-                    "PrimitivePatchExtra<Face, FaceList, PointField>::"
-                    "calcEdgeOwner()"
-                )
-                    << "Edge " << edgeI << " vertices:" << e
-                    << " is used by faces " << neighbouringFaces
-                    << " vertices:"
-                    << IndirectList<Face>(locFaceLst, neighbouringFaces)()
-                    << " none of which use the edge vertices in the same order"
-                    << nl << "I give up" << abort(FatalError);
-            }
-        }
-    }
-}
-
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-// ************************************************************************* //
diff --git a/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatchExtra/PrimitivePatchExtraCleanup.C b/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatchExtra/PrimitivePatchExtraCleanup.C
deleted file mode 100644
index c825f44a0e10dd309b23ecaa53dc79cdbb1f8a09..0000000000000000000000000000000000000000
--- a/src/OpenFOAM/meshes/primitiveMesh/PrimitivePatchExtra/PrimitivePatchExtraCleanup.C
+++ /dev/null
@@ -1,239 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
-     \\/     M anipulation  |
--------------------------------------------------------------------------------
-License
-    This file is part of OpenFOAM.
-
-    OpenFOAM is free software; you can redistribute it and/or modify it
-    under the terms of the GNU General Public License as published by the
-    Free Software Foundation; either version 2 of the License, or (at your
-    option) any later version.
-
-    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
-    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-    for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with OpenFOAM; if not, write to the Free Software Foundation,
-    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-\*---------------------------------------------------------------------------*/
-
-#include "PrimitivePatchExtra.H"
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
-
-// Check/fix edges with more than two faces
-template
-<
-    class Face,
-    template<class> class FaceList,
-    class PointField,
-    class PointType
->
-void Foam::PrimitivePatchExtra<Face, FaceList, PointField, PointType>::
-checkEdges
-(
-    const bool verbose
-) const
-{
-    const labelListList& eFaces = this->edgeFaces();
-    const edgeList& edgeLst = this->edges();
-
-    forAll(eFaces, edgeI)
-    {
-        const labelList& myFaces = eFaces[edgeI];
-
-        // boundary edges have one face
-        // interior edges have two faces
-        if (myFaces.empty())
-        {
-            FatalErrorIn
-            (
-                "PrimitivePatchExtra::checkEdges(bool verbose)"
-            )
-                << "Edge " << edgeI << " with vertices " << edgeLst[edgeI]
-                << " has no edgeFaces"
-                << exit(FatalError);
-        }
-        else if (myFaces.size() > 2)
-        {
-            WarningIn
-            (
-                "PrimitivePatchExtra::checkEdges(bool verbose)"
-            )
-                << "Edge " << edgeI << " with vertices " << edgeLst[edgeI]
-                << " has more than 2 faces connected to it : " << myFaces
-                << endl;
-        }
-    }
-}
-
-
-// Check normals and orientation
-template
-<
-    class Face,
-    template<class> class FaceList,
-    class PointField,
-    class PointType
->
-Foam::boolList
-Foam::PrimitivePatchExtra<Face, FaceList, PointField, PointType>::
-checkOrientation
-(
-    const bool verbose
-) const
-{
-    const FaceList<Face>& faceLst = *this;
-    const edgeList& edgeLst = this->edges();
-    const labelListList& faceEs = this->faceEdges();
-    const label numEdges = this->nEdges();
-    const Field<PointType>& pointLst = this->points();
-    const vectorField& normLst = this->faceNormals();
-
-    if (ParentType::debug)
-    {
-        Info<<"checkOrientation:::checkOrientation(bool)" << endl;
-    }
-
-    // Check edge normals, face normals, point normals.
-    forAll(faceEs, faceI)
-    {
-        const labelList& edgeLabels = faceEs[faceI];
-
-        if (edgeLabels.size() < 3)
-        {
-            FatalErrorIn
-            (
-                "PrimitivePatchExtra::checkOrientation(bool)"
-            )
-                << "face " << faceLst[faceI]
-                << " has fewer than 3 edges. Edges:" << edgeLabels
-                << exit(FatalError);
-        }
-
-        bool valid = true;
-        forAll(edgeLabels, i)
-        {
-            if (edgeLabels[i] < 0 || edgeLabels[i] >= numEdges)
-            {
-                WarningIn
-                (
-                    "PrimitivePatchExtra::checkOrientation(bool)"
-                )
-                    << "edge number " << edgeLabels[i] << " on face " << faceI
-                    << " out-of-range\n"
-                    << "This usually means the input surface has "
-                    << "edges with more than 2 faces connected.\n"
-                    << endl;
-                valid = false;
-            }
-        }
-        if (!valid)
-        {
-            continue;
-        }
-
-
-        //
-        //- Compute normal from 3 points, use the first as the origin
-        // minor warpage should not be a problem
-        const Face& f = faceLst[faceI];
-        const point p0(pointLst[f[0]]);
-        const point p1(pointLst[f[1]]);
-        const point p2(pointLst[f[f.size()-1]]);
-
-        const vector pointNormal((p1 - p0) ^ (p2 - p0));
-        if ((pointNormal & normLst[faceI]) < 0)
-        {
-            FatalErrorIn
-            (
-                "PrimitivePatchExtra::checkOrientation(bool)"
-            )
-                << "Normal calculated from points inconsistent with faceNormal"
-                << nl
-                << "face: " << f << nl
-                << "points: " << p0 << ' ' << p1 << ' ' << p2 << nl
-                << "pointNormal:" << pointNormal << nl
-                << "faceNormal:" << normLst[faceI]
-                << exit(FatalError);
-        }
-    }
-
-
-    const labelListList& eFaces    = this->edgeFaces();
-    const pointField& locPointsLst = this->localPoints();
-
-    // Storage for holding status of edge.
-    // True if normal flips across this edge
-    boolList borderEdge(numEdges, false);
-
-    forAll(edgeLst, edgeI)
-    {
-        const edge& e = edgeLst[edgeI];
-        const labelList& neighbouringFaces = eFaces[edgeI];
-
-        if (neighbouringFaces.size() == 2)
-        {
-            // we use localFaces() since edges() are LOCAL
-            // these are both already available
-            const Face& faceA = this->localFaces()[neighbouringFaces[0]];
-            const Face& faceB = this->localFaces()[neighbouringFaces[1]];
-
-            // If the faces are correctly oriented, the edges must go in
-            // different directions on connected faces.
-            if (faceA.edgeDirection(e) == faceB.edgeDirection(e))
-            {
-                borderEdge[edgeI] = true;
-                if (verbose)
-                {
-                    WarningIn
-                    (
-                        "PrimitivePatchExtra::checkOrientation(bool)"
-                    )
-                        << "face orientation incorrect." << nl
-                        << "localEdge[" << edgeI << "] " << e
-                        << " between faces:" << nl
-                        << "  face[" << neighbouringFaces[0] << "] "
-                        << faceLst[neighbouringFaces[0]]
-                        << "   localFace: " << faceA
-                        << nl
-                        << "  face[" << neighbouringFaces[1] << "] "
-                        << faceLst[neighbouringFaces[1]]
-                        << "   localFace: " << faceB
-                        << endl;
-                }
-            }
-        }
-        else if (neighbouringFaces.size() != 1)
-        {
-            if (verbose)
-            {
-                WarningIn
-                (
-                    "PrimitivePatchExtra::checkOrientation(bool)"
-                )
-                    << "Wrong number of edge neighbours." << nl
-                    << "edge[" << edgeI << "] " << e
-                    << " with points:" << locPointsLst[e.start()]
-                    << ' ' << locPointsLst[e.end()]
-                    << " has neighbouringFaces:" << neighbouringFaces << endl;
-            }
-            borderEdge[edgeI] = true;
-        }
-    }
-
-    return borderEdge;
-}
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-// ************************************************************************* //
diff --git a/src/OpenFOAM/primitives/Lists/PackedBoolList.H b/src/OpenFOAM/primitives/Lists/PackedBoolList.H
index 84d99561362dec03dbeecaf34154f9f97ba3e686..1c2f3179457ddf6082fbb354e78f317ebd8881b9 100644
--- a/src/OpenFOAM/primitives/Lists/PackedBoolList.H
+++ b/src/OpenFOAM/primitives/Lists/PackedBoolList.H
@@ -40,7 +40,7 @@ Description
 
 namespace Foam
 {
-    typedef PackedList<1> PackedBoolList;
+    typedef PackedList<> PackedBoolList;
 }
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
diff --git a/src/OpenFOAM/primitives/bools/Switch/Switch.C b/src/OpenFOAM/primitives/bools/Switch/Switch.C
index caf3cebf98dc12fcc0a1d43aa4adf172412aeacb..9b7b449a226452dab9f93d65966c3f472659bc2d 100644
--- a/src/OpenFOAM/primitives/bools/Switch/Switch.C
+++ b/src/OpenFOAM/primitives/bools/Switch/Switch.C
@@ -46,7 +46,7 @@ const char* Foam::Switch::names[Foam::Switch::INVALID+1] =
 
 Foam::Switch::switchType Foam::Switch::asEnum(const bool val)
 {
-    return val ? Switch::FALSE : Switch::TRUE;
+    return val ? Switch::TRUE : Switch::FALSE;
 }
 
 
diff --git a/src/OpenFOAM/primitives/bools/bool/boolIO.C b/src/OpenFOAM/primitives/bools/bool/boolIO.C
index a78cfbb7b8fcbd774bfe322f9d98c02cc3bdadbb..bfd087dda748740fdcbb09fca426827ec7080051 100644
--- a/src/OpenFOAM/primitives/bools/bool/boolIO.C
+++ b/src/OpenFOAM/primitives/bools/bool/boolIO.C
@@ -39,63 +39,11 @@ Description
 
 Foam::Istream& Foam::operator>>(Istream& is, bool& b)
 {
-    // we could also process everything via Switch
-    // The error messages are the problem: they are from SwitchIO.C
-//    Switch sw(is);
-//
-//    if (is.good())
-//    {
-//        b = sw;
-//    }
-//
-//    return is;
-//
-//
-    token t(is);
-
-    if (!t.good())
+    if (is.good())
     {
-        is.setBad();
-        return is;
+        b = Switch(is);
     }
 
-    if (t.isLabel())
-    {
-        b = bool(t.labelToken());
-    }
-    else if (t.isWord())
-    {
-        // allow invalid values, but catch after for correct error message
-        Switch::switchType sw = Switch::asEnum(t.wordToken(), true);
-
-        if (sw == Switch::INVALID)
-        {
-            is.setBad();
-            FatalIOErrorIn("operator>>(Istream&, bool&)", is)
-                << "expected 'true/false', 'on/off', found " << t.wordToken()
-                << exit(FatalIOError);
-
-            return is;
-        }
-        else
-        {
-            b = Switch::asBool(sw);
-        }
-    }
-    else
-    {
-        is.setBad();
-        FatalIOErrorIn("operator>>(Istream&, bool/Switch&)", is)
-            << "wrong token type - expected bool found " << t
-            << exit(FatalIOError);
-
-        return is;
-    }
-
-
-    // Check state of Istream
-    is.check("Istream& operator>>(Istream&, bool&)");
-
     return is;
 }
 
diff --git a/src/OpenFOAM/primitives/strings/fileName/fileName.C b/src/OpenFOAM/primitives/strings/fileName/fileName.C
index dbf0a664e81bfda46375fc8721a1465744e09560..3f41e9e692698f4833bd0d946a53ef410a0d3484 100644
--- a/src/OpenFOAM/primitives/strings/fileName/fileName.C
+++ b/src/OpenFOAM/primitives/strings/fileName/fileName.C
@@ -26,6 +26,7 @@ License
 
 #include "fileName.H"
 #include "wordList.H"
+#include "DynamicList.H"
 #include "debug.H"
 #include "OSspecific.H"
 
@@ -48,6 +49,30 @@ Foam::fileName::fileName(const wordList& lst)
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
+Foam::fileName::Type Foam::fileName::type() const
+{
+    return ::Foam::type(*this);
+}
+
+
+bool Foam::fileName::exists() const
+{
+    return ::Foam::exists(*this);
+}
+
+
+bool Foam::fileName::isDir() const
+{
+    return ::Foam::dir(*this);
+}
+
+
+bool Foam::fileName::isFile() const
+{
+    return ::Foam::file(*this);
+}
+
+
 //  Return file name (part beyond last /)
 //
 //  behaviour compared to /usr/bin/basename:
@@ -93,13 +118,13 @@ Foam::fileName Foam::fileName::path() const
     {
         return ".";
     }
-    else if (i == 0)
+    else if (i)
     {
-        return "/";
+        return substr(0, i);
     }
     else
     {
-        return substr(0, i);
+        return "/";
     }
 }
 
@@ -145,28 +170,22 @@ Foam::word Foam::fileName::ext() const
 //    -----           ------
 //    "foo"           1("foo")
 //    "/foo"          1("foo")
-//    "foo/bar"       2("foo", "foo")
-//    "/foo/bar"      2("foo", "foo")
+//    "foo/bar"       2("foo", "bar")
+//    "/foo/bar"      2("foo", "bar")
 //    "/foo/bar/"     2("foo", "bar")
 //
 Foam::wordList Foam::fileName::components(const char delimiter) const
 {
-    wordList wrdList(20);
+    DynamicList<word> wrdList(20);
 
     size_type start=0, end=0;
-    label nWords=0;
 
     while ((end = find(delimiter, start)) != npos)
     {
         // avoid empty element (caused by doubled slashes)
         if (start < end)
         {
-            wrdList[nWords++] = substr(start, end-start);
-
-            if (nWords == wrdList.size())
-            {
-                wrdList.setSize(2*wrdList.size());
-            }
+            wrdList.append(substr(start, end-start));
         }
         start = end + 1;
     }
@@ -174,12 +193,11 @@ Foam::wordList Foam::fileName::components(const char delimiter) const
     // avoid empty trailing element
     if (start < size())
     {
-        wrdList[nWords++] = substr(start, npos);
+        wrdList.append(substr(start, npos));
     }
 
-    wrdList.setSize(nWords);
-
-    return wrdList;
+    // transfer to wordList
+    return wordList(wrdList.xfer());
 }
 
 
@@ -194,12 +212,94 @@ Foam::word Foam::fileName::component
 }
 
 
-Foam::fileName::Type Foam::fileName::type() const
+
+// Return components following the IOobject requirements
+//
+//  behaviour
+//    input               IOobject(instance, local, name)
+//    -----               ------
+//    "foo"               ("", "", "foo")
+//    "foo/bar"           ("foo", "", "bar")
+//    "/XXX"              ERROR - no absolute path
+//    "foo/bar/"          ERROR - no name
+//    "foo/xxx/bar"       ("foo", "xxx", "bar")
+//    "foo/xxx/yyy/bar"   ("foo", "xxx/yyy", "bar")
+bool Foam::fileName::IOobjectComponents
+(
+    fileName& instance,
+    fileName& local,
+    word& name
+)
+const
 {
-    return ::Foam::type(*this);
+    instance.clear();
+    local.clear();
+    name.clear();
+
+    // called with directory
+    if (::Foam::dir(*this))
+    {
+        std::cerr
+            << "fileName::IOobjectComponents() called with directory: "
+            << this->c_str() << std::endl;
+        std::abort();
+
+        return false;
+    }
+
+    size_type first = find('/');
+
+    if (first == 0)
+    {
+        // called with absolute path
+        std::cerr
+            << "fileName::IOobjectComponents() called with absolute path: "
+            << this->c_str() << std::endl;
+        std::abort();
+
+        return false;
+    }
+
+    if (first == npos)
+    {
+        // no '/' found - no instance or local
+
+        // check afterwards
+        name.string::operator=(*this);
+    }
+    else
+    {
+        instance = substr(0, first);
+
+        size_type last = rfind('/');
+        if (last > first)
+        {
+            // with local
+            local = substr(first+1, last-first-1);
+        }
+
+        // check afterwards
+        name.string::operator=(substr(last+1));
+    }
+
+
+    // check for valid (and stripped) name, regardless of the debug level
+    if (name.empty() || string::stripInvalid<word>(name))
+    {
+        std::cerr
+            << "fileName::IOobjectComponents() has invalid word for name: "
+            << name.c_str() << "\nwhile processing  "
+            << this->c_str() << std::endl;
+        std::abort();
+
+        return false;
+    }
+
+    return true;
 }
 
 
+
 // * * * * * * * * * * * * * * * Member Operators  * * * * * * * * * * * * * //
 
 void Foam::fileName::operator=(const fileName& str)
diff --git a/src/OpenFOAM/primitives/strings/fileName/fileName.H b/src/OpenFOAM/primitives/strings/fileName/fileName.H
index 24dd213ef522cee5a75a8cc0937837fdc5ac4dc3..0eeb89312e19af4cb672e0b39ab772b3d0834c64 100644
--- a/src/OpenFOAM/primitives/strings/fileName/fileName.H
+++ b/src/OpenFOAM/primitives/strings/fileName/fileName.H
@@ -129,6 +129,20 @@ public:
         inline static bool valid(char);
 
 
+        // Interogation
+
+            //- Return the file type: FILE, DIRECTORY or UNDEFINED
+            Type type() const;
+
+            //- Does it exist (as FILE or DIRECTORY) in the file system?
+            bool exists() const;
+
+            //- Does it exist as DIRECTORY in the file system?
+            bool isDir() const;
+
+            //- Does it exist as FILE in the file system?
+            bool isFile() const;
+
         // Decomposition
 
             //- Return file name (part beyond last /)
@@ -146,14 +160,16 @@ public:
             //- Return path components as wordList
             wordList components(const char delimiter='/') const;
 
-            //- Return a component of the path
+            //- Return a single component of the path
             word component(const size_type, const char delimiter='/') const;
 
-
-        // Interogation
-
-            //- Return file type
-            Type type() const;
+            //- Return path as instance, local, name components for IOobject
+            bool IOobjectComponents
+            (
+                fileName& instance,
+                fileName& local,
+                word& name
+            ) const;
 
 
     // Member operators
diff --git a/src/Pstream/Allwmake b/src/Pstream/Allwmake
index f43c2b1a30a3f05be9019deb965bf619c95f203e..cb2c43e843246ec3b50afc715b2492a8a4228db8 100755
--- a/src/Pstream/Allwmake
+++ b/src/Pstream/Allwmake
@@ -6,17 +6,17 @@ wmake libso dummy
 
 case "$WM_MPLIB" in
 GAMMA)
-   wmake libso gamma
-   ;;
+    wmake libso gamma
+    ;;
 
 LAM | *MPI* )
-   export WM_OPTIONS=${WM_OPTIONS}$WM_MPLIB
-   set +x
-   echo
-   echo "Note: ignore spurious warnings about missing mpicxx.h headers"
-   set -x
-   wmake libso mpi
-   ;;
+    WM_OPTIONS=${WM_OPTIONS}$WM_MPLIB
+    set +x
+    echo
+    echo "Note: ignore spurious warnings about missing mpicxx.h headers"
+    set -x
+    wmake libso mpi
+    ;;
 esac
 
 # ----------------------------------------------------------------- end-of-file
diff --git a/src/autoMesh/autoHexMesh/autoHexMeshDriver/autoHexMeshDriver.C b/src/autoMesh/autoHexMesh/autoHexMeshDriver/autoHexMeshDriver.C
index 7a3152b494e0c0824e1ae7576f3edff7c6ed947e..0438fa276d330d60e92368e907f317adc2e59947 100644
--- a/src/autoMesh/autoHexMesh/autoHexMeshDriver/autoHexMeshDriver.C
+++ b/src/autoMesh/autoHexMesh/autoHexMeshDriver/autoHexMeshDriver.C
@@ -223,10 +223,10 @@ Foam::autoHexMeshDriver::autoHexMeshDriver
             (
                 IOobject
                 (
-                    "abc",                      // dummy name
-                    mesh_.time().timeName(),    // directory
-                    "triSurface",               // instance
-                    mesh_.time(),               // registry
+                    "abc",                                      // dummy name
+                    mesh_.time().findInstance("triSurface", word::null),// inst
+                    "triSurface",                               // local
+                    mesh_.time(),                               // registry
                     IOobject::MUST_READ,
                     IOobject::NO_WRITE
                 ),
diff --git a/src/autoMesh/autoHexMesh/autoHexMeshDriver/autoRefineDriver.C b/src/autoMesh/autoHexMesh/autoHexMeshDriver/autoRefineDriver.C
index e53c4e041a9b204b259ce65f53acfd32a5e345c1..e891cf761c7e452fa5003016cb4d92b868312997 100644
--- a/src/autoMesh/autoHexMesh/autoHexMeshDriver/autoRefineDriver.C
+++ b/src/autoMesh/autoHexMesh/autoHexMeshDriver/autoRefineDriver.C
@@ -77,10 +77,11 @@ Foam::label Foam::autoRefineDriver::readFeatureEdges
             (
                 IOobject
                 (
-                    featFileName,           // name
-                    mesh.time().constant(), // directory
-                    "triSurface",           // instance
-                    mesh.time(),            // registry
+                    featFileName,                       // name
+                    mesh.time().findInstance("triSurface", featFileName),
+                                                        // instance
+                    "triSurface",                       // local
+                    mesh.time(),                        // registry
                     IOobject::MUST_READ,
                     IOobject::NO_WRITE,
                     false
diff --git a/src/autoMesh/autoHexMesh/meshRefinement/meshRefinement.H b/src/autoMesh/autoHexMesh/meshRefinement/meshRefinement.H
index c684fbaad4511e961fda77260301304fa2f8cdf2..7720386219fb8e8fc92a82855925e4b8a9e0c9dc 100644
--- a/src/autoMesh/autoHexMesh/meshRefinement/meshRefinement.H
+++ b/src/autoMesh/autoHexMesh/meshRefinement/meshRefinement.H
@@ -413,6 +413,16 @@ private:
                 labelList& cellToZone
             ) const;
 
+            //- Determines cell zone from cell region information.
+            bool calcRegionToZone
+            (
+                const label surfZoneI,
+                const label ownRegion,
+                const label neiRegion,
+
+                labelList& regionToCellZone
+            ) const;
+
             //- Finds zone per cell. Uses topological walk with all faces
             //  marked in namedSurfaceIndex regarded as blocked.
             void findCellZoneTopo
@@ -423,6 +433,12 @@ private:
                 labelList& cellToZone
             ) const;
 
+            void makeConsistentFaceIndex
+            (
+                const labelList& cellToZone,
+                labelList& namedSurfaceIndex
+            ) const;
+
 
         //- Disallow default bitwise copy construct
         meshRefinement(const meshRefinement&);
diff --git a/src/autoMesh/autoHexMesh/meshRefinement/meshRefinementBaffles.C b/src/autoMesh/autoHexMesh/meshRefinement/meshRefinementBaffles.C
index 2d7ca7314bcd5e5228c75b6598940f71764cff5a..798d6d5ae4c44812d8f09df162081e7ec57975a2 100644
--- a/src/autoMesh/autoHexMesh/meshRefinement/meshRefinementBaffles.C
+++ b/src/autoMesh/autoHexMesh/meshRefinement/meshRefinementBaffles.C
@@ -1011,20 +1011,24 @@ void Foam::meshRefinement::findCellZoneGeometric
     }
 
     labelList neiCellZone(mesh_.nFaces()-mesh_.nInternalFaces());
-    for
-    (
-        label faceI = mesh_.nInternalFaces();
-        faceI < mesh_.nFaces();
-        faceI++
-    )
+    const polyBoundaryMesh& patches = mesh_.boundaryMesh();
+
+    forAll(patches, patchI)
     {
-        label own = mesh_.faceOwner()[faceI];
-        neiCellZone[faceI-mesh_.nInternalFaces()] = cellToZone[own];
+        const polyPatch& pp = patches[patchI];
+
+        if (pp.coupled())
+        {
+            forAll(pp, i)
+            {
+                label faceI = pp.start()+i;
+                label ownZone = cellToZone[mesh_.faceOwner()[faceI]];
+                neiCellZone[faceI-mesh_.nInternalFaces()] = ownZone;
+            }
+        }
     }
     syncTools::swapBoundaryFaceList(mesh_, neiCellZone, false);
 
-    const polyBoundaryMesh& patches = mesh_.boundaryMesh();
-
     forAll(patches, patchI)
     {
         const polyPatch& pp = patches[patchI];
@@ -1061,6 +1065,64 @@ void Foam::meshRefinement::findCellZoneGeometric
 }
 
 
+bool Foam::meshRefinement::calcRegionToZone
+(
+    const label surfZoneI,
+    const label ownRegion,
+    const label neiRegion,
+
+    labelList& regionToCellZone
+) const
+{
+    bool changed = false;
+
+    // Check whether inbetween different regions
+    if (ownRegion != neiRegion)
+    {
+        // Jump. Change one of the sides to my type.
+
+        // 1. Interface between my type and unset region.
+        // Set region to keepRegion
+
+        if (regionToCellZone[ownRegion] == -2)
+        {
+            if (regionToCellZone[neiRegion] == surfZoneI)
+            {
+                // Face between unset and my region. Put unset
+                // region into keepRegion
+                regionToCellZone[ownRegion] = -1;
+                changed = true;
+            }
+            else if (regionToCellZone[neiRegion] != -2)
+            {
+                // Face between unset and other region.
+                // Put unset region into my region
+                regionToCellZone[ownRegion] = surfZoneI;
+                changed = true;
+            }
+        }
+        else if (regionToCellZone[neiRegion] == -2)
+        {
+            if (regionToCellZone[ownRegion] == surfZoneI)
+            {
+                // Face between unset and my region. Put unset
+                // region into keepRegion
+                regionToCellZone[neiRegion] = -1;
+                changed = true;
+            }
+            else if (regionToCellZone[ownRegion] != -2)
+            {
+                // Face between unset and other region.
+                // Put unset region into my region
+                regionToCellZone[neiRegion] = surfZoneI;
+                changed = true;
+            }
+        }
+    }
+    return changed;
+}
+
+
 // Finds region per cell. Assumes:
 // - region containing keepPoint does not go into a cellZone
 // - all other regions can be found by crossing faces marked in
@@ -1152,59 +1214,75 @@ void Foam::meshRefinement::findCellZoneTopo
     {
         bool changed = false;
 
+        // Internal faces
+
         for (label faceI = 0; faceI < mesh_.nInternalFaces(); faceI++)
         {
             label surfI = namedSurfaceIndex[faceI];
 
             if (surfI != -1)
             {
-                // Get cell zone that surface cells are in
-                label surfZoneI = surfaceToCellZone[surfI];
+                // Calculate region to zone from cellRegions on either side
+                // of internal face.
+                bool changedCell = calcRegionToZone
+                (
+                    surfaceToCellZone[surfI],
+                    cellRegion[mesh_.faceOwner()[faceI]],
+                    cellRegion[mesh_.faceNeighbour()[faceI]],
+                    regionToCellZone
+                );
+
+                changed = changed | changedCell;
+            }
+        }
 
-                // Check whether inbetween different regions
-                label ownRegion = cellRegion[mesh_.faceOwner()[faceI]];
-                label neiRegion = cellRegion[mesh_.faceNeighbour()[faceI]];
+        // Boundary faces
 
-                if (ownRegion != neiRegion)
+        const polyBoundaryMesh& patches = mesh_.boundaryMesh();
+
+        // Get coupled neighbour cellRegion
+        labelList neiCellRegion(mesh_.nFaces()-mesh_.nInternalFaces());
+        forAll(patches, patchI)
+        {
+            const polyPatch& pp = patches[patchI];
+
+            if (pp.coupled())
+            {
+                forAll(pp, i)
                 {
-                    // Jump. Change one of the sides to my type.
+                    label faceI = pp.start()+i;
+                    neiCellRegion[faceI-mesh_.nInternalFaces()] =
+                        cellRegion[mesh_.faceOwner()[faceI]];
+                }
+            }
+        }
+        syncTools::swapBoundaryFaceList(mesh_, neiCellRegion, false);
 
-                    // 1. Interface between my type and unset region.
-                    // Set region to keepRegion
+        // Calculate region to zone from cellRegions on either side of coupled
+        // face.
+        forAll(patches, patchI)
+        {
+            const polyPatch& pp = patches[patchI];
 
-                    if (regionToCellZone[ownRegion] == -2)
-                    {
-                        if (regionToCellZone[neiRegion] == surfZoneI)
-                        {
-                            // Face between unset and my region. Put unset
-                            // region into keepRegion
-                            regionToCellZone[ownRegion] = -1;
-                            changed = true;
-                        }
-                        else if (regionToCellZone[neiRegion] != -2)
-                        {
-                            // Face between unset and other region.
-                            // Put unset region into my region
-                            regionToCellZone[ownRegion] = surfZoneI;
-                            changed = true;
-                        }
-                    }
-                    else if (regionToCellZone[neiRegion] == -2)
+            if (pp.coupled())
+            {
+                forAll(pp, i)
+                {
+                    label faceI = pp.start()+i;
+
+                    label surfI = namedSurfaceIndex[faceI];
+
+                    if (surfI != -1)
                     {
-                        if (regionToCellZone[ownRegion] == surfZoneI)
-                        {
-                            // Face between unset and my region. Put unset
-                            // region into keepRegion
-                            regionToCellZone[neiRegion] = -1;
-                            changed = true;
-                        }
-                        else if (regionToCellZone[ownRegion] != -2)
-                        {
-                            // Face between unset and other region.
-                            // Put unset region into my region
-                            regionToCellZone[neiRegion] = surfZoneI;
-                            changed = true;
-                        }
+                        bool changedCell = calcRegionToZone
+                        (
+                            surfaceToCellZone[surfI],
+                            cellRegion[mesh_.faceOwner()[faceI]],
+                            neiCellRegion[faceI-mesh_.nInternalFaces()],
+                            regionToCellZone
+                        );
+
+                        changed = changed | changedCell;
                     }
                 }
             }
@@ -1258,6 +1336,88 @@ void Foam::meshRefinement::findCellZoneTopo
 }
 
 
+// Make namedSurfaceIndex consistent with cellToZone - clear out any blocked
+// faces inbetween same cell zone.
+void Foam::meshRefinement::makeConsistentFaceIndex
+(
+    const labelList& cellToZone,
+    labelList& namedSurfaceIndex
+) const
+{
+    const labelList& faceOwner = mesh_.faceOwner();
+    const labelList& faceNeighbour = mesh_.faceNeighbour();
+
+    for (label faceI = 0; faceI < mesh_.nInternalFaces(); faceI++)
+    {
+        label ownZone = cellToZone[faceOwner[faceI]];
+        label neiZone = cellToZone[faceNeighbour[faceI]];
+
+        if (ownZone == neiZone && namedSurfaceIndex[faceI] != -1)
+        {
+            namedSurfaceIndex[faceI] = -1;
+        }
+        else if (ownZone != neiZone && namedSurfaceIndex[faceI] == -1)
+        {
+            FatalErrorIn("meshRefinement::zonify()")
+                << "Different cell zones on either side of face " << faceI
+                << " at " << mesh_.faceCentres()[faceI]
+                << " but face not marked with a surface."
+                << abort(FatalError);
+        }
+    }
+
+    const polyBoundaryMesh& patches = mesh_.boundaryMesh();
+
+    // Get coupled neighbour cellZone
+    labelList neiCellZone(mesh_.nFaces()-mesh_.nInternalFaces());
+    forAll(patches, patchI)
+    {
+        const polyPatch& pp = patches[patchI];
+
+        if (pp.coupled())
+        {
+            forAll(pp, i)
+            {
+                label faceI = pp.start()+i;
+                neiCellZone[faceI-mesh_.nInternalFaces()] =
+                    cellToZone[mesh_.faceOwner()[faceI]];
+            }
+        }
+    }
+    syncTools::swapBoundaryFaceList(mesh_, neiCellZone, false);
+
+    // Use coupled cellZone to do check
+    forAll(patches, patchI)
+    {
+        const polyPatch& pp = patches[patchI];
+
+        if (pp.coupled())
+        {
+            forAll(pp, i)
+            {
+                label faceI = pp.start()+i;
+
+                label ownZone = cellToZone[faceOwner[faceI]];
+                label neiZone = neiCellZone[faceI-mesh_.nInternalFaces()];
+
+                if (ownZone == neiZone && namedSurfaceIndex[faceI] != -1)
+                {
+                    namedSurfaceIndex[faceI] = -1;
+                }
+                else if (ownZone != neiZone && namedSurfaceIndex[faceI] == -1)
+                {
+                    FatalErrorIn("meshRefinement::zonify()")
+                        << "Different cell zones on either side of face "
+                        << faceI << " at " << mesh_.faceCentres()[faceI]
+                        << " but face not marked with a surface."
+                        << abort(FatalError);
+                }
+            }
+        }
+    }
+}
+
+
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
 // Split off unreachable areas of mesh.
@@ -2166,36 +2326,6 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::meshRefinement::zonify
         );
     }
 
-    //{
-    //    Pout<< "** finding out blocked faces." << endl;
-    //
-    //    cellSet zonedCellsGeom(mesh_, "zonedCellsGeom", 100);
-    //    forAll(cellToZone, cellI)
-    //    {
-    //        if (cellToZone[cellI] >= 0)
-    //        {
-    //            zonedCellsGeom.insert(cellI);
-    //        }
-    //    }
-    //    Pout<< "Writing zoned cells to " << zonedCellsGeom.objectPath()
-    //        << endl;
-    //    zonedCellsGeom.write();
-    //
-    //
-    //    faceSet zonedFaces(mesh_, "zonedFaces", 100);
-    //    forAll(namedSurfaceIndex, faceI)
-    //    {
-    //        label surfI = namedSurfaceIndex[faceI];
-    //
-    //        if (surfI != -1)
-    //        {
-    //            zonedFaces.insert(faceI);
-    //        }
-    //    }
-    //    Pout<< "Writing zoned faces to " << zonedFaces.objectPath() << endl;
-    //    zonedFaces.write();
-    //}
-
     // Set using walking
     // ~~~~~~~~~~~~~~~~~
 
@@ -2212,6 +2342,10 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::meshRefinement::zonify
     }
 
 
+    //// Make sure namedSurfaceIndex is unset inbetween same cell cell zones.
+    //makeConsistentFaceIndex(cellToZone, namedSurfaceIndex);
+
+
     // Topochange container
     polyTopoChange meshMod(mesh_);
 
@@ -2314,6 +2448,9 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::meshRefinement::zonify
         mesh_.clearOut();
     }
 
+    // None of the faces has changed, only the zones. Still...
+    updateMesh(map, labelList());
+
     return map;
 }
 
diff --git a/src/autoMesh/autoHexMesh/refinementSurfaces/refinementSurfaces.C b/src/autoMesh/autoHexMesh/refinementSurfaces/refinementSurfaces.C
index 2566a66e219e0656633fb64787fd5268bd15e468..a626103cd1af105355aee538164e09ed9250a102 100644
--- a/src/autoMesh/autoHexMesh/refinementSurfaces/refinementSurfaces.C
+++ b/src/autoMesh/autoHexMesh/refinementSurfaces/refinementSurfaces.C
@@ -522,8 +522,8 @@ void Foam::refinementSurfaces::setMinLevelFields
                     IOobject
                     (
                         "minLevel",
-                        triMesh.objectRegistry::time().constant(),// directory
-                        "triSurface",               // instance
+                        triMesh.objectRegistry::time().timeName(),  // instance
+                        "triSurface",                               // local
                         triMesh,
                         IOobject::NO_READ,
                         IOobject::AUTO_WRITE
diff --git a/src/finiteVolume/Make/files b/src/finiteVolume/Make/files
index 199daec5544e3c8a1a0d8f66ac34be4fb8144f38..c6a95a976bd247715d2490461c4100bb76f13030 100644
--- a/src/finiteVolume/Make/files
+++ b/src/finiteVolume/Make/files
@@ -93,6 +93,7 @@ $(derivedFvPatchFields)/directMappedFixedValue/directMappedFixedValueFvPatchFiel
 $(derivedFvPatchFields)/directMappedVelocityFluxFixedValue/directMappedVelocityFluxFixedValueFvPatchField.C
 $(derivedFvPatchFields)/fan/fanFvPatchFields.C
 $(derivedFvPatchFields)/fixedFluxBuoyantPressure/fixedFluxBuoyantPressureFvPatchScalarField.C
+$(derivedFvPatchFields)/fixedFluxBoussinesqBuoyantPressure/fixedFluxBoussinesqBuoyantPressureFvPatchScalarField.C
 $(derivedFvPatchFields)/fixedFluxPressure/fixedFluxPressureFvPatchScalarField.C
 $(derivedFvPatchFields)/fixedInternalValueFvPatchField/fixedInternalValueFvPatchFields.C
 $(derivedFvPatchFields)/fixedNormalSlip/fixedNormalSlipFvPatchFields.C
@@ -186,8 +187,15 @@ $(schemes)/harmonic/harmonic.C
 $(schemes)/localBlended/localBlended.C
 $(schemes)/localMax/localMax.C
 $(schemes)/localMin/localMin.C
+
 $(schemes)/linearFit/linearFit.C
+$(schemes)/biLinearFit/biLinearFit.C
 $(schemes)/quadraticLinearFit/quadraticLinearFit.C
+$(schemes)/quadraticFit/quadraticFit.C
+
+$(schemes)/quadraticLinearUpwindFit/quadraticLinearUpwindFit.C
+$(schemes)/quadraticUpwindFit/quadraticUpwindFit.C
+$(schemes)/cubicUpwindFit/cubicUpwindFit.C
 
 limitedSchemes = $(surfaceInterpolation)/limitedSchemes
 $(limitedSchemes)/limitedSurfaceInterpolationScheme/limitedSurfaceInterpolationSchemes.C
diff --git a/src/finiteVolume/fields/fvPatchFields/derived/fixedFluxBoussinesqBuoyantPressure/fixedFluxBoussinesqBuoyantPressureFvPatchScalarField.C b/src/finiteVolume/fields/fvPatchFields/derived/fixedFluxBoussinesqBuoyantPressure/fixedFluxBoussinesqBuoyantPressureFvPatchScalarField.C
new file mode 100644
index 0000000000000000000000000000000000000000..9a75eed1688a05b8c3f308220f2033a7bb6f05d8
--- /dev/null
+++ b/src/finiteVolume/fields/fvPatchFields/derived/fixedFluxBoussinesqBuoyantPressure/fixedFluxBoussinesqBuoyantPressureFvPatchScalarField.C
@@ -0,0 +1,149 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software; you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by the
+    Free Software Foundation; either version 2 of the License, or (at your
+    option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM; if not, write to the Free Software Foundation,
+    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+\*---------------------------------------------------------------------------*/
+
+#include "fixedFluxBoussinesqBuoyantPressureFvPatchScalarField.H"
+#include "addToRunTimeSelectionTable.H"
+#include "fvPatchFieldMapper.H"
+#include "volFields.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+fixedFluxBoussinesqBuoyantPressureFvPatchScalarField::
+fixedFluxBoussinesqBuoyantPressureFvPatchScalarField
+(
+    const fvPatch& p,
+    const DimensionedField<scalar, volMesh>& iF
+)
+:
+    fixedGradientFvPatchScalarField(p, iF)
+{}
+
+
+fixedFluxBoussinesqBuoyantPressureFvPatchScalarField::
+fixedFluxBoussinesqBuoyantPressureFvPatchScalarField
+(
+    const fixedFluxBoussinesqBuoyantPressureFvPatchScalarField& ptf,
+    const fvPatch& p,
+    const DimensionedField<scalar, volMesh>& iF,
+    const fvPatchFieldMapper& mapper
+)
+:
+    fixedGradientFvPatchScalarField(ptf, p, iF, mapper)
+{}
+
+
+fixedFluxBoussinesqBuoyantPressureFvPatchScalarField::
+fixedFluxBoussinesqBuoyantPressureFvPatchScalarField
+(
+    const fvPatch& p,
+    const DimensionedField<scalar, volMesh>& iF,
+    const dictionary&
+)
+:
+    fixedGradientFvPatchScalarField(p, iF)
+{
+    fvPatchField<scalar>::operator=(patchInternalField());
+    gradient() = 0.0;
+}
+
+
+fixedFluxBoussinesqBuoyantPressureFvPatchScalarField::
+fixedFluxBoussinesqBuoyantPressureFvPatchScalarField
+(
+    const fixedFluxBoussinesqBuoyantPressureFvPatchScalarField& wbppsf
+)
+:
+    fixedGradientFvPatchScalarField(wbppsf)
+{}
+
+
+fixedFluxBoussinesqBuoyantPressureFvPatchScalarField::
+fixedFluxBoussinesqBuoyantPressureFvPatchScalarField
+(
+    const fixedFluxBoussinesqBuoyantPressureFvPatchScalarField& wbppsf,
+    const DimensionedField<scalar, volMesh>& iF
+)
+:
+    fixedGradientFvPatchScalarField(wbppsf, iF)
+{}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+void fixedFluxBoussinesqBuoyantPressureFvPatchScalarField::updateCoeffs()
+{
+    if (updated())
+    {
+        return;
+    }
+
+    const dictionary& environmentalProperties
+        = db().lookupObject<IOdictionary>("environmentalProperties");
+
+    dimensionedVector g(environmentalProperties.lookup("g"));
+
+    const dictionary& transportProperties
+        = db().lookupObject<IOdictionary>("transportProperties");
+
+    dimensionedScalar beta(transportProperties.lookup("beta"));
+
+    const fvPatchField<scalar>& T =
+        patch().lookupPatchField<volScalarField, scalar>("T");
+
+    gradient() = beta.value()*T.snGrad()*(g.value() & patch().Cf());
+
+    fixedGradientFvPatchScalarField::updateCoeffs();
+}
+
+
+void fixedFluxBoussinesqBuoyantPressureFvPatchScalarField::write
+(
+    Ostream& os
+) const
+{
+    fixedGradientFvPatchScalarField::write(os);
+    writeEntry("value", os);
+}
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+makePatchTypeField
+(
+    fvPatchScalarField,
+    fixedFluxBoussinesqBuoyantPressureFvPatchScalarField
+);
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// ************************************************************************* //
diff --git a/src/finiteVolume/fields/fvPatchFields/derived/fixedFluxBoussinesqBuoyantPressure/fixedFluxBoussinesqBuoyantPressureFvPatchScalarField.H b/src/finiteVolume/fields/fvPatchFields/derived/fixedFluxBoussinesqBuoyantPressure/fixedFluxBoussinesqBuoyantPressureFvPatchScalarField.H
new file mode 100644
index 0000000000000000000000000000000000000000..094f8805606650a1f2b087d1404dcad78fd1c680
--- /dev/null
+++ b/src/finiteVolume/fields/fvPatchFields/derived/fixedFluxBoussinesqBuoyantPressure/fixedFluxBoussinesqBuoyantPressureFvPatchScalarField.H
@@ -0,0 +1,148 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software; you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by the
+    Free Software Foundation; either version 2 of the License, or (at your
+    option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM; if not, write to the Free Software Foundation,
+    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+Class
+    Foam::fixedFluxBoussinesqBuoyantPressureFvPatchScalarField
+
+Description
+    Boundary condition on pressure for use with buoyant solvers employing the
+    Boussinesq approximation to balance the flux generated by the temperature
+    gradient.
+
+SourceFiles
+    fixedFluxBoussinesqBuoyantPressureFvPatchScalarField.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef fixedFluxBoussinesqBuoyantPressureFvPatchScalarFields_H
+#define fixedFluxBoussinesqBuoyantPressureFvPatchScalarFields_H
+
+#include "fvPatchFields.H"
+#include "fixedGradientFvPatchFields.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+    Class fixedFluxBoussinesqBuoyantPressureFvPatchScalarField Declaration
+\*---------------------------------------------------------------------------*/
+
+class fixedFluxBoussinesqBuoyantPressureFvPatchScalarField
+:
+    public fixedGradientFvPatchScalarField
+{
+public:
+
+    //- Runtime type information
+    TypeName("fixedFluxBoussinesqBuoyantPressure");
+
+
+    // Constructors
+
+        //- Construct from patch and internal field
+        fixedFluxBoussinesqBuoyantPressureFvPatchScalarField
+        (
+            const fvPatch&,
+            const DimensionedField<scalar, volMesh>&
+        );
+
+        //- Construct from patch, internal field and dictionary
+        fixedFluxBoussinesqBuoyantPressureFvPatchScalarField
+        (
+            const fvPatch&,
+            const DimensionedField<scalar, volMesh>&,
+            const dictionary&
+        );
+
+        //- Construct by mapping given
+        //  fixedFluxBoussinesqBuoyantPressureFvPatchScalarField onto a new
+        //  patch
+        fixedFluxBoussinesqBuoyantPressureFvPatchScalarField
+        (
+            const fixedFluxBoussinesqBuoyantPressureFvPatchScalarField&,
+            const fvPatch&,
+            const DimensionedField<scalar, volMesh>&,
+            const fvPatchFieldMapper&
+        );
+
+        //- Construct as copy
+        fixedFluxBoussinesqBuoyantPressureFvPatchScalarField
+        (
+            const fixedFluxBoussinesqBuoyantPressureFvPatchScalarField&
+        );
+
+        //- Construct and return a clone
+        virtual tmp<fvPatchScalarField> clone() const
+        {
+            return tmp<fvPatchScalarField>
+            (
+                new fixedFluxBoussinesqBuoyantPressureFvPatchScalarField(*this)
+            );
+        }
+
+        //- Construct as copy setting internal field reference
+        fixedFluxBoussinesqBuoyantPressureFvPatchScalarField
+        (
+            const fixedFluxBoussinesqBuoyantPressureFvPatchScalarField&,
+            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 fixedFluxBoussinesqBuoyantPressureFvPatchScalarField
+                (
+                    *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/fvMesh/extendedStencil/extendedUpwindStencilTemplates.C b/src/finiteVolume/fvMesh/extendedStencil/extendedUpwindStencilTemplates.C
index 00cd58e17d793060bc99dd7149c0e1f84c2ceffe..5c183290444f066854caad7321f1463c246bcc36 100644
--- a/src/finiteVolume/fvMesh/extendedStencil/extendedUpwindStencilTemplates.C
+++ b/src/finiteVolume/fvMesh/extendedStencil/extendedUpwindStencilTemplates.C
@@ -108,7 +108,7 @@ Foam::extendedUpwindStencil::weightedSum
 
             forAll(pSfCorr, i)
             {
-                if (phi[faceI] > 0)
+                if (phi.boundaryField()[patchi][i] > 0)
                 {
                     // Flux out of owner. Use upwind (= owner side) stencil.
                     const List<Type>& stField = ownFld[faceI];
diff --git a/src/finiteVolume/interpolation/surfaceInterpolation/schemes/CentredFitScheme/CentredFitData.C b/src/finiteVolume/interpolation/surfaceInterpolation/schemes/CentredFitScheme/CentredFitData.C
index dea1b41143792cd55dc44e47ae0455d04eed511c..7f684998447f9c13a80e14aaab139a9f4b7e299d 100644
--- a/src/finiteVolume/interpolation/surfaceInterpolation/schemes/CentredFitScheme/CentredFitData.C
+++ b/src/finiteVolume/interpolation/surfaceInterpolation/schemes/CentredFitScheme/CentredFitData.C
@@ -42,16 +42,10 @@ Foam::CentredFitData<Polynomial>::CentredFitData
     const scalar centralWeight
 )
 :
-    MeshObject<fvMesh, CentredFitData<Polynomial> >(mesh),
-    stencil_(stencil),
-    linearLimitFactor_(linearLimitFactor),
-    centralWeight_(centralWeight),
-#   ifdef SPHERICAL_GEOMETRY
-    dim_(2),
-#   else
-    dim_(mesh.nGeometricD()),
-#   endif
-    minSize_(Polynomial::nTerms(dim_)),
+    FitData<CentredFitData<Polynomial>, extendedCentredStencil, Polynomial>
+    (
+        mesh, stencil, linearLimitFactor, centralWeight
+    ),
     coeffs_(mesh.nFaces())
 {
     if (debug)
@@ -59,15 +53,6 @@ Foam::CentredFitData<Polynomial>::CentredFitData
         Info<< "Contructing CentredFitData<Polynomial>" << endl;
     }
 
-    // Check input
-    if (linearLimitFactor > 1)
-    {
-        FatalErrorIn("CentredFitData<Polynomial>::CentredFitData")
-            << "linearLimitFactor requested = " << linearLimitFactor
-            << " should not be less than one"
-            << exit(FatalError);
-    }
-
     calcFit();
 
     if (debug)
@@ -81,85 +66,25 @@ Foam::CentredFitData<Polynomial>::CentredFitData
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
-template<class Polynomial>
-void Foam::CentredFitData<Polynomial>::findFaceDirs
-(
-    vector& idir,        // value changed in return
-    vector& jdir,        // value changed in return
-    vector& kdir,        // value changed in return
-    const fvMesh& mesh,
-    const label facei
-)
-{
-    idir = mesh.faceAreas()[facei];
-    idir /= mag(idir);
-
-#   ifndef SPHERICAL_GEOMETRY
-    if (mesh.nGeometricD() <= 2) // find the normal direction
-    {
-        if (mesh.directions()[0] == -1)
-        {
-            kdir = vector(1, 0, 0);
-        }
-        else if (mesh.directions()[1] == -1)
-        {
-            kdir = vector(0, 1, 0);
-        }
-        else
-        {
-            kdir = vector(0, 0, 1);
-        }
-    }
-    else // 3D so find a direction in the plane of the face
-    {
-        const face& f = mesh.faces()[facei];
-        kdir = mesh.points()[f[0]] - mesh.faceCentres()[facei];
-    }
-#   else
-    // Spherical geometry so kdir is the radial direction
-    kdir = mesh.faceCentres()[facei];
-#   endif
-
-    if (mesh.nGeometricD() == 3)
-    {
-        // Remove the idir component from kdir and normalise
-        kdir -= (idir & kdir)*idir;
-
-        scalar magk = mag(kdir);
-
-        if (magk < SMALL)
-        {
-            FatalErrorIn("findFaceDirs") << " calculated kdir = zero"
-                << exit(FatalError);
-        }
-        else
-        {
-            kdir /= magk;
-        }
-    }
-
-    jdir = kdir ^ idir;
-}
-
-
 template<class Polynomial>
 void Foam::CentredFitData<Polynomial>::calcFit()
 {
     const fvMesh& mesh = this->mesh();
 
     // Get the cell/face centres in stencil order.
-    // Centred face stencils no good for triangles of tets.
+    // Centred face stencils no good for triangles or tets.
     // Need bigger stencils
     List<List<point> > stencilPoints(mesh.nFaces());
-    stencil_.collectData(mesh.C(), stencilPoints);
+    this->stencil().collectData(mesh.C(), stencilPoints);
 
     // find the fit coefficients for every face in the mesh
 
-    const surfaceScalarField& w = this->mesh().surfaceInterpolation::weights();
+    const surfaceScalarField& w = mesh.surfaceInterpolation::weights();
 
     for(label facei = 0; facei < mesh.nInternalFaces(); facei++)
     {
-        calcFit(stencilPoints[facei], w[facei], facei);
+        FitData<CentredFitData<Polynomial>, extendedCentredStencil, Polynomial>::
+                   calcFit(coeffs_[facei], stencilPoints[facei], w[facei], facei);
     }
 
     const surfaceScalarField::GeometricBoundaryField& bw = w.boundaryField();
@@ -174,7 +99,10 @@ void Foam::CentredFitData<Polynomial>::calcFit()
 
             forAll(pw, i)
             {
-                calcFit(stencilPoints[facei], pw[i], facei);
+                FitData
+                <
+                    CentredFitData<Polynomial>, extendedCentredStencil, Polynomial
+                >::calcFit(coeffs_[facei], stencilPoints[facei], pw[i], facei);
                 facei++;
             }
         }
@@ -182,179 +110,4 @@ void Foam::CentredFitData<Polynomial>::calcFit()
 }
 
 
-template<class Polynomial>
-Foam::label Foam::CentredFitData<Polynomial>::calcFit
-(
-    const List<point>& C,
-    const scalar wLin,
-    const label facei
-)
-{
-    vector idir(1,0,0);
-    vector jdir(0,1,0);
-    vector kdir(0,0,1);
-    findFaceDirs(idir, jdir, kdir, this->mesh(), facei);
-
-    // Setup the point weights
-    scalarList wts(C.size(), scalar(1));
-    wts[0] = centralWeight_;
-    wts[1] = centralWeight_;
-
-    // Reference point
-    point p0 = this->mesh().faceCentres()[facei];
-
-    // p0 -> p vector in the face-local coordinate system
-    vector d;
-
-    // Local coordinate scaling
-    scalar scale = 1;
-
-    // Matrix of the polynomial components
-    scalarRectangularMatrix B(C.size(), minSize_, scalar(0));
-
-    for(label ip = 0; ip < C.size(); ip++)
-    {
-        const point& p = C[ip];
-
-        d.x() = (p - p0)&idir;
-        d.y() = (p - p0)&jdir;
-#       ifndef SPHERICAL_GEOMETRY
-        d.z() = (p - p0)&kdir;
-#       else
-        d.z() = mag(p) - mag(p0);
-#       endif
-
-        if (ip == 0)
-        {
-            scale = cmptMax(cmptMag((d)));
-        }
-
-        // Scale the radius vector
-        d /= scale;
-
-        Polynomial::addCoeffs
-        (
-            B[ip],
-            d,
-            wts[ip],
-            dim_
-        );
-    }
-
-    // Set the fit
-    label stencilSize = C.size();
-    coeffs_[facei].setSize(stencilSize);
-    scalarList singVals(minSize_);
-    label nSVDzeros = 0;
-
-    bool goodFit = false;
-    for(int iIt = 0; iIt < 10 && !goodFit; iIt++)
-    {
-        SVD svd(B, SMALL);
-
-        scalar fit0 = wts[0]*svd.VSinvUt()[0][0];
-        scalar fit1 = wts[1]*svd.VSinvUt()[0][1];
-
-        goodFit =
-            (mag(fit0 - wLin) < linearLimitFactor_*wLin)
-         && (mag(fit1 - (1 - wLin)) < linearLimitFactor_*(1 - wLin));
-
-        //scalar w0Err = fit0/wLin;
-        //scalar w1Err = fit1/(1 - wLin);
-
-        //goodFit =
-        //    (w0Err > linearLimitFactor_ && w0Err < (1 + linearLimitFactor_))
-        // && (w1Err > linearLimitFactor_ && w1Err < (1 + linearLimitFactor_));
-
-        if (goodFit)
-        {
-            coeffs_[facei][0] = fit0;
-            coeffs_[facei][1] = fit1;
-
-            for(label i=2; i<stencilSize; i++)
-            {
-                coeffs_[facei][i] = wts[i]*svd.VSinvUt()[0][i];
-            }
-
-            singVals = svd.S();
-            nSVDzeros = svd.nZeros();
-        }
-        else // (not good fit so increase weight in the centre and for linear)
-        {
-            wts[0] *= 10;
-            wts[1] *= 10;
-
-            for(label j = 0; j < B.m(); j++)
-            {
-                B[0][j] *= 10;
-                B[1][j] *= 10;
-            }
-        }
-    }
-
-    // static const scalar L = 0.1;
-    // static const scalar R = 0.2;
-
-    // static const scalar beta = 1.0/(R - L);
-    // static const scalar alpha = R*beta;
-
-    if (goodFit)
-    {
-        // scalar limiter =
-        // max
-        // (
-        //     min
-        //     (
-        //         min(alpha - beta*mag(coeffs_[facei][0] - wLin)/wLin, 1),
-        //         min(alpha - beta*mag(coeffs_[facei][1] - (1 - wLin))
-        //       /(1 - wLin), 1)
-        //     ), 0
-        // );
-
-        //Info<< wLin << " " << coeffs_[facei][0]
-        //    << " " << (1 - wLin) << " " << coeffs_[facei][1] << endl;
-
-        // Remove the uncorrected linear ocefficients
-        coeffs_[facei][0] -= wLin;
-        coeffs_[facei][1] -= 1 - wLin;
-
-        // if (limiter < 0.99)
-        // {
-        //     for(label i = 0; i < stencilSize; i++)
-        //     {
-        //         coeffs_[facei][i] *= limiter;
-        //     }
-        // }
-    }
-    else
-    {
-        if (debug)
-        {
-            WarningIn
-            (
-                "CentredFitData<Polynomial>::calcFit"
-                "(const List<point>& C, const label facei"
-            )   << "Could not fit face " << facei
-                << ", reverting to linear." << nl
-                << "    Weights "
-                << coeffs_[facei][0] << " " << wLin << nl
-                << "    Linear weights "
-                << coeffs_[facei][1] << " " << 1 - wLin << endl;
-        }
-
-        coeffs_[facei] = 0;
-    }
-
-    return minSize_ - nSVDzeros;
-}
-
-
-template<class Polynomial>
-bool Foam::CentredFitData<Polynomial>::movePoints()
-{
-    calcFit();
-    return true;
-}
-
-
 // ************************************************************************* //
diff --git a/src/finiteVolume/interpolation/surfaceInterpolation/schemes/CentredFitScheme/CentredFitData.H b/src/finiteVolume/interpolation/surfaceInterpolation/schemes/CentredFitScheme/CentredFitData.H
index 1630e06a927419c0747d33988a7d48ab48ec8483..cb01840260d25a5ef1781b890edd0650e24d0a87 100644
--- a/src/finiteVolume/interpolation/surfaceInterpolation/schemes/CentredFitScheme/CentredFitData.H
+++ b/src/finiteVolume/interpolation/surfaceInterpolation/schemes/CentredFitScheme/CentredFitData.H
@@ -36,8 +36,7 @@ SourceFiles
 #ifndef CentredFitData_H
 #define CentredFitData_H
 
-#include "MeshObject.H"
-#include "fvMesh.H"
+#include "FitData.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -53,27 +52,10 @@ class extendedCentredStencil;
 template<class Polynomial>
 class CentredFitData
 :
-    public MeshObject<fvMesh, CentredFitData<Polynomial> >
+    public FitData<CentredFitData<Polynomial>, extendedCentredStencil, Polynomial>
 {
     // Private data
 
-        //- The stencil the fit is based on
-        const extendedCentredStencil& stencil_;
-
-        //- Factor the fit is allowed to deviate from linear.
-        //  This limits the amount of high-order correction and increases
-        //  stability on bad meshes
-        const scalar linearLimitFactor_;
-
-        //- Weights for central stencil
-        const scalar centralWeight_;
-
-        //- Dimensionality of the geometry
-        const label dim_;
-
-        //- Minimum stencil size
-        const label minSize_;
-
         //- For each cell in the mesh store the values which multiply the
         //  values of the stencil to obtain the gradient for each direction
         List<scalarList> coeffs_;
@@ -81,28 +63,10 @@ class CentredFitData
 
     // Private member functions
 
-        //- Find the normal direction and i, j and k directions for face faci
-        static void findFaceDirs
-        (
-            vector& idir,        // value changed in return
-            vector& jdir,        // value changed in return
-            vector& kdir,        // value changed in return
-            const fvMesh& mesh,
-            const label faci
-        );
-
         //- Calculate the fit for the all the mesh faces
         //  and set the coefficients
         void calcFit();
 
-        //- Calculate the fit for the specified face and set the coefficients
-        label calcFit
-        (
-            const List<point>&,  // Stencil points
-            const scalar wLin,   // Linear weight
-            const label faci     // Current face index
-        );
-
 
 public:
 
@@ -133,9 +97,6 @@ public:
         {
             return coeffs_;
         }
-
-        //- Delete the data when the mesh moves not implemented
-        virtual bool movePoints();
 };
 
 
diff --git a/src/finiteVolume/interpolation/surfaceInterpolation/schemes/FitData/FitData.C b/src/finiteVolume/interpolation/surfaceInterpolation/schemes/FitData/FitData.C
new file mode 100644
index 0000000000000000000000000000000000000000..0872cb81a9c3cdc33fd43e20353b745a37d17590
--- /dev/null
+++ b/src/finiteVolume/interpolation/surfaceInterpolation/schemes/FitData/FitData.C
@@ -0,0 +1,287 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 1991-2007 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software; you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by the
+    Free Software Foundation; either version 2 of the License, or (at your
+    option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM; if not, write to the Free Software Foundation,
+    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+\*---------------------------------------------------------------------------*/
+
+#include "FitData.H"
+#include "surfaceFields.H"
+#include "volFields.H"
+#include "SVD.H"
+#include "syncTools.H"
+#include "extendedStencil.H"
+
+// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
+
+template<class Form, class extendedStencil, class Polynomial>
+Foam::FitData<Form, extendedStencil, Polynomial>::FitData
+(
+    const fvMesh& mesh,
+    const extendedStencil& stencil,
+    const scalar linearLimitFactor,
+    const scalar centralWeight
+)
+:
+    MeshObject<fvMesh, Form>(mesh),
+    stencil_(stencil),
+    linearLimitFactor_(linearLimitFactor),
+    centralWeight_(centralWeight),
+#   ifdef SPHERICAL_GEOMETRY
+    dim_(2),
+#   else
+    dim_(mesh.nGeometricD()),
+#   endif
+    minSize_(Polynomial::nTerms(dim_))
+{
+    // Check input
+    if (linearLimitFactor <= SMALL || linearLimitFactor > 3)
+    {
+        FatalErrorIn("FitData<Polynomial>::FitData")
+            << "linearLimitFactor requested = " << linearLimitFactor
+            << " should be between zero and 3"
+            << exit(FatalError);
+    }
+}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+template<class FitDataType, class ExtendedStencil, class Polynomial>
+void Foam::FitData<FitDataType, ExtendedStencil, Polynomial>::findFaceDirs
+(
+    vector& idir,        // value changed in return
+    vector& jdir,        // value changed in return
+    vector& kdir,        // value changed in return
+    const label facei
+)
+{
+    const fvMesh& mesh = this->mesh();
+
+    idir = mesh.faceAreas()[facei];
+    idir /= mag(idir);
+
+#   ifndef SPHERICAL_GEOMETRY
+    if (mesh.nGeometricD() <= 2) // find the normal direction
+    {
+        if (mesh.directions()[0] == -1)
+        {
+            kdir = vector(1, 0, 0);
+        }
+        else if (mesh.directions()[1] == -1)
+        {
+            kdir = vector(0, 1, 0);
+        }
+        else
+        {
+            kdir = vector(0, 0, 1);
+        }
+    }
+    else // 3D so find a direction in the plane of the face
+    {
+        const face& f = mesh.faces()[facei];
+        kdir = mesh.points()[f[0]] - mesh.faceCentres()[facei];
+    }
+#   else
+    // Spherical geometry so kdir is the radial direction
+    kdir = mesh.faceCentres()[facei];
+#   endif
+
+    if (mesh.nGeometricD() == 3)
+    {
+        // Remove the idir component from kdir and normalise
+        kdir -= (idir & kdir)*idir;
+
+        scalar magk = mag(kdir);
+
+        if (magk < SMALL)
+        {
+            FatalErrorIn("findFaceDirs") << " calculated kdir = zero"
+                << exit(FatalError);
+        }
+        else
+        {
+            kdir /= magk;
+        }
+    }
+
+    jdir = kdir ^ idir;
+}
+
+
+template<class FitDataType, class ExtendedStencil, class Polynomial>
+void Foam::FitData<FitDataType, ExtendedStencil, Polynomial>::calcFit
+(
+    scalarList& coeffsi,
+    const List<point>& C,
+    const scalar wLin,
+    const label facei
+)
+{
+    vector idir(1,0,0);
+    vector jdir(0,1,0);
+    vector kdir(0,0,1);
+    findFaceDirs(idir, jdir, kdir, facei);
+
+    // Setup the point weights
+    scalarList wts(C.size(), scalar(1));
+    wts[0] = centralWeight_;
+    wts[1] = centralWeight_;
+
+    // Reference point
+    point p0 = this->mesh().faceCentres()[facei];
+
+    // Info << "Face " << facei << " at " << p0 << " stencil points at:\n"
+    //     << C - p0 << endl;
+
+    // p0 -> p vector in the face-local coordinate system
+    vector d;
+
+    // Local coordinate scaling
+    scalar scale = 1;
+
+    // Matrix of the polynomial components
+    scalarRectangularMatrix B(C.size(), minSize_, scalar(0));
+
+    for(label ip = 0; ip < C.size(); ip++)
+    {
+        const point& p = C[ip];
+
+        d.x() = (p - p0)&idir;
+        d.y() = (p - p0)&jdir;
+#       ifndef SPHERICAL_GEOMETRY
+        d.z() = (p - p0)&kdir;
+#       else
+        d.z() = mag(p) - mag(p0);
+#       endif
+
+        if (ip == 0)
+        {
+            scale = cmptMax(cmptMag((d)));
+        }
+
+        // Scale the radius vector
+        d /= scale;
+
+        Polynomial::addCoeffs
+        (
+            B[ip],
+            d,
+            wts[ip],
+            dim_
+        );
+    }
+
+    // Set the fit
+    label stencilSize = C.size();
+    coeffsi.setSize(stencilSize);
+
+    bool goodFit = false;
+    for(int iIt = 0; iIt < 8 && !goodFit; iIt++)
+    {
+        SVD svd(B, SMALL);
+
+        scalar maxCoeff = 0;
+        label maxCoeffi = 0;
+
+        for(label i=0; i<stencilSize; i++)
+        {
+            coeffsi[i] = wts[i]*svd.VSinvUt()[0][i];
+            if (mag(coeffsi[i]) > maxCoeff)
+            {
+                maxCoeff = mag(coeffsi[i]);
+                maxCoeffi = i;
+            }
+        }
+
+        goodFit =
+            (mag(coeffsi[0] - wLin) < linearLimitFactor_*wLin)
+         && (mag(coeffsi[1] - (1 - wLin)) < linearLimitFactor_*(1 - wLin))
+         && maxCoeffi <= 1;
+
+        // if (goodFit && iIt > 0)
+        // {
+            // Info << "FitData<Polynomial>::calcFit"
+            //     << "(const List<point>& C, const label facei" << nl
+            //     << "Can now fit face " << facei << " iteration " << iIt
+            //     << " with sum of weights " << sum(coeffsi) << nl
+            //     << "    Weights " << coeffsi << nl
+            //     << "    Linear weights " << wLin << " " << 1 - wLin << nl
+            //     << "    sing vals " << svd.S() << endl;
+        // }
+
+        if (!goodFit) // (not good fit so increase weight in the centre)
+        {
+            // if (iIt == 7)
+            // {
+            //     WarningIn
+            //     (
+            //         "FitData<Polynomial>::calcFit"
+            //         "(const List<point>& C, const label facei"
+            //     )   << "Cannot fit face " << facei
+            //         << "    sing vals " << svd.S() << endl;
+            // }
+
+            wts[0] *= 10;
+            wts[1] *= 10;
+
+            for(label j = 0; j < B.m(); j++)
+            {
+                B[0][j] *= 10;
+                B[1][j] *= 10;
+            }
+        }
+    }
+
+    if (goodFit)
+    {
+        // Remove the uncorrected linear ocefficients
+        coeffsi[0] -= wLin;
+        coeffsi[1] -= 1 - wLin;
+    }
+    else
+    {
+        // if (debug)
+        // {
+            WarningIn
+            (
+                "FitData<Polynomial>::calcFit"
+                "(const List<point>& C, const label facei"
+            )   << "Could not fit face " << facei
+                << "    Weights = " << coeffsi
+                << ", reverting to linear." << nl
+                << "    Linear weights " << wLin << " " << 1 - wLin << endl;
+        // }
+
+        coeffsi = 0;
+    }
+}
+
+
+template<class FitDataType, class ExtendedStencil, class Polynomial>
+bool Foam::FitData<FitDataType, ExtendedStencil, Polynomial>::movePoints()
+{
+    calcFit();
+    return true;
+}
+
+// ************************************************************************* //
diff --git a/src/finiteVolume/interpolation/surfaceInterpolation/schemes/FitData/FitData.H b/src/finiteVolume/interpolation/surfaceInterpolation/schemes/FitData/FitData.H
new file mode 100644
index 0000000000000000000000000000000000000000..810c8d7e4c388b73121b430cf27aca803859f734
--- /dev/null
+++ b/src/finiteVolume/interpolation/surfaceInterpolation/schemes/FitData/FitData.H
@@ -0,0 +1,154 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 1991-2007 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software; you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by the
+    Free Software Foundation; either version 2 of the License, or (at your
+    option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM; if not, write to the Free Software Foundation,
+    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+Class
+    Foam::FitData
+
+Description
+    Data for the upwinded and centred polynomial fit interpolation schemes
+
+SourceFiles
+    FitData.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef FitData_H
+#define FitData_H
+
+#include "MeshObject.H"
+#include "fvMesh.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+                    Class FitData Declaration
+\*---------------------------------------------------------------------------*/
+
+template<class FitDataType, class ExtendedStencil, class Polynomial>
+class FitData
+:
+    public MeshObject<fvMesh, FitDataType>
+{
+    // Private data
+
+        //- The stencil the fit is based on
+        const ExtendedStencil& stencil_;
+
+        //- Factor the fit is allowed to deviate from linear.
+        //  This limits the amount of high-order correction and increases
+        //  stability on bad meshes
+        const scalar linearLimitFactor_;
+
+        //- Weights for central stencil
+        const scalar centralWeight_;
+
+        //- Dimensionality of the geometry
+        const label dim_;
+
+        //- Minimum stencil size
+        const label minSize_;
+
+
+    // Private member functions
+
+        //- Find the normal direction (i) and j and k directions for face faci
+        void findFaceDirs
+        (
+            vector& idir,        // value changed in return
+            vector& jdir,        // value changed in return
+            vector& kdir,        // value changed in return
+            const label faci
+        );
+
+        //- Calculate the fit for the all the mesh faces
+        //  and set the coefficients
+        // virtual void calcFit();
+
+
+public:
+
+    //TypeName("FitData");
+
+
+    // Constructors
+
+        //- Construct from components
+        FitData
+        (
+            const fvMesh& mesh,
+            const ExtendedStencil& stencil,
+            const scalar linearLimitFactor,
+            const scalar centralWeight
+        );
+
+
+    //- Destructor
+    virtual ~FitData()
+    {}
+
+
+    // Member functions
+
+        //- Return reference to the stencil
+        const ExtendedStencil& stencil() const
+        {
+            return stencil_;
+        }
+
+        //- Calculate the fit for the specified face and set the coefficients
+        void calcFit
+        (
+            scalarList& coeffsi, // coefficients to be set
+            const List<point>&,  // Stencil points
+            const scalar wLin,   // Linear weight
+            const label faci     // Current face index
+        );
+
+        //- Calculate the fit for all the faces
+        virtual void calcFit() = 0;
+
+
+        //- Delete the data when the mesh moves not implemented
+        bool movePoints();
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#ifdef NoRepository
+#   include "FitData.C"
+#endif
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/finiteVolume/interpolation/surfaceInterpolation/schemes/UpwindFitScheme/UpwindFitData.C b/src/finiteVolume/interpolation/surfaceInterpolation/schemes/UpwindFitScheme/UpwindFitData.C
new file mode 100644
index 0000000000000000000000000000000000000000..fd218100ccedcf953cc03760901540df035ae0ae
--- /dev/null
+++ b/src/finiteVolume/interpolation/surfaceInterpolation/schemes/UpwindFitScheme/UpwindFitData.C
@@ -0,0 +1,140 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 1991-2007 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software; you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by the
+    Free Software Foundation; either version 2 of the License, or (at your
+    option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM; if not, write to the Free Software Foundation,
+    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+\*---------------------------------------------------------------------------*/
+
+#include "UpwindFitData.H"
+#include "surfaceFields.H"
+#include "volFields.H"
+#include "SVD.H"
+#include "syncTools.H"
+#include "extendedUpwindStencil.H"
+
+// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
+
+template<class Polynomial>
+Foam::UpwindFitData<Polynomial>::UpwindFitData
+(
+    const fvMesh& mesh,
+    const extendedUpwindStencil& stencil,
+    const scalar linearLimitFactor,
+    const scalar centralWeight
+)
+:
+    FitData<UpwindFitData<Polynomial>, extendedUpwindStencil, Polynomial>
+    (
+        mesh, stencil, linearLimitFactor, centralWeight
+    ),
+    owncoeffs_(mesh.nFaces()),
+    neicoeffs_(mesh.nFaces())
+{
+    if (debug)
+    {
+        Info<< "Contructing UpwindFitData<Polynomial>" << endl;
+    }
+
+    calcFit();
+
+    if (debug)
+    {
+        Info<< "UpwindFitData<Polynomial>::UpwindFitData() :"
+            << "Finished constructing polynomialFit data"
+            << endl;
+    }
+}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+template<class Polynomial>
+void Foam::UpwindFitData<Polynomial>::calcFit()
+{
+    const fvMesh& mesh = this->mesh();
+
+    // Get the cell/face centres in stencil order.
+    // Upwind face stencils no good for triangles or tets.
+    // Need bigger stencils
+    List<List<point> > ownStencilPoints(mesh.nFaces());
+    this->stencil().collectData
+    (
+        this->stencil().ownMap(),
+        this->stencil().ownStencil(),
+        mesh.C(),
+        ownStencilPoints
+    );
+    List<List<point> > neiStencilPoints(mesh.nFaces());
+    this->stencil().collectData
+    (
+        this->stencil().neiMap(),
+        this->stencil().neiStencil(),
+        mesh.C(),
+        neiStencilPoints
+    );
+
+    // find the fit coefficients for every owner and neighbour of ever face
+
+    const surfaceScalarField& w = mesh.surfaceInterpolation::weights();
+
+    for(label facei = 0; facei < mesh.nInternalFaces(); facei++)
+    {
+        FitData<UpwindFitData<Polynomial>, extendedUpwindStencil, Polynomial>::
+           calcFit(owncoeffs_[facei], ownStencilPoints[facei], w[facei], facei);
+        FitData<UpwindFitData<Polynomial>, extendedUpwindStencil, Polynomial>::
+           calcFit(neicoeffs_[facei], neiStencilPoints[facei], w[facei], facei);
+    }
+
+    const surfaceScalarField::GeometricBoundaryField& bw = w.boundaryField();
+
+    forAll(bw, patchi)
+    {
+        const fvsPatchScalarField& pw = bw[patchi];
+
+        if (pw.coupled())
+        {
+            label facei = pw.patch().patch().start();
+
+            forAll(pw, i)
+            {
+                FitData
+                <
+                    UpwindFitData<Polynomial>, extendedUpwindStencil, Polynomial
+                >::calcFit
+                (
+                    owncoeffs_[facei], ownStencilPoints[facei], pw[i], facei
+                );
+                FitData
+                <
+                    UpwindFitData<Polynomial>, extendedUpwindStencil, Polynomial
+                >::calcFit
+                (
+                    neicoeffs_[facei], neiStencilPoints[facei], pw[i], facei
+                );
+                facei++;
+            }
+        }
+    }
+}
+
+
+// ************************************************************************* //
diff --git a/src/finiteVolume/interpolation/surfaceInterpolation/schemes/UpwindFitScheme/UpwindFitData.H b/src/finiteVolume/interpolation/surfaceInterpolation/schemes/UpwindFitScheme/UpwindFitData.H
new file mode 100644
index 0000000000000000000000000000000000000000..7f01135b9e664fd9c5ef07604b9e1fe6696fb96b
--- /dev/null
+++ b/src/finiteVolume/interpolation/surfaceInterpolation/schemes/UpwindFitScheme/UpwindFitData.H
@@ -0,0 +1,128 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 1991-2007 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software; you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by the
+    Free Software Foundation; either version 2 of the License, or (at your
+    option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM; if not, write to the Free Software Foundation,
+    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+Class
+    Foam::UpwindFitData
+
+Description
+    Data for the quadratic fit correction interpolation scheme to be used with
+    upwind biased stencil
+
+SourceFiles
+    UpwindFitData.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef UpwindFitData_H
+#define UpwindFitData_H
+
+#include "FitData.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+class extendedUpwindStencil;
+
+/*---------------------------------------------------------------------------*\
+                    Class UpwindFitData Declaration
+\*---------------------------------------------------------------------------*/
+
+template<class Polynomial>
+class UpwindFitData
+:
+    public FitData<UpwindFitData<Polynomial>, extendedUpwindStencil, Polynomial>
+{
+    // Private data
+
+        //- For each face of the mesh store the coefficients to multiply the
+        // stencil cell values by if the flow is from the owner
+        List<scalarList> owncoeffs_;
+
+        //- For each face of the mesh store the coefficients to multiply the
+        // stencil cell values by if the flow is from the neighbour
+        List<scalarList> neicoeffs_;
+
+
+    // Private member functions
+
+        //- Calculate the fit for the all the mesh faces
+        //  and set the coefficients
+        void calcFit();
+
+
+public:
+
+    TypeName("UpwindFitData");
+
+
+    // Constructors
+
+        //- Construct from components
+        UpwindFitData
+        (
+            const fvMesh& mesh,
+            const extendedUpwindStencil& stencil,
+            const scalar linearLimitFactor,
+            const scalar centralWeight
+        );
+
+
+    //- Destructor
+    virtual ~UpwindFitData()
+    {}
+
+
+    // Member functions
+
+        //- Return reference to owner fit coefficients
+        const List<scalarList>& owncoeffs() const
+        {
+            return owncoeffs_;
+        }
+
+        //- Return reference to neighbour fit coefficients
+        const List<scalarList>& neicoeffs() const
+        {
+            return neicoeffs_;
+        }
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#ifdef NoRepository
+#   include "UpwindFitData.C"
+#endif
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/finiteVolume/interpolation/surfaceInterpolation/schemes/UpwindFitScheme/UpwindFitScheme.H b/src/finiteVolume/interpolation/surfaceInterpolation/schemes/UpwindFitScheme/UpwindFitScheme.H
new file mode 100644
index 0000000000000000000000000000000000000000..0921dcfea960692a9b8f510a267968ac28501c99
--- /dev/null
+++ b/src/finiteVolume/interpolation/surfaceInterpolation/schemes/UpwindFitScheme/UpwindFitScheme.H
@@ -0,0 +1,188 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 1991-2007 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software; you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by the
+    Free Software Foundation; either version 2 of the License, or (at your
+    option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM; if not, write to the Free Software Foundation,
+    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+Class
+    Foam::UpwindFitScheme
+
+Description
+    Upwind biased fit surface interpolation scheme which applies an explicit
+    correction to linear.
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef UpwindFitScheme_H
+#define UpwindFitScheme_H
+
+#include "UpwindFitData.H"
+#include "linear.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+                           Class UpwindFitScheme Declaration
+\*---------------------------------------------------------------------------*/
+
+template<class Type, class Polynomial, class Stencil>
+class UpwindFitScheme
+:
+    public linear<Type>
+{
+    // Private Data
+
+        //- Reference to the surface flux used to choose upwind direction
+        const surfaceScalarField& faceFlux_;
+
+        //- Factor the fit is allowed to deviate from linear.
+        //  This limits the amount of high-order correction and increases
+        //  stability on bad meshes
+        const scalar linearLimitFactor_;
+
+        //- Weights for central stencil
+        const scalar centralWeight_;
+
+
+    // Private Member Functions
+
+        //- Disallow default bitwise copy construct
+        UpwindFitScheme(const UpwindFitScheme&);
+
+        //- Disallow default bitwise assignment
+        void operator=(const UpwindFitScheme&);
+
+
+public:
+
+    //- Runtime type information
+    TypeName("UpwindFitScheme");
+
+
+    // Constructors
+
+        //- Construct from mesh and Istream
+        //  The name of the flux field is read from the Istream and looked-up
+        //  from the mesh objectRegistry
+        UpwindFitScheme(const fvMesh& mesh, Istream& is)
+        :
+            linear<Type>(mesh),
+            faceFlux_(mesh.lookupObject<surfaceScalarField>(word(is))),
+            linearLimitFactor_(readScalar(is)),
+            centralWeight_(1000)
+        {}
+
+
+        //- Construct from mesh, faceFlux and Istream
+        UpwindFitScheme
+        (
+            const fvMesh& mesh,
+            const surfaceScalarField& faceFlux,
+            Istream& is
+        )
+        :
+            linear<Type>(mesh),
+            faceFlux_(faceFlux),
+            linearLimitFactor_(readScalar(is)),
+            centralWeight_(1000)
+        {}
+
+
+    // Member Functions
+
+        //- Return true if this scheme uses an explicit correction
+        virtual bool corrected() const
+        {
+            return true;
+        }
+
+        //- Return the explicit correction to the face-interpolate
+        virtual tmp<GeometricField<Type, fvsPatchField, surfaceMesh> >
+        correction
+        (
+            const GeometricField<Type, fvPatchField, volMesh>& vf
+        ) const
+        {
+            const fvMesh& mesh = this->mesh();
+
+            const extendedUpwindStencil& stencil = Stencil::New
+            (
+                mesh,
+                scalar(0.5)
+            );
+
+            const UpwindFitData<Polynomial>& ufd =
+            UpwindFitData<Polynomial>::New
+            (
+                mesh,
+                stencil,
+                linearLimitFactor_,
+                centralWeight_
+            );
+
+            const List<scalarList>& fo = ufd.owncoeffs();
+            const List<scalarList>& fn = ufd.neicoeffs();
+
+            return stencil.weightedSum(faceFlux_, vf, fo, fn);
+        }
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+// Add the patch constructor functions to the hash tables
+
+#define makeUpwindFitSurfaceInterpolationTypeScheme(SS, POLYNOMIAL, STENCIL, TYPE) \
+                                                                              \
+typedef UpwindFitScheme<TYPE, POLYNOMIAL, STENCIL>                           \
+    UpwindFitScheme##TYPE##POLYNOMIAL##STENCIL##_;                           \
+defineTemplateTypeNameAndDebugWithName                                        \
+    (UpwindFitScheme##TYPE##POLYNOMIAL##STENCIL##_, #SS, 0);                 \
+                                                                              \
+surfaceInterpolationScheme<TYPE>::addMeshConstructorToTable                   \
+<UpwindFitScheme<TYPE, POLYNOMIAL, STENCIL> >                                \
+    add##SS##STENCIL##TYPE##MeshConstructorToTable_;                          \
+                                                                              \
+surfaceInterpolationScheme<TYPE>::addMeshFluxConstructorToTable               \
+<UpwindFitScheme<TYPE, POLYNOMIAL, STENCIL> >                                \
+    add##SS##STENCIL##TYPE##MeshFluxConstructorToTable_;
+
+#define makeUpwindFitSurfaceInterpolationScheme(SS, POLYNOMIAL, STENCIL)     \
+                                                                              \
+makeUpwindFitSurfaceInterpolationTypeScheme(SS,POLYNOMIAL,STENCIL,scalar)    \
+makeUpwindFitSurfaceInterpolationTypeScheme(SS,POLYNOMIAL,STENCIL,vector)    \
+makeUpwindFitSurfaceInterpolationTypeScheme(SS,POLYNOMIAL,STENCIL,sphericalTensor) \
+makeUpwindFitSurfaceInterpolationTypeScheme(SS,POLYNOMIAL,STENCIL,symmTensor)\
+makeUpwindFitSurfaceInterpolationTypeScheme(SS,POLYNOMIAL,STENCIL,tensor)
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/finiteVolume/interpolation/surfaceInterpolation/schemes/biLinearFit/biLinearFit.C b/src/finiteVolume/interpolation/surfaceInterpolation/schemes/biLinearFit/biLinearFit.C
new file mode 100644
index 0000000000000000000000000000000000000000..8d49862a97161e7b34ce3c7133b8f7105fceed0f
--- /dev/null
+++ b/src/finiteVolume/interpolation/surfaceInterpolation/schemes/biLinearFit/biLinearFit.C
@@ -0,0 +1,49 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 1991-2007 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software; you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by the
+    Free Software Foundation; either version 2 of the License, or (at your
+    option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM; if not, write to the Free Software Foundation,
+    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+\*---------------------------------------------------------------------------*/
+
+#include "CentredFitScheme.H"
+#include "biLinearFitPolynomial.H"
+#include "centredCFCStencilObject.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+    defineTemplateTypeNameAndDebug
+    (
+        CentredFitData<biLinearFitPolynomial>,
+        0
+    );
+
+    makeCentredFitSurfaceInterpolationScheme
+    (
+        biLinearFit,
+        biLinearFitPolynomial,
+        centredCFCStencilObject
+    );
+}
+
+// ************************************************************************* //
diff --git a/src/finiteVolume/interpolation/surfaceInterpolation/schemes/biLinearFit/biLinearFitPolynomial.H b/src/finiteVolume/interpolation/surfaceInterpolation/schemes/biLinearFit/biLinearFitPolynomial.H
new file mode 100644
index 0000000000000000000000000000000000000000..5960f54ee2b9415b4cd68c2f66963a0765f406e8
--- /dev/null
+++ b/src/finiteVolume/interpolation/surfaceInterpolation/schemes/biLinearFit/biLinearFitPolynomial.H
@@ -0,0 +1,100 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software; you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by the
+    Free Software Foundation; either version 2 of the License, or (at your
+    option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM; if not, write to the Free Software Foundation,
+    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+Class
+    Foam::biLinearFitPolynomial
+
+Description
+    BiLinear polynomial for interpolation fitting.
+    Can be used with the CentredFit scheme to crate a biLinear surface
+    interpolation scheme
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef biLinearFitPolynomial_H
+#define biLinearFitPolynomial_H
+
+#include "vector.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+                     Class biLinearFitPolynomial Declaration
+\*---------------------------------------------------------------------------*/
+
+class biLinearFitPolynomial
+{
+public:
+
+    // Member functions
+
+        static label nTerms(const direction dim)
+        {
+            return
+            (
+                dim == 1 ? 2 :
+                dim == 2 ? 4 :
+                dim == 3 ? 6 : 0
+            );
+        }
+
+        static void addCoeffs
+        (
+            scalar* coeffs,
+            const vector& d,
+            const scalar weight,
+            const direction dim
+        )
+        {
+            register label curIdx = 0;
+
+            coeffs[curIdx++] = weight;
+            coeffs[curIdx++] = weight*d.x();
+
+            if (dim >= 2)
+            {
+                coeffs[curIdx++] = weight*d.y();
+                coeffs[curIdx++] = weight*d.x()*d.y();
+            }
+            if (dim == 3)
+            {
+                coeffs[curIdx++] = weight*d.z();
+                coeffs[curIdx++] = weight*d.x()*d.z();
+            }
+        }
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/finiteVolume/interpolation/surfaceInterpolation/schemes/cubicUpwindFit/cubicUpwindFit.C b/src/finiteVolume/interpolation/surfaceInterpolation/schemes/cubicUpwindFit/cubicUpwindFit.C
new file mode 100644
index 0000000000000000000000000000000000000000..63f239f529581dd23c174fd8df2bddf1c0f2facb
--- /dev/null
+++ b/src/finiteVolume/interpolation/surfaceInterpolation/schemes/cubicUpwindFit/cubicUpwindFit.C
@@ -0,0 +1,49 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 1991-2007 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software; you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by the
+    Free Software Foundation; either version 2 of the License, or (at your
+    option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM; if not, write to the Free Software Foundation,
+    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+\*---------------------------------------------------------------------------*/
+
+#include "UpwindFitScheme.H"
+#include "cubicUpwindFitPolynomial.H"
+#include "upwindCFCStencilObject.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+    defineTemplateTypeNameAndDebug
+    (
+        UpwindFitData<cubicUpwindFitPolynomial>,
+        0
+    );
+
+    makeUpwindFitSurfaceInterpolationScheme
+    (
+        cubicUpwindFit,
+        cubicUpwindFitPolynomial,
+        upwindCFCStencilObject
+    );
+}
+
+// ************************************************************************* //
diff --git a/src/finiteVolume/interpolation/surfaceInterpolation/schemes/cubicUpwindFit/cubicUpwindFitPolynomial.H b/src/finiteVolume/interpolation/surfaceInterpolation/schemes/cubicUpwindFit/cubicUpwindFitPolynomial.H
new file mode 100644
index 0000000000000000000000000000000000000000..dab0871b8e4e8a21c83c8d31ecaf258ac1173698
--- /dev/null
+++ b/src/finiteVolume/interpolation/surfaceInterpolation/schemes/cubicUpwindFit/cubicUpwindFitPolynomial.H
@@ -0,0 +1,109 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software; you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by the
+    Free Software Foundation; either version 2 of the License, or (at your
+    option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM; if not, write to the Free Software Foundation,
+    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+Class
+    Foam::cubicUpwindFitPolynomial
+
+Description
+    Cubic polynomial for upwind biased interpolation fitting.
+
+    Can be used with the UpwindFit scheme to crate a cubic surface
+    interpolation scheme
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef cubicUpwindFitPolynomial_H
+#define cubicUpwindFitPolynomial_H
+
+#include "vector.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+                 Class cubicUpwindFitPolynomial Declaration
+\*---------------------------------------------------------------------------*/
+
+class cubicUpwindFitPolynomial
+{
+public:
+
+    // Member functions
+
+        static label nTerms(const direction dim)
+        {
+            return
+            (
+                dim == 1 ? 4 :
+                dim == 2 ? 8 :
+                dim == 3 ? 14 : 0
+            );
+        }
+
+        static void addCoeffs
+        (
+            scalar* coeffs,
+            const vector& d,
+            const scalar weight,
+            const direction dim
+        )
+        {
+            register label curIdx = 0;
+
+            coeffs[curIdx++] = weight;
+            coeffs[curIdx++] = weight*d.x();
+            coeffs[curIdx++] = weight*sqr(d.x());
+            coeffs[curIdx++] = weight*pow(d.x(),3);
+
+            if (dim >= 2)
+            {
+                coeffs[curIdx++] = weight*d.y();
+                coeffs[curIdx++] = weight*d.x()*d.y();
+                coeffs[curIdx++] = weight*sqr(d.y());
+                coeffs[curIdx++] = weight*d.x()*sqr(d.y());
+            }
+            if (dim == 3)
+            {
+                coeffs[curIdx++] = weight*d.z();
+                coeffs[curIdx++] = weight*d.x()*d.z();
+                coeffs[curIdx++] = weight*d.y()*d.z();
+                coeffs[curIdx++] = weight*sqr(d.z());
+                coeffs[curIdx++] = weight*d.x()*d.y()*d.z();
+                coeffs[curIdx++] = weight*d.x()*sqr(d.z());
+            }
+        }
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/finiteVolume/interpolation/surfaceInterpolation/schemes/quadraticFit/quadraticFit.C b/src/finiteVolume/interpolation/surfaceInterpolation/schemes/quadraticFit/quadraticFit.C
new file mode 100644
index 0000000000000000000000000000000000000000..fd0bd3f8bdfc08985f17c59cda8977cf38ade918
--- /dev/null
+++ b/src/finiteVolume/interpolation/surfaceInterpolation/schemes/quadraticFit/quadraticFit.C
@@ -0,0 +1,49 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 1991-2007 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software; you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by the
+    Free Software Foundation; either version 2 of the License, or (at your
+    option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM; if not, write to the Free Software Foundation,
+    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+\*---------------------------------------------------------------------------*/
+
+#include "CentredFitScheme.H"
+#include "quadraticFitPolynomial.H"
+#include "centredCFCStencilObject.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+    defineTemplateTypeNameAndDebug
+    (
+        CentredFitData<quadraticFitPolynomial>,
+        0
+    );
+
+    makeCentredFitSurfaceInterpolationScheme
+    (
+        quadraticFit,
+        quadraticFitPolynomial,
+        centredCFCStencilObject
+    );
+}
+
+// ************************************************************************* //
diff --git a/src/finiteVolume/interpolation/surfaceInterpolation/schemes/quadraticFit/quadraticFitPolynomial.H b/src/finiteVolume/interpolation/surfaceInterpolation/schemes/quadraticFit/quadraticFitPolynomial.H
new file mode 100644
index 0000000000000000000000000000000000000000..5ba7520df1476250b1605a779555ac6b723decc9
--- /dev/null
+++ b/src/finiteVolume/interpolation/surfaceInterpolation/schemes/quadraticFit/quadraticFitPolynomial.H
@@ -0,0 +1,104 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software; you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by the
+    Free Software Foundation; either version 2 of the License, or (at your
+    option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM; if not, write to the Free Software Foundation,
+    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+Class
+    Foam::quadraticFitPolynomial
+
+Description
+    Quadratic polynomial for centred interpolation fitting.
+
+    Can be used with the CentredFit scheme to crate a quadratic surface
+    interpolation scheme
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef quadraticFitPolynomial_H
+#define quadraticFitPolynomial_H
+
+#include "vector.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+                 Class quadraticFitPolynomial Declaration
+\*---------------------------------------------------------------------------*/
+
+class quadraticFitPolynomial
+{
+public:
+
+    // Member functions
+
+        static label nTerms(const direction dim)
+        {
+            return
+            (
+                dim == 1 ? 3 :
+                dim == 2 ? 6 :
+                dim == 3 ? 9 : 0
+            );
+        }
+
+        static void addCoeffs
+        (
+            scalar* coeffs,
+            const vector& d,
+            const scalar weight,
+            const direction dim
+        )
+        {
+            register label curIdx = 0;
+
+            coeffs[curIdx++] = weight;
+            coeffs[curIdx++] = weight*d.x();
+            coeffs[curIdx++] = weight*sqr(d.x());
+
+            if (dim >= 2)
+            {
+                coeffs[curIdx++] = weight*d.y();
+                coeffs[curIdx++] = weight*d.x()*d.y();
+                coeffs[curIdx++] = weight*sqr(d.y());
+            }
+            if (dim == 3)
+            {
+                coeffs[curIdx++] = weight*d.z();
+                coeffs[curIdx++] = weight*d.x()*d.z();
+                coeffs[curIdx++] = weight*sqr(d.z());
+            }
+        }
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/finiteVolume/interpolation/surfaceInterpolation/schemes/quadraticLinearUpwindFit/quadraticLinearUpwindFit.C b/src/finiteVolume/interpolation/surfaceInterpolation/schemes/quadraticLinearUpwindFit/quadraticLinearUpwindFit.C
new file mode 100644
index 0000000000000000000000000000000000000000..fb344602dca6f65774d5d16ca4faa3fe0adc8a4a
--- /dev/null
+++ b/src/finiteVolume/interpolation/surfaceInterpolation/schemes/quadraticLinearUpwindFit/quadraticLinearUpwindFit.C
@@ -0,0 +1,49 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 1991-2007 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software; you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by the
+    Free Software Foundation; either version 2 of the License, or (at your
+    option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM; if not, write to the Free Software Foundation,
+    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+\*---------------------------------------------------------------------------*/
+
+#include "UpwindFitScheme.H"
+#include "quadraticLinearUpwindFitPolynomial.H"
+#include "upwindCFCStencilObject.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+    defineTemplateTypeNameAndDebug
+    (
+        UpwindFitData<quadraticLinearUpwindFitPolynomial>,
+        0
+    );
+
+    makeUpwindFitSurfaceInterpolationScheme
+    (
+        quadraticLinearUpwindFit,
+        quadraticLinearUpwindFitPolynomial,
+        upwindCFCStencilObject
+    );
+}
+
+// ************************************************************************* //
diff --git a/src/finiteVolume/interpolation/surfaceInterpolation/schemes/quadraticLinearUpwindFit/quadraticLinearUpwindFitPolynomial.H b/src/finiteVolume/interpolation/surfaceInterpolation/schemes/quadraticLinearUpwindFit/quadraticLinearUpwindFitPolynomial.H
new file mode 100644
index 0000000000000000000000000000000000000000..b904d6baa82b6ac8f4a8e55dab9c17e2d630b8bb
--- /dev/null
+++ b/src/finiteVolume/interpolation/surfaceInterpolation/schemes/quadraticLinearUpwindFit/quadraticLinearUpwindFitPolynomial.H
@@ -0,0 +1,102 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software; you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by the
+    Free Software Foundation; either version 2 of the License, or (at your
+    option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM; if not, write to the Free Software Foundation,
+    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+Class
+    Foam::quadraticLinearUpwindFitPolynomial
+
+Description
+    Quadratic polynomial for upwind biased interpolation fitting.
+
+    Can be used with the UpwindFit scheme to crate a quadratic surface
+    interpolation scheme
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef quadraticLinearUpwindFitPolynomial_H
+#define quadraticLinearUpwindFitPolynomial_H
+
+#include "vector.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+                 Class quadraticLinearUpwindFitPolynomial Declaration
+\*---------------------------------------------------------------------------*/
+
+class quadraticLinearUpwindFitPolynomial
+{
+public:
+
+    // Member functions
+
+        static label nTerms(const direction dim)
+        {
+            return
+            (
+                dim == 1 ? 3 :
+                dim == 2 ? 5 :
+                dim == 3 ? 7 : 0
+            );
+        }
+
+        static void addCoeffs
+        (
+            scalar* coeffs,
+            const vector& d,
+            const scalar weight,
+            const direction dim
+        )
+        {
+            register label curIdx = 0;
+
+            coeffs[curIdx++] = weight;
+            coeffs[curIdx++] = weight*d.x();
+            coeffs[curIdx++] = weight*sqr(d.x());
+
+            if (dim >= 2)
+            {
+                coeffs[curIdx++] = weight*d.y();
+                coeffs[curIdx++] = weight*d.x()*d.y();
+            }
+            if (dim == 3)
+            {
+                coeffs[curIdx++] = weight*d.z();
+                coeffs[curIdx++] = weight*d.x()*d.z();
+            }
+        }
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/finiteVolume/interpolation/surfaceInterpolation/schemes/quadraticUpwindFit/quadraticUpwindFit.C b/src/finiteVolume/interpolation/surfaceInterpolation/schemes/quadraticUpwindFit/quadraticUpwindFit.C
new file mode 100644
index 0000000000000000000000000000000000000000..66aadef7dbb6c89d2546eba5b2ef0771f04e13eb
--- /dev/null
+++ b/src/finiteVolume/interpolation/surfaceInterpolation/schemes/quadraticUpwindFit/quadraticUpwindFit.C
@@ -0,0 +1,49 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 1991-2007 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software; you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by the
+    Free Software Foundation; either version 2 of the License, or (at your
+    option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM; if not, write to the Free Software Foundation,
+    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+\*---------------------------------------------------------------------------*/
+
+#include "UpwindFitScheme.H"
+#include "quadraticUpwindFitPolynomial.H"
+#include "upwindFECStencilObject.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+    defineTemplateTypeNameAndDebug
+    (
+        UpwindFitData<quadraticUpwindFitPolynomial>,
+        0
+    );
+
+    makeUpwindFitSurfaceInterpolationScheme
+    (
+        quadraticUpwindFit,
+        quadraticUpwindFitPolynomial,
+        upwindFECStencilObject
+    );
+}
+
+// ************************************************************************* //
diff --git a/src/finiteVolume/interpolation/surfaceInterpolation/schemes/quadraticUpwindFit/quadraticUpwindFitPolynomial.H b/src/finiteVolume/interpolation/surfaceInterpolation/schemes/quadraticUpwindFit/quadraticUpwindFitPolynomial.H
new file mode 100644
index 0000000000000000000000000000000000000000..7256d601a381a53e92a0431b30adedb4f2dc99d2
--- /dev/null
+++ b/src/finiteVolume/interpolation/surfaceInterpolation/schemes/quadraticUpwindFit/quadraticUpwindFitPolynomial.H
@@ -0,0 +1,105 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software; you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by the
+    Free Software Foundation; either version 2 of the License, or (at your
+    option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM; if not, write to the Free Software Foundation,
+    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+Class
+    Foam::quadraticUpwindFitPolynomial
+
+Description
+    Quadratic polynomial for upwind biased interpolation fitting.
+
+    Can be used with the UpwindFit scheme to crate a quadratic surface
+    interpolation scheme
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef quadraticUpwindFitPolynomial_H
+#define quadraticUpwindFitPolynomial_H
+
+#include "vector.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+                 Class quadraticUpwindFitPolynomial Declaration
+\*---------------------------------------------------------------------------*/
+
+class quadraticUpwindFitPolynomial
+{
+public:
+
+    // Member functions
+
+        static label nTerms(const direction dim)
+        {
+            return
+            (
+                dim == 1 ? 3 :
+                dim == 2 ? 6 :
+                dim == 3 ? 9 : 0
+            );
+        }
+
+        static void addCoeffs
+        (
+            scalar* coeffs,
+            const vector& d,
+            const scalar weight,
+            const direction dim
+        )
+        {
+            register label curIdx = 0;
+
+            coeffs[curIdx++] = weight;
+            coeffs[curIdx++] = weight*d.x();
+            coeffs[curIdx++] = weight*sqr(d.x());
+
+            if (dim >= 2)
+            {
+                coeffs[curIdx++] = weight*d.y();
+                coeffs[curIdx++] = weight*d.x()*d.y();
+                //coeffs[curIdx++] = weight*d.x()*sqr(d.y());
+                coeffs[curIdx++] = weight*sqr(d.y());
+            }
+            if (dim == 3)
+            {
+                coeffs[curIdx++] = weight*d.z();
+                coeffs[curIdx++] = weight*d.x()*d.z();
+                coeffs[curIdx++] = weight*sqr(d.z());
+            }
+        }
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/meshTools/Make/files b/src/meshTools/Make/files
index 98c7bf0640d01a9cbef0859fbebeef5f252d2482..a93cd58400f6dfb5c138fa3e1f67b0252df6139a 100644
--- a/src/meshTools/Make/files
+++ b/src/meshTools/Make/files
@@ -55,14 +55,15 @@ indexedOctree/treeDataTriSurface.C
 searchableSurface = searchableSurface
 $(searchableSurface)/distributedTriSurfaceMesh.C
 $(searchableSurface)/searchableBox.C
+$(searchableSurface)/searchableCylinder.C
 $(searchableSurface)/searchablePlane.C
 $(searchableSurface)/searchablePlate.C
 $(searchableSurface)/searchableSphere.C
 $(searchableSurface)/searchableSurface.C
 $(searchableSurface)/searchableSurfaces.C
 $(searchableSurface)/searchableSurfacesQueries.C
-$(searchableSurface)/triSurfaceMesh.C
 $(searchableSurface)/searchableSurfaceWithGaps.C
+$(searchableSurface)/triSurfaceMesh.C
 
 topoSets = sets/topoSets
 $(topoSets)/cellSet.C
diff --git a/src/meshTools/Make/options b/src/meshTools/Make/options
index ef1033b0e8e02532fad69152efae5ae8342f046a..d550c78e4c260fc31774360f5c72203ff1da6969 100644
--- a/src/meshTools/Make/options
+++ b/src/meshTools/Make/options
@@ -1,7 +1,9 @@
 EXE_INC = \
     -I$(LIB_SRC)/triSurface/lnInclude \
+    -I$(LIB_SRC)/decompositionAgglomeration/decompositionMethods/lnInclude \
     -I$(LIB_SRC)/lagrangian/basic/lnInclude
 
 LIB_LIBS = \
     -ltriSurface \
+    -ldecompositionMethods \
     -llagrangian
diff --git a/src/meshTools/octree/treeLeaf.H b/src/meshTools/octree/treeLeaf.H
index 7913d9b790c65bda7d2881768d99253174ed0799..76b22d4c0d1fe3a69605dd06af5cf7cd5f20535e 100644
--- a/src/meshTools/octree/treeLeaf.H
+++ b/src/meshTools/octree/treeLeaf.H
@@ -30,8 +30,10 @@ Description
 
 SourceFiles
     treeLeaf.C
-    octreeDataPointTreeLeaf.C  (specialization for points only)
-    octreeDataPointTreeLeaf.H  (specialization for points only)
+    octreeDataPointTreaLeaf.H       (specialization for points)
+    octreeDataPointTreeLeaf.C
+    octreeDataTriSurfaceTreeLeaf.H  (specialization for triSurface)
+    octreeDataTriSurfaceTreeLeaf.C
 
 \*---------------------------------------------------------------------------*/
 
@@ -274,6 +276,7 @@ public:
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 #include "octreeDataPointTreeLeaf.H"
+#include "octreeDataTriSurfaceTreeLeaf.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
diff --git a/src/meshTools/searchableSurface/distributedTriSurfaceMesh.C b/src/meshTools/searchableSurface/distributedTriSurfaceMesh.C
index 0f44333b6ee94313ac77d73f93a2597d4d6a9295..06020467036039319af49714caa501e7d74ae6b5 100644
--- a/src/meshTools/searchableSurface/distributedTriSurfaceMesh.C
+++ b/src/meshTools/searchableSurface/distributedTriSurfaceMesh.C
@@ -31,38 +31,56 @@ License
 #include "triangleFuncs.H"
 #include "matchPoints.H"
 #include "globalIndex.H"
-#include "PackedBoolList.H"
 #include "Time.H"
 
+#include "IFstream.H"
+#include "decompositionMethod.H"
+#include "vectorList.H"
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
 namespace Foam
 {
-    defineTypeNameAndDebug(distributedTriSurfaceMesh, 0);
-    addToRunTimeSelectionTable
-    (
-        searchableSurface,
-        distributedTriSurfaceMesh,
-        dict
-    );
 
-    scalar distributedTriSurfaceMesh::mergeDist_ = SMALL;
+defineTypeNameAndDebug(distributedTriSurfaceMesh, 0);
+addToRunTimeSelectionTable(searchableSurface, distributedTriSurfaceMesh, dict);
+
 }
 
 
+template<>
+const char*
+Foam::NamedEnum<Foam::distributedTriSurfaceMesh::distributionType, 3>::names[] =
+{
+    "follow",
+    "independent",
+    "frozen"
+};
+
+const Foam::NamedEnum<Foam::distributedTriSurfaceMesh::distributionType, 3>
+    Foam::distributedTriSurfaceMesh::distributionTypeNames_;
+
+
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
 // Read my additional data from the dictionary
 bool Foam::distributedTriSurfaceMesh::read()
 {
-    // Get bb of all domains
+    // Get bb of all domains.
     procBb_.setSize(Pstream::nProcs());
 
     procBb_[Pstream::myProcNo()] = List<treeBoundBox>(dict_.lookup("bounds"));
     Pstream::gatherList(procBb_);
     Pstream::scatterList(procBb_);
 
+    // Distribution type
+    distType_ = distributionTypeNames_.read(dict_.lookup("distributionType"));
+
+    if (dict_.found("mergeDistance"))
+    {
+        dict_.lookup("mergeDistance") >> mergeDist_;
+    }
+
     return true;
 }
 
@@ -86,7 +104,69 @@ bool Foam::distributedTriSurfaceMesh::isLocal
 }
 
 
-void Foam::distributedTriSurfaceMesh::splitSegment
+//void Foam::distributedTriSurfaceMesh::splitSegment
+//(
+//    const label segmentI,
+//    const point& start,
+//    const point& end,
+//    const treeBoundBox& bb,
+//
+//    DynamicList<segment>& allSegments,
+//    DynamicList<label>& allSegmentMap,
+//    DynamicList<label> sendMap
+//) const
+//{
+//    // Work points
+//    point clipPt0, clipPt1;
+//
+//    if (bb.contains(start))
+//    {
+//        // start within, trim end to bb
+//        bool clipped = bb.intersects(end, start, clipPt0);
+//
+//        if (clipped)
+//        {
+//            // segment from start to clippedStart passes
+//            // through proc.
+//            sendMap[procI].append(allSegments.size());
+//            allSegmentMap.append(segmentI);
+//            allSegments.append(segment(start, clipPt0));
+//        }
+//    }
+//    else if (bb.contains(end))
+//    {
+//        // end within, trim start to bb
+//        bool clipped = bb.intersects(start, end, clipPt0);
+//
+//        if (clipped)
+//        {
+//            sendMap[procI].append(allSegments.size());
+//            allSegmentMap.append(segmentI);
+//            allSegments.append(segment(clipPt0, end));
+//        }
+//    }
+//    else
+//    {
+//        // trim both
+//        bool clippedStart = bb.intersects(start, end, clipPt0);
+//
+//        if (clippedStart)
+//        {
+//            bool clippedEnd = bb.intersects(end, clipPt0, clipPt1);
+//
+//            if (clippedEnd)
+//            {
+//                // middle part of segment passes through proc.
+//                sendMap[procI].append(allSegments.size());
+//                allSegmentMap.append(segmentI);
+//                allSegments.append(segment(clipPt0, clipPt1));
+//            }
+//        }
+//    }
+//}
+
+
+void Foam::distributedTriSurfaceMesh::distributeSegment
 (
     const label segmentI,
     const point& start,
@@ -98,7 +178,7 @@ void Foam::distributedTriSurfaceMesh::splitSegment
 ) const
 {
     // Work points
-    point clipPt0, clipPt1;
+    point clipPt;
 
 
     // 1. Fully local already handled outside. Note: retest is cheap.
@@ -108,9 +188,9 @@ void Foam::distributedTriSurfaceMesh::splitSegment
     }
 
 
-    // 2. Check if fully inside other processor. Rare occurrence
+    // 2. If fully inside one other processor, then only need to send
+    // to that one processor even if it intersects another. Rare occurrence
     // but cheap to test.
-
     forAll(procBb_, procI)
     {
         if (procI != Pstream::myProcNo())
@@ -119,8 +199,6 @@ void Foam::distributedTriSurfaceMesh::splitSegment
 
             if (isLocal(bbs, start, end))
             {
-                //Pout<< "    Completely remote segment:"
-                //    << start << end << " on proc:" << procI << endl;
                 sendMap[procI].append(allSegments.size());
                 allSegmentMap.append(segmentI);
                 allSegments.append(segment(start, end));
@@ -130,7 +208,8 @@ void Foam::distributedTriSurfaceMesh::splitSegment
     }
 
 
-    // 3. Not contained in single processor. Clip against proc bbs.
+    // 3. If not contained in single processor send to all intersecting
+    // processors.
     forAll(procBb_, procI)
     {
         const List<treeBoundBox>& bbs = procBb_[procI];
@@ -139,67 +218,37 @@ void Foam::distributedTriSurfaceMesh::splitSegment
         {
             const treeBoundBox& bb = bbs[bbI];
 
-            if (bb.contains(start))
-            {
-                // start within, trim end to bb
-                bool clipped = bb.intersects(end, start, clipPt0);
+            // Scheme a: any processor that intersects the segment gets
+            // the segment.
 
-                if (clipped)
-                {
-                    //Pout<< "    Start of segment:"
-                    //    << start << end << " clips proc:" << procI
-                    //    << " at " << clipPt0 << endl;
-                    // segment from start to clippedStart passes
-                    // through proc.
-                    sendMap[procI].append(allSegments.size());
-                    allSegmentMap.append(segmentI);
-                    allSegments.append(segment(start, clipPt0));
-                }
-            }
-            else if (bb.contains(end))
+            if (bb.intersects(start, end, clipPt))
             {
-                // end within, trim start to bb
-                bool clipped = bb.intersects(start, end, clipPt0);
-
-                if (clipped)
-                {
-                    //Pout<< "    End of segment:"
-                    //    << start << end << " clips proc:" << procI
-                    //    << " at " << clipPt0 << endl;
-                    sendMap[procI].append(allSegments.size());
-                    allSegmentMap.append(segmentI);
-                    allSegments.append(segment(clipPt0, end));
-                }
+                sendMap[procI].append(allSegments.size());
+                allSegmentMap.append(segmentI);
+                allSegments.append(segment(start, end));
             }
-            else
-            {
-                // trim both
-                bool clippedStart = bb.intersects(start, end, clipPt0);
 
-                if (clippedStart)
-                {
-                    bool clippedEnd = bb.intersects(end, clipPt0, clipPt1);
-
-                    if (clippedEnd)
-                    {
-                        //Pout<< "    Middle of segment:"
-                        //    << start << end << " clips proc:" << procI
-                        //    << " at " << clipPt0 << clipPt1 << endl;
-                        // middle part of segment passes through
-                        // proc.
-                        sendMap[procI].append(allSegments.size());
-                        allSegmentMap.append(segmentI);
-                        allSegments.append(segment(clipPt0, clipPt1));
-                    }
-                }
-            }
+            // Alternative: any processor only gets clipped bit of
+            // segment. This gives small problems with additional
+            // truncation errors.
+            //splitSegment
+            //(
+            //    segmentI,
+            //    start,
+            //    end,
+            //    bb,
+            //
+            //    allSegments,
+            //    allSegmentMap,
+            //   sendMap[procI]
+            //);
         }
     }
 }
 
 
 Foam::autoPtr<Foam::mapDistribute>
-Foam::distributedTriSurfaceMesh::constructSegments
+Foam::distributedTriSurfaceMesh::distributeSegments
 (
     const pointField& start,
     const pointField& end,
@@ -227,7 +276,7 @@ Foam::distributedTriSurfaceMesh::constructSegments
 
         forAll(start, segmentI)
         {
-            splitSegment
+            distributeSegment
             (
                 segmentI,
                 start[segmentI],
@@ -243,11 +292,12 @@ Foam::distributedTriSurfaceMesh::constructSegments
         sendMap.setSize(Pstream::nProcs());
         forAll(sendMap, procI)
         {
+            dynSendMap[procI].shrink();
             sendMap[procI].transfer(dynSendMap[procI]);
         }
 
-        allSegments.transfer(dynAllSegments);
-        allSegmentMap.transfer(dynAllSegmentMap);
+        allSegments.transfer(dynAllSegments.shrink());
+        allSegmentMap.transfer(dynAllSegmentMap.shrink());
     }
 
 
@@ -371,7 +421,7 @@ void Foam::distributedTriSurfaceMesh::findLine
 
         const autoPtr<mapDistribute> mapPtr
         (
-            constructSegments
+            distributeSegments
             (
                 start,
                 end,
@@ -707,12 +757,13 @@ Foam::distributedTriSurfaceMesh::calcLocalQueries
         sendMap.setSize(Pstream::nProcs());
         forAll(sendMap, procI)
         {
+            dynSendMap[procI].shrink();
             sendMap[procI].transfer(dynSendMap[procI]);
         }
 
-        allCentres.transfer(dynAllCentres);
-        allRadiusSqr.transfer(dynAllRadiusSqr);
-        allSegmentMap.transfer(dynAllSegmentMap);
+        allCentres.transfer(dynAllCentres.shrink());
+        allRadiusSqr.transfer(dynAllRadiusSqr.shrink());
+        allSegmentMap.transfer(dynAllSegmentMap.shrink());
     }
 
 
@@ -766,6 +817,102 @@ Foam::distributedTriSurfaceMesh::calcLocalQueries
 }
 
 
+// Find bounding boxes that guarantee a more or less uniform distribution
+// of triangles. Decomposition in here is only used to get the bounding
+// boxes, actual decomposition is done later on.
+// Returns a per processor a list of bounding boxes that most accurately
+// describe the shape. For now just a single bounding box per processor but
+// optimisation might be to determine a better fitting shape.
+Foam::List<Foam::List<Foam::treeBoundBox> >
+Foam::distributedTriSurfaceMesh::independentlyDistributedBbs
+(
+    const triSurface& s
+)
+{
+    if (!decomposer_.valid())
+    {
+        // Use current decomposer.
+        // Note: or always use hierarchical?
+        IOdictionary decomposeDict
+        (
+            IOobject
+            (
+                "decomposeParDict",
+                searchableSurface::time().system(),
+                searchableSurface::time(),
+                IOobject::MUST_READ,
+                IOobject::NO_WRITE,
+                false
+            )
+        );
+        decomposer_ = decompositionMethod::New(decomposeDict);
+
+        if (!decomposer_().parallelAware())
+        {
+            FatalErrorIn
+            (
+                "distributedTriSurfaceMesh::independentlyDistributedBbs"
+                "(const triSurface&)"
+            )   << "The decomposition method " << decomposer_().typeName
+                << " does not decompose in parallel."
+                << " Please choose one that does." << exit(FatalError);
+        }
+    }
+
+    // Do decomposition according to triangle centre
+    pointField triCentres(s.size());
+    forAll (s, triI)
+    {
+        triCentres[triI] = s[triI].centre(s.points());
+    }
+
+    // Do the actual decomposition
+    labelList distribution(decomposer_->decompose(triCentres));
+
+    // Find bounding box for all triangles on new distribution.
+
+    // Initialise to inverted box (VGREAT, -VGREAT)
+    List<List<treeBoundBox> > bbs(Pstream::nProcs());
+    forAll(bbs, procI)
+    {
+        bbs[procI].setSize(1);
+        //bbs[procI][0] = boundBox::invertedBox;
+        bbs[procI][0].min() = point( VGREAT,  VGREAT,  VGREAT);
+        bbs[procI][0].max() = point(-VGREAT, -VGREAT, -VGREAT); 
+    }
+
+    forAll (s, triI)
+    {
+        point& bbMin = bbs[distribution[triI]][0].min();
+        point& bbMax = bbs[distribution[triI]][0].max();
+
+        const labelledTri& f = s[triI];
+        const point& p0 = s.points()[f[0]];
+        const point& p1 = s.points()[f[1]];
+        const point& p2 = s.points()[f[2]];
+
+        bbMin = min(bbMin, p0);
+        bbMin = min(bbMin, p1);
+        bbMin = min(bbMin, p2);
+
+        bbMax = max(bbMax, p0);
+        bbMax = max(bbMax, p1);
+        bbMax = max(bbMax, p2);
+    }
+
+    // Now combine for all processors and convert to correct format.
+    forAll(bbs, procI)
+    {
+        forAll(bbs[procI], i)
+        {
+            reduce(bbs[procI][i].min(), minOp<point>());
+            reduce(bbs[procI][i].max(), maxOp<point>());
+        }
+    }
+    return bbs;
+}
+
+
 void Foam::distributedTriSurfaceMesh::calcBounds
 (
     boundBox& bb,
@@ -775,10 +922,12 @@ void Foam::distributedTriSurfaceMesh::calcBounds
     // Unfortunately nPoints constructs meshPoints() so do compact version
     // ourselves
 
-    PackedBoolList pointIsUsed(points().size());
+    PackedList<1> pointIsUsed(points().size());
+    pointIsUsed = 0U;
 
     nPoints = 0;
-    bb = boundBox::invertedBox;
+    bb.min() = point(VGREAT, VGREAT, VGREAT);
+    bb.max() = point(-VGREAT, -VGREAT, -VGREAT);
 
     const triSurface& s = static_cast<const triSurface&>(*this);
 
@@ -1198,17 +1347,30 @@ Foam::distributedTriSurfaceMesh::distributedTriSurfaceMesh
 Foam::distributedTriSurfaceMesh::distributedTriSurfaceMesh(const IOobject& io)
 :
     triSurfaceMesh(io),
+//    triSurfaceMesh
+//    (
+//        IOobject
+//        (
+//            io.name(),
+//            io.db().time().findInstanceDir(io.local()),
+//            io.local(),
+//            io.db(),
+//            io.readOpt(),
+//            io.writeOpt(),
+//            io.registerObject()
+//        )
+//    ),
     dict_
     (
         IOobject
         (
-            io.name() + "Dict",
-            io.instance(),
-            io.local(),
-            io.db(),
-            io.readOpt(),
-            io.writeOpt(),
-            io.registerObject()
+            searchableSurface::name() + "Dict",
+            searchableSurface::instance(),
+            searchableSurface::local(),
+            searchableSurface::db(),
+            searchableSurface::readOpt(),
+            searchableSurface::writeOpt(),
+            searchableSurface::registerObject()
         )
     )
 {
@@ -1223,17 +1385,31 @@ Foam::distributedTriSurfaceMesh::distributedTriSurfaceMesh
 )
 :
     triSurfaceMesh(io, dict),
+//    triSurfaceMesh
+//    (
+//        IOobject
+//        (
+//            io.name(),
+//            io.db().time().findInstanceDir(io.local()),
+//            io.local(),
+//            io.db(),
+//            io.readOpt(),
+//            io.writeOpt(),
+//            io.registerObject()
+//        ),
+//        dict
+//    ),
     dict_
     (
         IOobject
         (
-            io.name() + "Dict",
-            io.instance(),
-            io.local(),
-            io.db(),
-            io.readOpt(),
-            io.writeOpt(),
-            io.registerObject()
+            searchableSurface::name() + "Dict",
+            searchableSurface::instance(),
+            searchableSurface::local(),
+            searchableSurface::db(),
+            searchableSurface::readOpt(),
+            searchableSurface::writeOpt(),
+            searchableSurface::registerObject()
         )
     )
 {
@@ -1260,7 +1436,7 @@ void Foam::distributedTriSurfaceMesh::clearOut()
 
 const Foam::globalIndex& Foam::distributedTriSurfaceMesh::globalTris() const
 {
-    if (globalTris_.empty())
+    if (!globalTris_.valid())
     {
         globalTris_.reset(new globalIndex(triSurface::size()));
     }
@@ -1855,6 +2031,18 @@ Foam::triSurface Foam::distributedTriSurfaceMesh::overlappingSurface
     // Determine what triangles to keep.
     boolList includedFace(s.size(), false);
 
+    // Create a slightly larger bounding box.
+    List<treeBoundBox> bbsX(bbs.size());
+    const scalar eps = 1.0e-4;
+    forAll(bbs, i)
+    {
+        const point mid = 0.5*(bbs[i].min() + bbs[i].max());
+        const vector halfSpan = (1.0+eps)*(bbs[i].max() - mid);
+
+        bbsX[i].min() = mid - halfSpan;
+        bbsX[i].max() = mid + halfSpan;
+    }
+
     forAll(s, triI)
     {
         const labelledTri& f = s[triI];
@@ -1862,7 +2050,7 @@ Foam::triSurface Foam::distributedTriSurfaceMesh::overlappingSurface
         const point& p1 = s.points()[f[1]];
         const point& p2 = s.points()[f[2]];
 
-        if (overlaps(bbs, p0, p1, p2))
+        if (overlaps(bbsX, p0, p1, p2))
         {
             includedFace[triI] = true;
         }
@@ -1880,17 +2068,37 @@ void Foam::distributedTriSurfaceMesh::distribute
     autoPtr<mapDistribute>& pointMap
 )
 {
-    // Get bb of all domains
+    // Get bbs of all domains
+    // ~~~~~~~~~~~~~~~~~~~~~~
+
     {
         List<List<treeBoundBox> > newProcBb(Pstream::nProcs());
-        newProcBb[Pstream::myProcNo()].setSize(bbs.size());
-        forAll(bbs, i)
+
+        switch(distType_)
         {
-            newProcBb[Pstream::myProcNo()][i] = bbs[i];
-        }
-        Pstream::gatherList(newProcBb);
-        Pstream::scatterList(newProcBb);
+            case FOLLOW:
+                newProcBb[Pstream::myProcNo()].setSize(bbs.size());
+                forAll(bbs, i)
+                {
+                    newProcBb[Pstream::myProcNo()][i] = bbs[i];
+                }
+                Pstream::gatherList(newProcBb);
+                Pstream::scatterList(newProcBb);
+            break;
 
+            case INDEPENDENT:
+                newProcBb = independentlyDistributedBbs(*this);
+            break;
+
+            case FROZEN:
+                return;
+            break;
+
+            default:
+                FatalErrorIn("distributedTriSurfaceMesh::distribute(..)")
+                    << "Unsupported distribution type." << exit(FatalError);
+            break;
+        }
 
         //if (debug)
         //{
@@ -1931,6 +2139,9 @@ void Foam::distributedTriSurfaceMesh::distribute
     }
 
 
+    // Use procBbs to determine which faces go where
+    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
     labelListList faceSendMap(Pstream::nProcs());
     labelListList pointSendMap(Pstream::nProcs());
 
diff --git a/src/meshTools/searchableSurface/distributedTriSurfaceMesh.H b/src/meshTools/searchableSurface/distributedTriSurfaceMesh.H
index e7b7b6fb2f1a10d7c450138a1816603418542d51..733cd24891e21befee9e9318fa301180bc3f8966 100644
--- a/src/meshTools/searchableSurface/distributedTriSurfaceMesh.H
+++ b/src/meshTools/searchableSurface/distributedTriSurfaceMesh.H
@@ -26,7 +26,20 @@ Class
     Foam::distributedTriSurfaceMesh
 
 Description
-    IOoject and searching on triSurface
+    IOoject and searching on distributed triSurface. All processor hold
+    (possibly overlapping) part of the overall surface. All queries are
+    distributed to the processor that can answer it and the result sent back.
+
+    Can work in three modes:
+    - follow : makes sure each processor has all the triangles inside the
+    externally provided bounding box (usually the mesh bounding box).
+    Guarantees minimum amount of communication since mesh-local queries
+    should be answerable without any comms.
+    - independent : surface is decomposed according to the triangle centres
+    so the decomposition might be radically different from the mesh
+    decomposition. Guarantees best memory balance but at the expense of
+    more communication.
+    - frozen : no change
 
 SourceFiles
     distributedTriSurfaceMesh.C
@@ -47,6 +60,7 @@ namespace Foam
 {
 
 class mapDistribute;
+class decompositionMethod;
 
 // Typedefs
 typedef Pair<point> segment;
@@ -62,12 +76,26 @@ class distributedTriSurfaceMesh
 :
     public triSurfaceMesh
 {
-private:
+public:
 
     // Static data
 
+        enum distributionType
+        {
+            FOLLOW = 0,
+            INDEPENDENT = 1,
+            FROZEN = 2
+        };
+
+        static const NamedEnum<distributionType, 3> distributionTypeNames_;
+
+private:
+
         //- Merging distance
-        static scalar mergeDist_;
+        scalar mergeDist_;
+
+        //- Decomposition used when independently decomposing surface.
+        autoPtr<decompositionMethod> decomposer_;
 
 
     // Private member data
@@ -81,6 +109,9 @@ private:
         //- Global triangle numbering
         mutable autoPtr<globalIndex> globalTris_;
 
+        //- The distribution type.
+        distributionType distType_;
+
 
     // Private Member Functions
 
@@ -100,8 +131,22 @@ private:
             );
 
             //- Split segment into subsegments overlapping the processor
+            //  bounding box.
+            //void Foam::distributedTriSurfaceMesh::splitSegment
+            //(
+            //    const label segmentI,
+            //    const point& start,
+            //    const point& end,
+            //    const treeBoundBox& bb,
+            //
+            //    DynamicList<segment>& allSegments,
+            //    DynamicList<label>& allSegmentMap,
+            //    DynamicList<label> sendMap
+            //) const
+
+            //- Distribute segments into overlapping processor
             //  bounding boxes. Sort per processor.
-            void splitSegment
+            void distributeSegment
             (
                 const label,
                 const point& start,
@@ -114,7 +159,7 @@ private:
 
             //- Divide edges into local and remote segments. Construct map to
             //  distribute and collect data.
-            autoPtr<mapDistribute> constructSegments
+            autoPtr<mapDistribute> distributeSegments
             (
                 const pointField& start,
                 const pointField& end,
@@ -167,6 +212,12 @@ private:
 
         // Surface redistribution
 
+            //- Finds new bounds based on an indepedent decomposition.
+            List<List<treeBoundBox> > independentlyDistributedBbs
+            (
+                const triSurface&
+            );
+
             //- Calculate surface bounding box
             void calcBounds(boundBox& bb, label& nPoints) const;
 
@@ -287,32 +338,6 @@ public:
 
     // Member Functions
 
-        //- Return merge distance
-        static scalar mergeDist()
-        {
-            return mergeDist_;
-        }
-
-        //- Set the merge distance, returning the previous value
-        static scalar setMergeDist(const scalar t)
-        {
-            if (t < -VSMALL)
-            {
-                FatalErrorIn
-                (
-                    "scalar distributedTriSurfaceMesh::setMergeDist"
-                    "(const scalar t)"
-                )   << "Negative merge distance tolerance. This is not allowed."
-                    << abort(FatalError);
-            }
-
-            scalar oldTol = mergeDist_;
-            mergeDist_ = t;
-
-            return oldTol;
-        }
-
-
         //- Triangle indexing (demand driven)
         const globalIndex& globalTris() const;
 
diff --git a/src/meshTools/searchableSurface/searchableCylinder.C b/src/meshTools/searchableSurface/searchableCylinder.C
new file mode 100644
index 0000000000000000000000000000000000000000..e2b8426f1fec5448dc51fbc9347b0893e6e9eb60
--- /dev/null
+++ b/src/meshTools/searchableSurface/searchableCylinder.C
@@ -0,0 +1,468 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software; you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by the
+    Free Software Foundation; either version 2 of the License, or (at your
+    option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM; if not, write to the Free Software Foundation,
+    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+\*---------------------------------------------------------------------------*/
+
+#include "searchableCylinder.H"
+#include "addToRunTimeSelectionTable.H"
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+defineTypeNameAndDebug(searchableCylinder, 0);
+addToRunTimeSelectionTable(searchableSurface, searchableCylinder, dict);
+
+}
+
+
+// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
+
+Foam::pointIndexHit Foam::searchableCylinder::findNearest
+(
+    const point& sample,
+    const scalar nearestDistSqr
+) const
+{
+    pointIndexHit info(false, sample, -1);
+
+    vector v(sample - point1_);
+
+    // Decompose sample-point1 into normal and parallel component
+    scalar parallel = (v & unitDir_);
+
+    // Remove the parallel component
+    v -= parallel*unitDir_;
+    scalar magV = mag(v);
+
+    if (parallel <= 0)
+    {
+        // nearest is at point1 end cap. Clip to radius.
+        if (magV < ROOTVSMALL)
+        {
+            info.setPoint(point1_);
+        }
+        else
+        {
+            //info.setPoint(point1_ + min(magV, radius_)*v/magV);
+            info.setPoint(point1_ + radius_*(v/magV));
+        }
+    }
+    else if (parallel >= magDir_)
+    {
+        // nearest is at point2
+        if (magV < ROOTVSMALL)
+        {
+            info.setPoint(point2_);
+        }
+        else
+        {
+            info.setPoint(point2_ + min(magV, radius_)*v/magV);
+        }
+    }
+    else
+    {
+        if (magV < ROOTVSMALL)
+        {
+            info.setPoint(point1_ + parallel*unitDir_);
+        }
+        else
+        {
+            // Project onto radius
+            info.setPoint(point1_ + parallel*unitDir_ + radius_*v/magV);
+        }
+    }
+
+    if (magSqr(sample - info.rawPoint()) < nearestDistSqr)
+    {
+        info.setHit();
+        info.setIndex(0);
+    }
+
+    return info;
+}
+
+
+// From http://www.gamedev.net/community/forums/topic.asp?topic_id=467789 -
+// intersection of cylinder with ray
+void Foam::searchableCylinder::findLineAll
+(
+    const point& start,
+    const point& end,
+    pointIndexHit& near,
+    pointIndexHit& far
+) const
+{
+    near.setMiss();
+    far.setMiss();
+
+    // Line as P = start + t*V
+    const vector V(end-start);
+
+//Pout<< "point1:" << point1_ << " point2:" << point2_
+//    << " start:" << start << " end:" << end << endl;
+
+    const vector x = (start-point1_) ^ unitDir_;
+    const vector y = V ^ unitDir_;
+    const scalar d = sqr(radius_);
+
+    // Second order equation of the form a*t^2 + b*t + c
+    const scalar a = (y&y);
+    const scalar b = 2*(x&y);
+    const scalar c = (x&x)-d;
+
+    const scalar disc = b*b-4*a*c;
+
+//Pout<< "a:" << a << " b:" << b << " c:" << c << " disc:" << disc
+//    << endl;
+
+    if (disc < 0)
+    {
+        return;
+    }
+    else if (disc < ROOTVSMALL)
+    {
+        // Single solution
+        if (mag(a) > ROOTVSMALL)
+        {
+            scalar t = -b/(2*a);
+            if (t >= 0 && t <= 1)
+            {
+                near.setPoint(start + t*V);
+                near.setHit();
+                near.setIndex(0);
+            }
+        }
+    }
+    else
+    {
+        if (mag(a) > ROOTVSMALL)
+        {
+            scalar sqrtDisc = sqrt(disc);
+
+            scalar t1 = (-b + sqrtDisc)/2*a;
+            scalar t2 = (-b - sqrtDisc)/2*a;
+
+            if (t1 < t2)
+            {
+                if (t1 >= 0 && t1 <= 1)
+                {
+                    near.setPoint(start + t1*V);
+                    near.setHit();
+                    near.setIndex(0);
+                }
+                if (t2 >= 0 && t2 <= 1)
+                {
+                    far.setPoint(start + t2*V);
+                    far.setHit();
+                    far.setIndex(0);
+                }
+            }
+            else
+            {
+                if (t2 >= 0 && t2 <= 1)
+                {
+                    near.setPoint(start + t2*V);
+                    near.setHit();
+                    near.setIndex(0);
+                }
+                if (t1 >= 0 && t1 <= 1)
+                {
+                    far.setPoint(start + t1*V);
+                    far.setHit();
+                    far.setIndex(0);
+                }
+            }
+        }
+    }
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::searchableCylinder::searchableCylinder
+(
+    const IOobject& io,
+    const point& point1,
+    const point& point2,
+    const scalar radius
+)
+:
+    searchableSurface(io),
+    point1_(point1),
+    point2_(point2),
+    magDir_(mag(point2_-point1_)),
+    unitDir_((point2_-point1_)/magDir_),
+    radius_(radius)
+{
+    Pout<< "point1_:" << point1_ << endl;
+    Pout<< "point2_:" << point2_ << endl;
+    Pout<< "magDir_:" << magDir_ << endl;
+    Pout<< "unitDir_:" << unitDir_ << endl;
+    Pout<< "radius_:" << radius_ << endl;
+}
+
+
+Foam::searchableCylinder::searchableCylinder
+(
+    const IOobject& io,
+    const dictionary& dict
+)
+:
+    searchableSurface(io),
+    point1_(dict.lookup("point1")),
+    point2_(dict.lookup("point2")),
+    magDir_(mag(point2_-point1_)),
+    unitDir_((point2_-point1_)/magDir_),
+    radius_(readScalar(dict.lookup("radius")))
+{
+    Pout<< "point1_:" << point1_ << endl;
+    Pout<< "point2_:" << point2_ << endl;
+    Pout<< "magDir_:" << magDir_ << endl;
+    Pout<< "unitDir_:" << unitDir_ << endl;
+    Pout<< "radius_:" << radius_ << endl;
+}
+
+
+// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
+
+Foam::searchableCylinder::~searchableCylinder()
+{}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+const Foam::wordList& Foam::searchableCylinder::regions() const
+{
+    if (regions_.empty())
+    {
+        regions_.setSize(1);
+        regions_[0] = "region0";
+    }
+    return regions_;
+}
+
+
+void Foam::searchableCylinder::findNearest
+(
+    const pointField& samples,
+    const scalarField& nearestDistSqr,
+    List<pointIndexHit>& info
+) const
+{
+    info.setSize(samples.size());
+
+    forAll(samples, i)
+    {
+        info[i] = findNearest(samples[i], nearestDistSqr[i]);
+    }
+}
+
+
+void Foam::searchableCylinder::findLine
+(
+    const pointField& start,
+    const pointField& end,
+    List<pointIndexHit>& info
+) const
+{
+    info.setSize(start.size());
+
+    pointIndexHit b;
+
+    forAll(start, i)
+    {
+        // Pick nearest intersection. If none intersected take second one.
+        findLineAll(start[i], end[i], info[i], b);
+        if (!info[i].hit() && b.hit())
+        {
+            info[i] = b;
+        }
+    }
+}
+
+
+void Foam::searchableCylinder::findLineAny
+(
+    const pointField& start,
+    const pointField& end,
+    List<pointIndexHit>& info
+) const
+{
+    info.setSize(start.size());
+
+    pointIndexHit b;
+
+    forAll(start, i)
+    {
+        // Discard far intersection
+        findLineAll(start[i], end[i], info[i], b);
+        if (!info[i].hit() && b.hit())
+        {
+            info[i] = b;
+        }
+    }
+}
+
+
+void Foam::searchableCylinder::findLineAll
+(
+    const pointField& start,
+    const pointField& end,
+    List<List<pointIndexHit> >& info
+) const
+{
+    info.setSize(start.size());
+
+    forAll(start, i)
+    {
+        pointIndexHit near, far;
+        findLineAll(start[i], end[i], near, far);
+
+        if (near.hit())
+        {
+            if (far.hit())
+            {
+                info[i].setSize(2);
+                info[i][0] = near;
+                info[i][1] = far;
+            }
+            else
+            {
+                info[i].setSize(1);
+                info[i][0] = near;
+            }
+        }
+        else
+        {
+            if (far.hit())
+            {
+                info[i].setSize(1);
+                info[i][0] = far;
+            }
+            else
+            {
+                info[i].clear();
+            }
+        }
+    }
+}
+
+
+void Foam::searchableCylinder::getRegion
+(
+    const List<pointIndexHit>& info,
+    labelList& region
+) const
+{
+    region.setSize(info.size());
+    region = 0;
+}
+
+
+void Foam::searchableCylinder::getNormal
+(
+    const List<pointIndexHit>& info,
+    vectorField& normal
+) const
+{
+    normal.setSize(info.size());
+    normal = vector::zero;
+
+    forAll(info, i)
+    {
+        if (info[i].hit())
+        {
+            vector v(info[i].hitPoint() - point1_);
+
+            // Decompose sample-point1 into normal and parallel component
+            scalar parallel = v & unitDir_;
+
+            if (parallel < 0)
+            {
+                normal[i] = -unitDir_;
+            }
+            else if (parallel > magDir_)
+            {
+                normal[i] = -unitDir_;
+            }
+            else
+            {
+                // Remove the parallel component
+                v -= parallel*unitDir_;
+                normal[i] = v/mag(v);
+            }
+        }
+    }
+}
+
+
+void Foam::searchableCylinder::getVolumeType
+(
+    const pointField& points,
+    List<volumeType>& volType
+) const
+{
+    volType.setSize(points.size());
+    volType = INSIDE;
+
+    forAll(points, pointI)
+    {
+        const point& pt = points[pointI];
+
+        vector v(pt - point1_);
+
+        // Decompose sample-point1 into normal and parallel component
+        scalar parallel = v & unitDir_;
+
+        if (parallel < 0)
+        {
+            // left of point1 endcap
+            volType[pointI] = OUTSIDE;
+        }
+        else if (parallel > magDir_)
+        {
+            // right of point2 endcap
+            volType[pointI] = OUTSIDE;
+        }
+        else
+        {
+            // Remove the parallel component
+            v -= parallel*unitDir_;
+
+            if (mag(v) > radius_)
+            {
+                volType[pointI] = OUTSIDE;
+            }
+            else
+            {
+                volType[pointI] = INSIDE;
+            }
+        }
+    }
+}
+
+
+// ************************************************************************* //
diff --git a/src/meshTools/searchableSurface/searchableCylinder.H b/src/meshTools/searchableSurface/searchableCylinder.H
new file mode 100644
index 0000000000000000000000000000000000000000..55ee0354ddd0665e6e37ec85320aca072fe29a25
--- /dev/null
+++ b/src/meshTools/searchableSurface/searchableCylinder.H
@@ -0,0 +1,225 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software; you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by the
+    Free Software Foundation; either version 2 of the License, or (at your
+    option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM; if not, write to the Free Software Foundation,
+    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+Class
+    Foam::searchableCylinder
+
+Description
+    Searching on cylinder
+
+SourceFiles
+    searchableCylinder.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef searchableCylinder_H
+#define searchableCylinder_H
+
+#include "treeBoundBox.H"
+#include "searchableSurface.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+// Forward declaration of classes
+
+/*---------------------------------------------------------------------------*\
+                           Class searchableCylinder Declaration
+\*---------------------------------------------------------------------------*/
+
+class searchableCylinder
+:
+    public searchableSurface
+{
+private:
+
+    // Private Member Data
+
+        //- 'left' point
+        const point point1_;
+
+        //- 'right' point
+        const point point2_;
+
+        //- length of vector point2-point1
+        const scalar magDir_;
+
+        //- normalised vector point2-point1
+        const vector unitDir_;
+
+        //- Radius squared
+        const scalar radius_;
+
+        //- Names of regions
+        mutable wordList regions_;
+
+
+    // Private Member Functions
+
+        //- Find nearest point on cylinder.
+        pointIndexHit findNearest
+        (
+            const point& sample,
+            const scalar nearestDistSqr
+        ) const;
+
+        //- Find intersection with cylinder
+        void findLineAll
+        (
+            const point& start,
+            const point& end,
+            pointIndexHit& near,
+            pointIndexHit& far
+        ) const;
+
+
+        //- Disallow default bitwise copy construct
+        searchableCylinder(const searchableCylinder&);
+
+        //- Disallow default bitwise assignment
+        void operator=(const searchableCylinder&);
+
+
+public:
+
+    //- Runtime type information
+    TypeName("searchableCylinder");
+
+
+    // Constructors
+
+        //- Construct from components
+        searchableCylinder
+        (
+            const IOobject& io,
+            const point&,
+            const point&,
+            const scalar radius
+        );
+
+        //- Construct from dictionary (used by searchableSurface)
+        searchableCylinder
+        (
+            const IOobject& io,
+            const dictionary& dict
+        );
+
+    // Destructor
+
+        virtual ~searchableCylinder();
+
+
+    // Member Functions
+
+        virtual const wordList& regions() const;
+
+        //- Whether supports volume type below
+        virtual bool hasVolumeType() const
+        {
+            return true;
+        }
+
+        //- Range of local indices that can be returned.
+        virtual label size() const
+        {
+            return 1;
+        }
+
+
+        // Multiple point queries.
+
+            virtual void findNearest
+            (
+                const pointField& sample,
+                const scalarField& nearestDistSqr,
+                List<pointIndexHit>&
+            ) const;
+
+            virtual void findLine
+            (
+                const pointField& start,
+                const pointField& end,
+                List<pointIndexHit>&
+            ) const;
+
+            virtual void findLineAny
+            (
+                const pointField& start,
+                const pointField& end,
+                List<pointIndexHit>&
+            ) const;
+
+            //- Get all intersections in order from start to end.
+            virtual void findLineAll
+            (
+                const pointField& start,
+                const pointField& end,
+                List<List<pointIndexHit> >&
+            ) const;
+
+            //- From a set of points and indices get the region
+            virtual void getRegion
+            (
+                const List<pointIndexHit>&,
+                labelList& region
+            ) const;
+
+            //- From a set of points and indices get the normal
+            virtual void getNormal
+            (
+                const List<pointIndexHit>&,
+                vectorField& normal
+            ) const;
+
+            //- Determine type (inside/outside/mixed) for point. unknown if
+            //  cannot be determined (e.g. non-manifold surface)
+            virtual void getVolumeType
+            (
+                const pointField&,
+                List<volumeType>&
+            ) const;
+
+
+        // regIOobject implementation
+
+            bool writeData(Ostream&) const
+            {
+                notImplemented("searchableCylinder::writeData(Ostream&) const");
+                return false;
+            }
+
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/meshTools/searchableSurface/searchableSurfaces.C b/src/meshTools/searchableSurface/searchableSurfaces.C
index 70cdbe5465e042774e3f1693ce0e0e782e07d1f7..46c968f15369b62c8f47abe05d5fcad7eb8449cd 100644
--- a/src/meshTools/searchableSurface/searchableSurfaces.C
+++ b/src/meshTools/searchableSurface/searchableSurfaces.C
@@ -27,6 +27,7 @@ License
 #include "searchableSurfaces.H"
 #include "searchableSurfacesQueries.H"
 #include "ListOps.H"
+#include "Time.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -186,6 +187,14 @@ Foam::searchableSurfaces::searchableSurfaces
         // their object name. Maybe have stlTriSurfaceMesh which appends .stl
         // when reading/writing?
         namedIO().rename(key);  // names_[surfI]
+        if (namedIO().local() != word::null)
+        {
+            namedIO().instance() = namedIO().time().findInstance
+            (
+                namedIO().local(),
+                namedIO().name()
+            );
+        }
 
         // Create and hook surface
         set
diff --git a/src/postProcessing/foamCalcFunctions/Make/files b/src/postProcessing/foamCalcFunctions/Make/files
index 50dc36be0c5b50ad5d11ca1c643f249b8f8fade9..4f4a0ccf6ff4906926916c1ef1e7a3c39d737a50 100644
--- a/src/postProcessing/foamCalcFunctions/Make/files
+++ b/src/postProcessing/foamCalcFunctions/Make/files
@@ -7,6 +7,7 @@ field/magSqr/magSqr.C
 field/magGrad/magGrad.C
 field/div/div.C
 field/randomise/randomise.C
+field/interpolate/interpolate.C
 
 basic/add/add.C
 
diff --git a/src/postProcessing/foamCalcFunctions/field/interpolate/interpolate.C b/src/postProcessing/foamCalcFunctions/field/interpolate/interpolate.C
new file mode 100644
index 0000000000000000000000000000000000000000..d9126c6c03910f9acf2efa1c3cc032c42a8c321e
--- /dev/null
+++ b/src/postProcessing/foamCalcFunctions/field/interpolate/interpolate.C
@@ -0,0 +1,136 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software; you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by the
+    Free Software Foundation; either version 2 of the License, or (at your
+    option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM; if not, write to the Free Software Foundation,
+    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+\*---------------------------------------------------------------------------*/
+
+#include "interpolate.H"
+#include "addToRunTimeSelectionTable.H"
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+namespace Foam
+{
+    namespace calcTypes
+    {
+        defineTypeNameAndDebug(interpolate, 0);
+        addToRunTimeSelectionTable(calcType, interpolate, dictionary);
+    }
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::calcTypes::interpolate::interpolate()
+:
+    calcType()
+{}
+
+
+// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
+
+Foam::calcTypes::interpolate::~interpolate()
+{}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+void Foam::calcTypes::interpolate::init()
+{
+    Foam::argList::validArgs.append("interpolate");
+    argList::validArgs.append("fieldName1 .. fieldNameN");
+}
+
+
+void Foam::calcTypes::interpolate::preCalc
+(
+    const argList& args,
+    const Time& runTime,
+    const fvMesh& mesh
+)
+{
+    if (args.additionalArgs().size() < 2)
+    {
+        Info<< nl << "must specify one or more fields" << nl;
+        args.printUsage();
+        FatalError.exit();
+    }
+}
+
+
+void Foam::calcTypes::interpolate::calc
+(
+    const argList& args,
+    const Time& runTime,
+    const fvMesh& mesh
+)
+{
+    const stringList& params = args.additionalArgs();
+
+    for (label fieldi=1; fieldi<params.size(); fieldi++)
+    {
+        const word fieldName(params[fieldi]);
+
+        IOobject fieldHeader
+        (
+            fieldName,
+            runTime.timeName(),
+            mesh,
+            IOobject::MUST_READ
+        );
+
+        // Check field exists
+        if (fieldHeader.headerOk())
+        {
+            bool processed = false;
+
+            writeInterpolateField<scalar>(fieldHeader, mesh, processed);
+            writeInterpolateField<vector>(fieldHeader, mesh, processed);
+            writeInterpolateField<sphericalTensor>
+            (
+                fieldHeader,
+                mesh,
+                processed
+            );
+            writeInterpolateField<symmTensor>(fieldHeader, mesh, processed);
+            writeInterpolateField<tensor>(fieldHeader, mesh, processed);
+
+            if (!processed)
+            {
+                 FatalError
+                     << "Unable to process " << fieldName << nl
+                     << "No call to interpolate for fields of type "
+                     << fieldHeader.headerClassName() << nl << nl
+                     << exit(FatalError);
+            }
+        }
+        else
+        {
+            Info<< "    No " << fieldName << endl;
+        }
+    }
+}
+
+
+// ************************************************************************* //
+
diff --git a/src/postProcessing/foamCalcFunctions/field/interpolate/interpolate.H b/src/postProcessing/foamCalcFunctions/field/interpolate/interpolate.H
new file mode 100644
index 0000000000000000000000000000000000000000..156a2c263fceb8e51cbce8c41919005f958f7de1
--- /dev/null
+++ b/src/postProcessing/foamCalcFunctions/field/interpolate/interpolate.H
@@ -0,0 +1,138 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software; you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by the
+    Free Software Foundation; either version 2 of the License, or (at your
+    option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM; if not, write to the Free Software Foundation,
+    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+Class
+    Foam::calcTypes::interpolate
+
+Description
+    Interpolates volume fields to surface fields for each time.
+
+SourceFiles
+    interpolate.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef interpolate_H
+#define interpolate_H
+
+#include "calcType.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+namespace calcTypes
+{
+
+/*---------------------------------------------------------------------------*\
+                          Class interpolate Declaration
+\*---------------------------------------------------------------------------*/
+
+class interpolate
+:
+    public calcType
+{
+    // Private Member Functions
+
+        //- Disallow default bitwise copy construct
+        interpolate(const interpolate&);
+
+        //- Disallow default bitwise assignment
+        void operator=(const interpolate&);
+
+
+protected:
+
+    // Member Functions
+
+        // Calculation routines
+
+            //- Initialise - typically setting static variables,
+            //  e.g. command line arguments
+            virtual void init();
+
+            //- Pre-time loop calculations
+            virtual void preCalc
+            (
+                const argList& args,
+                const Time& runTime,
+                const fvMesh& mesh
+            );
+
+            //- Time loop calculations
+            virtual void calc
+            (
+                const argList& args,
+                const Time& runTime,
+                const fvMesh& mesh
+            );
+
+
+        // I-O
+
+            //- Write interpolate fields
+            template<class Type>
+            void writeInterpolateField
+            (
+                const IOobject& header,
+                const fvMesh& mesh,
+                bool& processed
+            );
+
+
+public:
+
+    //- Runtime type information
+    TypeName("interpolate");
+
+
+    // Constructors
+
+        //- Construct null
+        interpolate();
+
+
+    // Destructor
+
+        virtual ~interpolate();
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace calcTypes
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#ifdef NoRepository
+#   include "writeInterpolateField.C"
+#endif
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/solveMomentumEquation.C b/src/postProcessing/foamCalcFunctions/field/interpolate/writeInterpolateField.C
similarity index 56%
rename from applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/solveMomentumEquation.C
rename to src/postProcessing/foamCalcFunctions/field/interpolate/writeInterpolateField.C
index 935a02b60ac1025abf52ba266def97fb13dc6c94..88b1a295aa12e4a90321016b7c4101242bfef9c5 100644
--- a/applications/solvers/heatTransfer/chtMultiRegionFoam/fluid/solveMomentumEquation.C
+++ b/src/postProcessing/foamCalcFunctions/field/interpolate/writeInterpolateField.C
@@ -22,36 +22,41 @@ License
     along with OpenFOAM; if not, write to the Free Software Foundation,
     Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 
-Description
-    Solve momentum equation and return matrix for use in pressure equation
-
 \*---------------------------------------------------------------------------*/
 
-tmp<fvVectorMatrix> solveMomentumEquation
+template<class Type>
+void Foam::calcTypes::interpolate::writeInterpolateField
 (
-    const bool momentumPredictor,
-    volVectorField& U,
-    const volScalarField& rho,
-    const surfaceScalarField& phi,
-    const volScalarField& pd,
-    const volScalarField& gh,
-    const compressible::turbulenceModel& turb
+    const IOobject& header,
+    const fvMesh& mesh,
+    bool& processed
 )
 {
-    // Solve the Momentum equation
-    tmp<fvVectorMatrix> UEqn
-    (
-        fvm::ddt(rho, U)
-      + fvm::div(phi, U)
-      + turb.divDevRhoReff(U)
-    );
-
-    UEqn().relax();
+    typedef GeometricField<Type, fvPatchField, volMesh> fieldType;
+    typedef GeometricField<Type, fvsPatchField, surfaceMesh> surfaceFieldType;
 
-    if (momentumPredictor)
+    if (header.headerClassName() == fieldType::typeName)
     {
-        solve(UEqn() == -fvc::grad(pd) - fvc::grad(rho)*gh);
+        Info<< "    Reading " << header.name() << endl;
+        fieldType field(header, mesh);
+
+        Info<< "    Calculating interpolate" << header.name() << endl;
+        surfaceFieldType interpolateField
+        (
+            IOobject
+            (
+                "interpolate" + header.name(),
+                mesh.time().timeName(),
+                mesh,
+                IOobject::NO_READ
+            ),
+            fvc::interpolate(field)
+        );
+        interpolateField.write();
+
+        processed = true;
     }
-
-    return UEqn;
 }
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
diff --git a/src/postProcessing/functionObjects/field/fieldAverage/fieldAverage/fieldAverage.C b/src/postProcessing/functionObjects/field/fieldAverage/fieldAverage/fieldAverage.C
index 92b3f96366d4b6e5dd703e0552ba0cff7dcc908a..b117112a539c207ed47f1d02e328021a47478842 100644
--- a/src/postProcessing/functionObjects/field/fieldAverage/fieldAverage/fieldAverage.C
+++ b/src/postProcessing/functionObjects/field/fieldAverage/fieldAverage/fieldAverage.C
@@ -82,7 +82,7 @@ void Foam::fieldAverage::initialise()
     // Add mean fields to the field lists
     forAll(faItems_, i)
     {
-        const word fieldName = faItems_[i].fieldName();
+        const word& fieldName = faItems_[i].fieldName();
         if (obr_.foundObject<volScalarField>(fieldName))
         {
             addMeanField<scalar>(i, meanScalarFields_);
@@ -117,7 +117,7 @@ void Foam::fieldAverage::initialise()
     {
         if (faItems_[i].prime2Mean())
         {
-            const word fieldName = faItems_[i].fieldName();
+            const word& fieldName = faItems_[i].fieldName();
             if (!faItems_[i].mean())
             {
                 FatalErrorIn("Foam::fieldAverage::initialise()")
diff --git a/src/randomProcesses/fft/fft.C b/src/randomProcesses/fft/fft.C
index 660079d6bf80d615915397b83ab036c86b52ef0f..67d13fd04db53d41dc3be55487dae7bc08458f87 100644
--- a/src/randomProcesses/fft/fft.C
+++ b/src/randomProcesses/fft/fft.C
@@ -48,8 +48,9 @@ void fft::transform
 {
     forAll(nn, idim)
     {
-        scalar pow2 = log(scalar(nn[idim]))/log(scalar(2));
-        if ((pow2 - int(pow2 + 0.5)) > SMALL)
+        // Check for power of two
+        unsigned int dimCount = nn[idim];
+        if (!dimCount || (dimCount & (dimCount - 1)))
         {
             FatalErrorIn
             (
diff --git a/src/sampling/Make/files b/src/sampling/Make/files
index 43bc910a3cc2b67b1a314a3f095885c09399a868..004f81d435793d392ca76af730cd3c28509d5faa 100644
--- a/src/sampling/Make/files
+++ b/src/sampling/Make/files
@@ -29,6 +29,7 @@ sampledSurface/isoSurface/sampledIsoSurface.C
 sampledSurface/isoSurface/isoSurfaceCell.C
 sampledSurface/isoSurface/sampledIsoSurfaceCell.C
 sampledSurface/distanceSurface/distanceSurface.C
+sampledSurface/sampledCuttingPlane/sampledCuttingPlane.C
 sampledSurface/sampledSurface/sampledSurface.C
 sampledSurface/sampledSurfaces/sampledSurfaces.C
 sampledSurface/sampledSurfacesFunctionObject/sampledSurfacesFunctionObject.C
diff --git a/src/sampling/sampledSurface/isoSurface/isoSurface.C b/src/sampling/sampledSurface/isoSurface/isoSurface.C
index e146c90f7a73ea6eb2b4b92d86045118245b8c1c..b092f62605e27b12faeb3cc2c6d6679eccfed5fb 100644
--- a/src/sampling/sampledSurface/isoSurface/isoSurface.C
+++ b/src/sampling/sampledSurface/isoSurface/isoSurface.C
@@ -206,7 +206,8 @@ void Foam::isoSurface::calcCutTypes
     if (debug)
     {
         Pout<< "isoSurface : detected " << nCutCells_
-            << " candidate cut cells." << endl;
+            << " candidate cut cells (out of " << mesh_.nCells()
+            << ")." << endl;
     }
 }
 
@@ -814,65 +815,53 @@ Foam::triSurface Foam::isoSurface::stitchTriPoints
         tris.transfer(dynTris);
     }
 
+    if (debug)
+    {
+        Pout<< "isoSurface : merged from " << nTris
+            << " down to " << tris.size() << " triangles." << endl;
+    }
+
 
 
-    // Use face centres to determine 'flat hole' situation (see RMT paper).
+    // Determine 'flat hole' situation (see RMT paper).
     // Two unconnected triangles get connected because (some of) the edges
     // separating them get collapsed. Below only checks for duplicate triangles,
     // not non-manifold edge connectivity.
     if (checkDuplicates)
     {
-        if (debug)
-        {
-            Pout<< "isoSurface : merged from " << nTris
-                << " down to " << tris.size() << " triangles." << endl;
-        }
+        labelListList pointFaces;
+        invertManyToMany(newPoints.size(), tris, pointFaces);
+
+        // Filter out duplicates.
+        DynamicList<label> newToOldTri(tris.size());
 
-        pointField centres(tris.size());
         forAll(tris, triI)
         {
-            centres[triI] = tris[triI].centre(newPoints);
-        }
-
-        pointField mergedCentres;
-        labelList oldToMerged;
-        bool hasMerged = mergePoints
-        (
-            centres,
-            mergeDistance_,
-            false,
-            oldToMerged,
-            mergedCentres
-        );
+            const labelledTri& tri = tris[triI];
 
-        if (debug)
-        {
-            Pout<< "isoSurface : detected "
-                << centres.size()-mergedCentres.size()
-                << " duplicate triangles." << endl;
-        }
+            const labelList& pFaces = pointFaces[tri[0]];
 
-        if (hasMerged)
-        {
-            // Filter out duplicates.
-            label newTriI = 0;
-            DynamicList<label> newToOldTri(tris.size());
-            labelList newToMaster(mergedCentres.size(), -1);
-            forAll(tris, triI)
+            // Find the minimum of any duplicates
+            label dupTriI = -1;
+            forAll(pFaces, i)
             {
-                label mergedI = oldToMerged[triI];
-
-                if (newToMaster[mergedI] == -1)
+                if (pFaces[i] < triI && tris[pFaces[i]] == tri)
                 {
-                    newToMaster[mergedI] = triI;
-                    newToOldTri.append(triMap[triI]);
-                    tris[newTriI++] = tris[triI];
+                    dupTriI = pFaces[i];
                 }
             }
 
-            triMap.transfer(newToOldTri);
-            tris.setSize(newTriI);
+            if (dupTriI == -1)
+            {
+                // There is no lower triangle
+                label newTriI = newToOldTri.size();
+                newToOldTri.append(triI);
+                tris[newTriI] = tris[triI];
+            }
         }
+
+        triMap.transfer(newToOldTri);
+        tris.setSize(triMap.size());
     }
 
     return triSurface(tris, geometricSurfacePatchList(0), newPoints, true);
@@ -986,7 +975,7 @@ void Foam::isoSurface::calcAddressing
     {
         Pout<< "isoSurface : detected "
             << mergedCentres.size()
-            << " edges on " << surf.size() << " triangles." << endl;
+            << " geometric edges on " << surf.size() << " triangles." << endl;
     }
 
     if (!hasMerged)
@@ -1013,6 +1002,10 @@ void Foam::isoSurface::calcAddressing
     edgeFace1 = -1;
     edgeFacesRest.clear();
 
+    // Overflow edge faces for geometric shared edges that turned
+    // out to be different anyway.
+    EdgeMap<labelList> extraEdgeFaces(mergedCentres.size()/100);
+
     forAll(oldToMerged, oldEdgeI)
     {
         label triI = oldEdgeI / 3;
@@ -1020,33 +1013,127 @@ void Foam::isoSurface::calcAddressing
 
         if (edgeFace0[edgeI] == -1)
         {
+            // First triangle for edge
             edgeFace0[edgeI] = triI;
         }
-        else if (edgeFace1[edgeI] == -1)
-        {
-            edgeFace1[edgeI] = triI;
-        }
         else
         {
-            //WarningIn("orientSurface(triSurface&)")
-            //    << "Edge " << edgeI << " with centre " << mergedCentres[edgeI]
-            //    << " used by more than two triangles: " << edgeFace0[edgeI]
-            //    << ", "
-            //    << edgeFace1[edgeI] << " and " << triI << endl;
-            Map<labelList>::iterator iter = edgeFacesRest.find(edgeI);
-
-            if (iter != edgeFacesRest.end())
+            //- Check that the two triangles actually topologically
+            //  share an edge
+            const labelledTri& prevTri = surf[edgeFace0[edgeI]];
+            const labelledTri& tri = surf[triI];
+
+            label fp = oldEdgeI % 3;
+
+            edge e(tri[fp], tri[tri.fcIndex(fp)]);
+
+            label prevTriIndex = -1;
+
+            forAll(prevTri, i)
             {
-                labelList& eFaces = iter();
-                label sz = eFaces.size();
-                eFaces.setSize(sz+1);
-                eFaces[sz] = triI;
+                if (edge(prevTri[i], prevTri[prevTri.fcIndex(i)]) == e)
+                {
+                    prevTriIndex = i;
+                    break;
+                }
+            }
+
+            if (prevTriIndex == -1)
+            {
+                // Different edge. Store for later.
+                EdgeMap<labelList>::iterator iter = extraEdgeFaces.find(e);
+
+                if (iter != extraEdgeFaces.end())
+                {
+                    labelList& eFaces = iter();
+                    label sz = eFaces.size();
+                    eFaces.setSize(sz+1);
+                    eFaces[sz] = triI;
+                }
+                else
+                {
+                    extraEdgeFaces.insert(e, labelList(1, triI));
+                }
+            }
+            else if (edgeFace1[edgeI] == -1)
+            {
+                edgeFace1[edgeI] = triI;
             }
             else
             {
-                edgeFacesRest.insert(edgeI, labelList(1, triI));
+                //WarningIn("orientSurface(triSurface&)")
+                //    << "Edge " << edgeI << " with centre "
+                //    << mergedCentres[edgeI]
+                //    << " used by more than two triangles: "
+                //    << edgeFace0[edgeI] << ", "
+                //    << edgeFace1[edgeI] << " and " << triI << endl;
+                Map<labelList>::iterator iter = edgeFacesRest.find(edgeI);
+
+                if (iter != edgeFacesRest.end())
+                {
+                    labelList& eFaces = iter();
+                    label sz = eFaces.size();
+                    eFaces.setSize(sz+1);
+                    eFaces[sz] = triI;
+                }
+                else
+                {
+                    edgeFacesRest.insert(edgeI, labelList(1, triI));
+                }
+            }
+        }
+    }
+
+    // Add extraEdgeFaces
+    edgeI = edgeFace0.size();
+
+    edgeFace0.setSize(edgeI + extraEdgeFaces.size());
+    edgeFace1.setSize(edgeI + extraEdgeFaces.size(), -1);
+
+    forAllConstIter(EdgeMap<labelList>, extraEdgeFaces, iter)
+    {
+        const labelList& eFaces = iter();
+
+        // The current edge will become edgeI. Replace all occurrences in
+        // faceEdges
+        forAll(eFaces, i)
+        {
+            label triI = eFaces[i];
+            const labelledTri& tri = surf[triI];
+
+            FixedList<label, 3>& fEdges = faceEdges[triI];
+            forAll(tri, fp)
+            {
+                edge e(tri[fp], tri[tri.fcIndex(fp)]);
+
+                if (e == iter.key())
+                {
+                    fEdges[fp] = edgeI;
+                    break;
+                }
+            }
+        }
+
+
+        // Add face to edgeFaces
+
+        edgeFace0[edgeI] = eFaces[0];
+
+        if (eFaces.size() >= 2)
+        {
+            edgeFace1[edgeI] = eFaces[1];
+
+            if (eFaces.size() > 2)
+            {
+                edgeFacesRest.insert
+                (
+                    edgeI,
+                    SubList<label>(eFaces, eFaces.size()-2, 2)
+                );
             }
         }
+
+        edgeI++;
     }
 }
 
@@ -1097,6 +1184,24 @@ void Foam::isoSurface::walkOrientation
 
                     // nbr points
                     label nbrFp = findIndex(nbrTri, p0);
+
+                    if (nbrFp == -1)
+                    {
+                        FatalErrorIn("isoSurface::walkOrientation(..)")
+                            << "triI:" << triI
+                            << " tri:" << tri
+                            << " p0:" << p0
+                            << " p1:" << p1
+                            << " fEdges:" << fEdges
+                            << " edgeI:" << edgeI
+                            << " edgeFace0:" << edgeFace0[edgeI]
+                            << " edgeFace1:" << edgeFace1[edgeI]
+                            << " nbrI:" << nbrI
+                            << " nbrTri:" << nbrTri
+                            << abort(FatalError);
+                    }
+
+
                     label nbrP1 = nbrTri[nbrTri.rcIndex(nbrFp)];
 
                     bool sameOrientation = (p1 == nbrP1);
@@ -1352,8 +1457,17 @@ Foam::isoSurface::isoSurface
     iso_(iso),
     mergeDistance_(mergeTol*mesh_.bounds().mag())
 {
+    if (debug)
+    {
+        Pout<< "isoSurface     :" << nl
+            << "    isoField   : " << cVals.name() << nl
+            << "    isoValue   : " << iso << nl
+            << "    regularise : " << regularise << nl
+            << "    mergeTol   : " << mergeTol << nl
+            << endl;
+    }
+
     const polyBoundaryMesh& patches = mesh_.boundaryMesh();
-    const labelList& own = mesh_.faceOwner();
 
     // Check
     forAll(patches, patchI)
@@ -1442,24 +1556,6 @@ Foam::isoSurface::isoSurface
         snappedCc = -1;
     }
 
-    // Determine neighbouring snap status
-    labelList neiSnappedCc(mesh_.nFaces()-mesh_.nInternalFaces(), -1);
-    forAll(patches, patchI)
-    {
-        const polyPatch& pp = patches[patchI];
-
-        if (pp.coupled())
-        {
-            label faceI = pp.start();
-            forAll(pp, i)
-            {
-                neiSnappedCc[faceI-mesh_.nInternalFaces()] =
-                    snappedCc[own[faceI]];
-                faceI++;
-            }
-        }
-    }
-    syncTools::swapBoundaryFaceList(mesh_, neiSnappedCc, false);
 
 
     if (debug)
diff --git a/src/sampling/sampledSurface/isoSurface/isoSurfaceTemplates.C b/src/sampling/sampledSurface/isoSurface/isoSurfaceTemplates.C
index 67d05a5a1c73396ae34c5a94dbf0ea5b4ae4759d..50888ee31d2d660cfe2b3d1acf9c1037c53d4cca 100644
--- a/src/sampling/sampledSurface/isoSurface/isoSurfaceTemplates.C
+++ b/src/sampling/sampledSurface/isoSurface/isoSurfaceTemplates.C
@@ -299,7 +299,16 @@ void Foam::isoSurface::generateTriPoints
     )
     {
         FatalErrorIn("isoSurface::generateTriPoints(..)")
-            << "Incorrect size." << abort(FatalError);
+            << "Incorrect size." << endl
+            << "mesh: nCells:" << mesh_.nCells()
+            << " points:" << mesh_.nPoints() << endl
+            << "cVals:" << cVals.size() << endl
+            << "cCoords:" << cCoords.size() << endl
+            << "snappedCc:" << snappedCc.size() << endl
+            << "pVals:" << pVals.size() << endl
+            << "pCoords:" << pCoords.size() << endl
+            << "snappedPoint:" << snappedPoint.size() << endl
+            << abort(FatalError);
     }
 
     // Determine neighbouring snap status
diff --git a/src/sampling/sampledSurface/isoSurface/sampledIsoSurface.C b/src/sampling/sampledSurface/isoSurface/sampledIsoSurface.C
index 7ba7d852dc5881c4d1d90db14a9867245dba7852..9511f6dabe7f0572d3d3f1327c19fa10a306122b 100644
--- a/src/sampling/sampledSurface/isoSurface/sampledIsoSurface.C
+++ b/src/sampling/sampledSurface/isoSurface/sampledIsoSurface.C
@@ -29,7 +29,6 @@ License
 #include "volFields.H"
 #include "volPointInterpolation.H"
 #include "addToRunTimeSelectionTable.H"
-#include "fvMesh.H"
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
@@ -45,8 +44,6 @@ void Foam::sampledIsoSurface::getIsoFields() const
 {
     const fvMesh& fvm = static_cast<const fvMesh&>(mesh());
 
-    word pointFldName = "volPointInterpolate(" + isoField_ + ')';
-
     // Get volField
     // ~~~~~~~~~~~~
 
@@ -54,7 +51,7 @@ void Foam::sampledIsoSurface::getIsoFields() const
     {
         if (debug)
         {
-            Info<< "sampledIsoSurface::getIsoField() : lookup "
+            Info<< "sampledIsoSurface::getIsoField() : lookup volField "
                 << isoField_ << endl;
         }
         storedVolFieldPtr_.clear();
@@ -79,7 +76,7 @@ void Foam::sampledIsoSurface::getIsoFields() const
         {
             if (debug)
             {
-                Info<< "sampledIsoSurface::getIsoField() : reading "
+                Info<< "sampledIsoSurface::getIsoField() : reading volField "
                     << isoField_ << " from time " << fvm.time().timeName()
                     << endl;
             }
@@ -101,78 +98,212 @@ void Foam::sampledIsoSurface::getIsoFields() const
                 )
             );
             volFieldPtr_ = storedVolFieldPtr_.operator->();
+        }
+    }
+
+
 
-            // Interpolate to get pointField
+    // Get pointField
+    // ~~~~~~~~~~~~~~
 
+    if (!subMeshPtr_.valid())
+    {
+        word pointFldName = "volPointInterpolate(" + isoField_ + ')';
+
+        if (fvm.foundObject<pointScalarField>(pointFldName))
+        {
             if (debug)
             {
-                Info<< "sampledIsoSurface::getIsoField() : interpolating "
+                Info<< "sampledIsoSurface::getIsoField() : lookup pointField "
                     << pointFldName << endl;
             }
-
-            storedPointFieldPtr_.reset
-            (
-                volPointInterpolation::New(fvm).interpolate(*volFieldPtr_).ptr()
-            );
-            pointFieldPtr_ = storedPointFieldPtr_.operator->();
+            pointFieldPtr_ = &fvm.lookupObject<pointScalarField>(pointFldName);
         }
-    }
+        else
+        {
+            // Not in registry. Interpolate.
 
+            if (debug)
+            {
+                Info<< "sampledIsoSurface::getIsoField() : checking pointField "
+                    << pointFldName << " for same time "
+                    << fvm.time().timeName() << endl;
+            }
 
+            if
+            (
+                storedPointFieldPtr_.empty()
+             || (fvm.time().timeName() != storedPointFieldPtr_().instance())
+            )
+            {
+                if (debug)
+                {
+                    Info<< "sampledIsoSurface::getIsoField() :"
+                        << " interpolating volField " << volFieldPtr_->name()
+                        << " to get pointField " << pointFldName << endl;
+                }
 
-    // Get pointField
-    // ~~~~~~~~~~~~~~
+                storedPointFieldPtr_.reset
+                (
+                    volPointInterpolation::New(fvm)
+                    .interpolate(*volFieldPtr_).ptr()
+                );
+                storedPointFieldPtr_->checkOut();
+                pointFieldPtr_ = storedPointFieldPtr_.operator->();
+            }
+        }
 
-    if (fvm.foundObject<pointScalarField>(pointFldName))
-    {
         if (debug)
         {
-            Info<< "sampledIsoSurface::getIsoField() : lookup "
-                << pointFldName << endl;
+            Info<< "sampledIsoSurface::getIsoField() : volField "
+                << volFieldPtr_->name() << " min:" << min(*volFieldPtr_).value()
+                << " max:" << max(*volFieldPtr_).value() << endl;
+            Info<< "sampledIsoSurface::getIsoField() : pointField "
+                << pointFieldPtr_->name()
+                << " min:" << gMin(pointFieldPtr_->internalField())
+                << " max:" << gMax(pointFieldPtr_->internalField()) << endl;
         }
-        pointFieldPtr_ = &fvm.lookupObject<pointScalarField>(pointFldName);
     }
     else
     {
-        // Not in registry. Interpolate.
+        // Get subMesh variants
+        const fvMesh& subFvm = subMeshPtr_().subMesh();
 
-        if (debug)
+        // Either lookup on the submesh or subset the whole-mesh volField
+
+        if (subFvm.foundObject<volScalarField>(isoField_))
         {
-            Info<< "sampledIsoSurface::getIsoField() : checking interpolate "
-                << isoField_ << " for same time " << fvm.time().timeName()
-                << endl;
+            if (debug)
+            {
+                Info<< "sampledIsoSurface::getIsoField() :"
+                    << " submesh lookup volField "
+                    << isoField_ << endl;
+            }
+            storedVolSubFieldPtr_.clear();
+            volSubFieldPtr_ = &subFvm.lookupObject<volScalarField>(isoField_);
         }
-
-        if
-        (
-            storedPointFieldPtr_.empty()
-         || (fvm.time().timeName() != storedPointFieldPtr_().instance())
-        )
+        else
         {
             if (debug)
             {
-                Info<< "sampledIsoSurface::getIsoField() : interpolating "
-                    << pointFldName << endl;
+                Info<< "sampledIsoSurface::getIsoField() : subsetting volField "
+                    << isoField_ << endl;
             }
+            storedVolSubFieldPtr_.reset
+            (
+                subMeshPtr_().interpolate
+                (
+                    *volFieldPtr_
+                ).ptr()
+            );
+            storedVolSubFieldPtr_->checkOut();
+            volSubFieldPtr_ = storedVolSubFieldPtr_.operator->();
+        }
 
-            storedPointFieldPtr_.reset
+
+        // Pointfield on submesh
+
+        word pointFldName =
+            "volPointInterpolate("
+          + volSubFieldPtr_->name()
+          + ')';
+
+        if (subFvm.foundObject<pointScalarField>(pointFldName))
+        {
+            if (debug)
+            {
+                Info<< "sampledIsoSurface::getIsoField() :"
+                    << " submesh lookup pointField " << pointFldName << endl;
+            }
+            storedPointSubFieldPtr_.clear();
+            pointSubFieldPtr_ = &subFvm.lookupObject<pointScalarField>
+            (
+                pointFldName
+            );
+        }
+        else
+        {
+            if (debug)
+            {
+                Info<< "sampledIsoSurface::getIsoField() :"
+                    << " interpolating submesh volField "
+                    << volSubFieldPtr_->name()
+                    << " to get submesh pointField " << pointFldName << endl;
+            }
+            storedPointSubFieldPtr_.reset
             (
-                volPointInterpolation::New(fvm).interpolate(*volFieldPtr_).ptr()
+                volPointInterpolation::New
+                (
+                    subFvm
+                ).interpolate(*volSubFieldPtr_).ptr()
             );
-            pointFieldPtr_ = storedPointFieldPtr_.operator->();
+            storedPointSubFieldPtr_->checkOut();
+            pointSubFieldPtr_ = storedPointSubFieldPtr_.operator->();
+        }
+
+        if (debug)
+        {
+            Info<< "sampledIsoSurface::getIsoField() : volSubField "
+                << volSubFieldPtr_->name()
+                << " min:" << min(*volSubFieldPtr_).value()
+                << " max:" << max(*volSubFieldPtr_).value() << endl;
+            Info<< "sampledIsoSurface::getIsoField() : pointSubField "
+                << pointSubFieldPtr_->name()
+                << " min:" << gMin(pointSubFieldPtr_->internalField())
+                << " max:" << gMax(pointSubFieldPtr_->internalField()) << endl;
         }
     }
+}
 
-    if (debug)
+
+Foam::tmp<Foam::volScalarField> Foam::sampledIsoSurface::average
+(
+    const fvMesh& mesh,
+    const pointScalarField& pfld
+) const
+{
+    tmp<volScalarField> tcellAvg
+    (
+        new volScalarField
+        (
+            IOobject
+            (
+                "cellAvg",
+                mesh.time().timeName(),
+                mesh,
+                IOobject::NO_READ,
+                IOobject::NO_WRITE,
+                false
+            ),
+            mesh,
+            dimensionedScalar("zero", dimless, scalar(0.0))
+        )
+    );
+    volScalarField& cellAvg = tcellAvg();
+
+    labelField nPointCells(mesh.nCells(), 0);
+    {
+        for (label pointI = 0; pointI < mesh.nPoints(); pointI++)
+        {
+            const labelList& pCells = mesh.pointCells(pointI);
+
+            forAll(pCells, i)
+            {
+                label cellI = pCells[i];
+
+                cellAvg[cellI] += pfld[pointI];
+                nPointCells[cellI]++;
+            }
+        }
+    }
+    forAll(cellAvg, cellI)
     {
-        Info<< "sampledIsoSurface::getIsoField() : volField "
-            << volFieldPtr_->name() << " min:" << min(*volFieldPtr_).value()
-            << " max:" << max(*volFieldPtr_).value() << endl;
-        Info<< "sampledIsoSurface::getIsoField() : pointField "
-            << pointFieldPtr_->name()
-            << " min:" << gMin(pointFieldPtr_->internalField())
-            << " max:" << gMax(pointFieldPtr_->internalField()) << endl;
+        cellAvg[cellI] /= nPointCells[cellI];
     }
+    // Give value to calculatedFvPatchFields
+    cellAvg.correctBoundaryConditions();
+
+    return tcellAvg;
 }
 
 
@@ -186,6 +317,33 @@ bool Foam::sampledIsoSurface::updateGeometry() const
         return false;
     }
 
+    // Get any subMesh
+    if (zoneID_.index() != -1 && !subMeshPtr_.valid())
+    {
+        const polyBoundaryMesh& patches = mesh().boundaryMesh();
+
+        // Patch to put exposed internal faces into
+        label exposedPatchI = patches.findPatchID(exposedPatchName_);
+
+        if (debug)
+        {
+            Info<< "Allocating subset of size "
+                << mesh().cellZones()[zoneID_.index()].size()
+                << " with exposed faces into patch "
+                << patches[exposedPatchI].name() << endl;
+        }
+
+        subMeshPtr_.reset
+        (
+            new fvMeshSubset(static_cast<const fvMesh&>(mesh()))
+        );
+        subMeshPtr_().setLargeCellSubset
+        (
+            labelHashSet(mesh().cellZones()[zoneID_.index()]),
+            exposedPatchI
+        );
+    }
+
 
     prevTimeIndex_ = fvm.time().timeIndex();
     getIsoFields();
@@ -196,67 +354,65 @@ bool Foam::sampledIsoSurface::updateGeometry() const
 
     if (average_)
     {
-        //- From point field and interpolated cell.
-        volScalarField cellAvg
-        (
-            IOobject
-            (
-                "cellAvg",
-                fvm.time().timeName(),
-                fvm.time(),
-                IOobject::NO_READ,
-                IOobject::NO_WRITE,
-                false
-            ),
-            fvm,
-            dimensionedScalar("zero", dimless, scalar(0.0))
-        );
-        labelField nPointCells(fvm.nCells(), 0);
+        if (subMeshPtr_.valid())
         {
-            for (label pointI = 0; pointI < fvm.nPoints(); pointI++)
-            {
-                const labelList& pCells = fvm.pointCells(pointI);
-
-                forAll(pCells, i)
-                {
-                    label cellI = pCells[i];
-
-                    cellAvg[cellI] += (*pointFieldPtr_)[pointI];
-                    nPointCells[cellI]++;
-                }
-            }
+            surfPtr_.reset
+            (
+                new isoSurface
+                (
+                    average(subMeshPtr_().subMesh(), *pointSubFieldPtr_),
+                    *pointSubFieldPtr_,
+                    isoVal_,
+                    regularise_,
+                    mergeTol_
+                )
+            );
         }
-        forAll(cellAvg, cellI)
+        else
         {
-            cellAvg[cellI] /= nPointCells[cellI];
-        }
-        // Give value to calculatedFvPatchFields
-        cellAvg.correctBoundaryConditions();
-
-        surfPtr_.reset
-        (
-            new isoSurface
+            surfPtr_.reset
             (
-                cellAvg,
-                *pointFieldPtr_,
-                isoVal_,
-                regularise_
-            )
-        );
+                new isoSurface
+                (
+                    average(fvm, *pointFieldPtr_),
+                    *pointFieldPtr_,
+                    isoVal_,
+                    regularise_,
+                    mergeTol_
+                )
+            );
+        }
     }
     else
     {
-        //- Direct from cell field and point field.
-        surfPtr_.reset
-        (
-            new isoSurface
+        if (subMeshPtr_.valid())
+        {
+            surfPtr_.reset
             (
-                *volFieldPtr_,
-                *pointFieldPtr_,
-                isoVal_,
-                regularise_
-            )
-        );
+                new isoSurface
+                (
+                    *volSubFieldPtr_,
+                    *pointSubFieldPtr_,
+                    isoVal_,
+                    regularise_,
+                    mergeTol_
+                )
+            );
+        }
+        else
+        {
+            surfPtr_.reset
+            (
+                new isoSurface
+                (
+                    *volFieldPtr_,
+                    *pointFieldPtr_,
+                    isoVal_,
+                    regularise_,
+                    mergeTol_
+                )
+            );
+        }
     }
 
 
@@ -267,8 +423,13 @@ bool Foam::sampledIsoSurface::updateGeometry() const
             << "    regularise     : " << regularise_ << nl
             << "    average        : " << average_ << nl
             << "    isoField       : " << isoField_ << nl
-            << "    isoValue       : " << isoVal_ << nl
-            << "    points         : " << points().size() << nl
+            << "    isoValue       : " << isoVal_ << nl;
+        if (subMeshPtr_.valid())
+        {
+            Pout<< "    zone size      : " << subMeshPtr_().subMesh().nCells()
+                << nl;
+        }
+        Pout<< "    points         : " << points().size() << nl
             << "    tris           : " << surface().size() << nl
             << "    cut cells      : " << surface().meshCells().size()
             << endl;
@@ -290,9 +451,11 @@ Foam::sampledIsoSurface::sampledIsoSurface
     sampledSurface(name, mesh, dict),
     isoField_(dict.lookup("isoField")),
     isoVal_(readScalar(dict.lookup("isoValue"))),
+    mergeTol_(dict.lookupOrDefault("mergeTol", 1E-6)),
     regularise_(dict.lookupOrDefault("regularise", true)),
     average_(dict.lookupOrDefault("average", false)),
-    zoneName_(word::null),
+    zoneID_(dict.lookupOrDefault("zone", word::null), mesh.cellZones()),
+    exposedPatchName_(word::null),
     surfPtr_(NULL),
     facesPtr_(NULL),
     prevTimeIndex_(-1),
@@ -311,16 +474,29 @@ Foam::sampledIsoSurface::sampledIsoSurface
             << " span across cells." << exit(FatalError);
     }
 
-//    dict.readIfPresent("zone", zoneName_);
-//
-//    if (debug && zoneName_.size())
-//    {
-//        if (mesh.cellZones().findZoneID(zoneName_) < 0)
-//        {
-//            Info<< "cellZone \"" << zoneName_
-//                << "\" not found - using entire mesh" << endl;
-//        }
-//    }
+    if (zoneID_.index() != -1)
+    {
+        dict.lookup("exposedPatchName") >> exposedPatchName_;
+
+        if (mesh.boundaryMesh().findPatchID(exposedPatchName_) == -1)
+        {
+            FatalErrorIn
+            (
+                "sampledIsoSurface::sampledIsoSurface"
+                "(const word&, const polyMesh&, const dictionary&)"
+            )   << "Cannot find patch " << exposedPatchName_
+                << " in which to put exposed faces." << endl
+                << "Valid patches are " << mesh.boundaryMesh().names()
+                << exit(FatalError);
+        }
+
+        if (debug && zoneID_.index() != -1)
+        {
+            Info<< "Restricting to cellZone " << zoneID_.name()
+                << " with exposed internal faces into patch "
+                << exposedPatchName_ << endl;
+        }
+    }
 }
 
 
@@ -344,6 +520,7 @@ bool Foam::sampledIsoSurface::expire()
 {
     surfPtr_.clear();
     facesPtr_.clear();
+    subMeshPtr_.clear();
 
     // already marked as expired
     if (prevTimeIndex_ == -1)
@@ -465,8 +642,8 @@ Foam::sampledIsoSurface::interpolate
 void Foam::sampledIsoSurface::print(Ostream& os) const
 {
     os  << "sampledIsoSurface: " << name() << " :"
-        << "  field:" << isoField_
-        << "  value:" << isoVal_;
+        << "  field   :" << isoField_
+        << "  value   :" << isoVal_;
         //<< "  faces:" << faces().size()       // note: possibly no geom yet
         //<< "  points:" << points().size();
 }
diff --git a/src/sampling/sampledSurface/isoSurface/sampledIsoSurface.H b/src/sampling/sampledSurface/isoSurface/sampledIsoSurface.H
index b0c5ff37b254c7df5c82f96131c27024d5511268..4cf334ecbd504924344a3b6a4b51224f3a9ffbdc 100644
--- a/src/sampling/sampledSurface/isoSurface/sampledIsoSurface.H
+++ b/src/sampling/sampledSurface/isoSurface/sampledIsoSurface.H
@@ -38,8 +38,10 @@ SourceFiles
 #ifndef sampledIsoSurface_H
 #define sampledIsoSurface_H
 
-#include "sampledSurface.H"
 #include "isoSurface.H"
+#include "sampledSurface.H"
+#include "ZoneIDs.H"
+#include "fvMeshSubset.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -62,14 +64,20 @@ class sampledIsoSurface
         //- iso value
         const scalar isoVal_;
 
+        //- Merge tolerance
+        const scalar mergeTol_;
+
         //- Whether to coarse
         const Switch regularise_;
 
         //- Whether to recalculate cell values as average of point values
         const Switch average_;
 
-        //- zone name (if restricted to zones)
-        word zoneName_;
+        //- zone name/index (if restricted to zones)
+        mutable cellZoneID zoneID_;
+
+        //- for zones: patch to put exposed faces into
+        mutable word exposedPatchName_;
 
         mutable autoPtr<isoSurface> surfPtr_;
 
@@ -90,6 +98,19 @@ class sampledIsoSurface
             mutable autoPtr<pointScalarField> storedPointFieldPtr_;
             mutable const pointScalarField* pointFieldPtr_;
 
+            // And on subsetted mesh
+
+                //- Cached submesh
+                mutable autoPtr<fvMeshSubset> subMeshPtr_;
+
+                //- Cached volfield
+                mutable autoPtr<volScalarField> storedVolSubFieldPtr_;
+                mutable const volScalarField* volSubFieldPtr_;
+
+                //- Cached pointfield
+                mutable autoPtr<pointScalarField> storedPointSubFieldPtr_;
+                mutable const pointScalarField* pointSubFieldPtr_;
+
 
 
     // Private Member Functions
@@ -97,6 +118,12 @@ class sampledIsoSurface
         //- Get fields needed to recreate iso surface.
         void getIsoFields() const;
 
+        tmp<volScalarField> average
+        (
+            const fvMesh&,
+            const pointScalarField&
+        ) const;
+
         //- Create iso surface (if time has changed)
         //  Do nothing (and return false) if no update was needed
         bool updateGeometry() const;
diff --git a/src/sampling/sampledSurface/isoSurface/sampledIsoSurfaceTemplates.C b/src/sampling/sampledSurface/isoSurface/sampledIsoSurfaceTemplates.C
index 89fa1b513a948fd6869fa2339912e885eab86b18..57267ac43501df0e09f94af3a6cfb977497c7b7c 100644
--- a/src/sampling/sampledSurface/isoSurface/sampledIsoSurfaceTemplates.C
+++ b/src/sampling/sampledSurface/isoSurface/sampledIsoSurfaceTemplates.C
@@ -52,34 +52,47 @@ Foam::sampledIsoSurface::interpolateField
     const interpolation<Type>& interpolator
 ) const
 {
-    const fvMesh& fvm = static_cast<const fvMesh&>(mesh());
-
     // Get fields to sample. Assume volPointInterpolation!
     const GeometricField<Type, fvPatchField, volMesh>& volFld =
         interpolator.psi();
 
-    tmp<GeometricField<Type, pointPatchField, pointMesh> > tpointFld
-    (
-        volPointInterpolation::New(fvm).interpolate(volFld)
-    );
-
-    const GeometricField<Type, pointPatchField, pointMesh>& pointFld =
-        tpointFld();
-
-    // Get pointers to sampling field (both original and interpolated one)
-    getIsoFields();
-
     // Recreate geometry if time has changed
     updateGeometry();
 
-    // Sample.
-    return surface().interpolate
-    (
-        *volFieldPtr_,
-        *pointFieldPtr_,
-        volFld,
-        pointFld
-    );
+    if (subMeshPtr_.valid())
+    {
+        tmp<GeometricField<Type, fvPatchField, volMesh> > tvolSubFld =
+            subMeshPtr_().interpolate(volFld);
+
+        const GeometricField<Type, fvPatchField, volMesh>& volSubFld =
+            tvolSubFld();
+
+        tmp<GeometricField<Type, pointPatchField, pointMesh> > tpointSubFld =
+            volPointInterpolation::New(volSubFld.mesh()).interpolate(volSubFld);
+
+        // Sample.
+        return surface().interpolate
+        (
+            *volSubFieldPtr_,
+            *pointSubFieldPtr_,
+            volSubFld,
+            tpointSubFld()
+        );
+    }
+    else
+    {
+        tmp<GeometricField<Type, pointPatchField, pointMesh> > tpointFld =
+            volPointInterpolation::New(volFld.mesh()).interpolate(volFld);
+
+        // Sample.
+        return surface().interpolate
+        (
+            *volFieldPtr_,
+            *pointFieldPtr_,
+            volFld,
+            tpointFld()
+        );
+    }
 }
 
 
diff --git a/src/sampling/sampledSurface/sampledCuttingPlane/sampledCuttingPlane.C b/src/sampling/sampledSurface/sampledCuttingPlane/sampledCuttingPlane.C
new file mode 100644
index 0000000000000000000000000000000000000000..85dbeca59590d134b6e7fca455dd391229119de2
--- /dev/null
+++ b/src/sampling/sampledSurface/sampledCuttingPlane/sampledCuttingPlane.C
@@ -0,0 +1,420 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software; you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by the
+    Free Software Foundation; either version 2 of the License, or (at your
+    option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM; if not, write to the Free Software Foundation,
+    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+\*---------------------------------------------------------------------------*/
+
+#include "sampledCuttingPlane.H"
+#include "dictionary.H"
+#include "volFields.H"
+#include "volPointInterpolation.H"
+#include "addToRunTimeSelectionTable.H"
+#include "fvMesh.H"
+#include "isoSurface.H"
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+namespace Foam
+{
+    defineTypeNameAndDebug(sampledCuttingPlane, 0);
+    addNamedToRunTimeSelectionTable(sampledSurface, sampledCuttingPlane, word, cuttingPlane);
+}
+
+// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
+
+void Foam::sampledCuttingPlane::createGeometry()
+{
+    if (debug)
+    {
+        Pout<< "sampledCuttingPlane::createGeometry :updating geometry."
+            << endl;
+    }
+
+    // Clear any stored topologies
+    facesPtr_.clear();
+    isoSurfPtr_.ptr();
+    pointDistance_.clear();
+    cellDistancePtr_.clear();
+
+
+    // Get any subMesh
+    if (zoneID_.index() != -1 && !subMeshPtr_.valid())
+    {
+        const polyBoundaryMesh& patches = mesh().boundaryMesh();
+
+        // Patch to put exposed internal faces into
+        label exposedPatchI = patches.findPatchID(exposedPatchName_);
+
+        if (debug)
+        {
+            Info<< "Allocating subset of size "
+                << mesh().cellZones()[zoneID_.index()].size()
+                << " with exposed faces into patch "
+                << patches[exposedPatchI].name() << endl;
+        }
+
+        subMeshPtr_.reset
+        (
+            new fvMeshSubset(static_cast<const fvMesh&>(mesh()))
+        );
+        subMeshPtr_().setLargeCellSubset
+        (
+            labelHashSet(mesh().cellZones()[zoneID_.index()]),
+            exposedPatchI
+        );
+    }
+
+
+    // Select either the submesh or the underlying mesh
+    const fvMesh& fvm =
+    (
+        subMeshPtr_.valid()
+      ? subMeshPtr_().subMesh()
+      : static_cast<const fvMesh&>(mesh())
+    );
+
+
+    // Distance to cell centres
+    // ~~~~~~~~~~~~~~~~~~~~~~~~
+
+    cellDistancePtr_.reset
+    (
+        new volScalarField
+        (
+            IOobject
+            (
+                "cellDistance",
+                fvm.time().timeName(),
+                fvm.time(),
+                IOobject::NO_READ,
+                IOobject::NO_WRITE,
+                false
+            ),
+            fvm,
+            dimensionedScalar("zero", dimLength, 0)
+        )
+    );
+    volScalarField& cellDistance = cellDistancePtr_();
+
+    // Internal field
+    {
+        const pointField& cc = fvm.C();
+        scalarField& fld = cellDistance.internalField();
+
+        forAll(cc, i)
+        {
+            // Signed distance
+            fld[i] = (cc[i] - plane_.refPoint()) & plane_.normal();
+        }
+    }
+
+    // Patch fields
+    {
+        forAll(fvm.C().boundaryField(), patchI)
+        {
+            const pointField& cc = fvm.C().boundaryField()[patchI];
+            fvPatchScalarField& fld = cellDistance.boundaryField()[patchI];
+
+            forAll(fld, i)
+            {
+                fld[i] =  (cc[i] - plane_.refPoint()) & plane_.normal();
+            }
+        }
+    }
+
+
+    // On processor patches the mesh.C() will already be the cell centre
+    // on the opposite side so no need to swap cellDistance.
+
+
+    // Distance to points
+    pointDistance_.setSize(fvm.nPoints());
+    {
+        const pointField& pts = fvm.points();
+
+        forAll(pointDistance_, i)
+        {
+            pointDistance_[i] = (pts[i] - plane_.refPoint()) & plane_.normal();
+        }
+    }
+
+
+    if (debug)
+    {
+        Pout<< "Writing cell distance:" << cellDistance.objectPath() << endl;
+        cellDistance.write();
+        pointScalarField pDist
+        (
+            IOobject
+            (
+                "pointDistance",
+                fvm.time().timeName(),
+                fvm.time(),
+                IOobject::NO_READ,
+                IOobject::NO_WRITE,
+                false
+            ),
+            pointMesh::New(fvm),
+            dimensionedScalar("zero", dimLength, 0)
+        );
+        pDist.internalField() = pointDistance_;
+
+        Pout<< "Writing point distance:" << pDist.objectPath() << endl;
+        pDist.write();
+    }
+
+
+    //- Direct from cell field and point field.
+    isoSurfPtr_.reset
+    (
+        new isoSurface
+        (
+            cellDistance,
+            pointDistance_,
+            0.0,
+            regularise_
+        )
+    );
+
+    if (debug)
+    {
+        print(Pout);
+        Pout<< endl;
+    }
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::sampledCuttingPlane::sampledCuttingPlane
+(
+    const word& name,
+    const polyMesh& mesh,
+    const dictionary& dict
+)
+:
+    sampledSurface(name, mesh, dict),
+    plane_(dict),
+    mergeTol_(dict.lookupOrDefault("mergeTol", 1E-6)),
+    regularise_(dict.lookupOrDefault("regularise", true)),
+    zoneID_(dict.lookupOrDefault("zone", word::null), mesh.cellZones()),
+    exposedPatchName_(word::null),
+    needsUpdate_(true),
+    subMeshPtr_(NULL),
+    cellDistancePtr_(NULL),
+    isoSurfPtr_(NULL),
+    facesPtr_(NULL)
+{
+    if (zoneID_.index() != -1)
+    {
+        dict.lookup("exposedPatchName") >> exposedPatchName_;
+
+        if (mesh.boundaryMesh().findPatchID(exposedPatchName_) == -1)
+        {
+            FatalErrorIn
+            (
+                "sampledCuttingPlane::sampledCuttingPlane"
+                "(const word&, const polyMesh&, const dictionary&)"
+            )   << "Cannot find patch " << exposedPatchName_
+                << " in which to put exposed faces." << endl
+                << "Valid patches are " << mesh.boundaryMesh().names()
+                << exit(FatalError);
+        }
+
+        if (debug && zoneID_.index() != -1)
+        {
+            Info<< "Restricting to cellZone " << zoneID_.name()
+                << " with exposed internal faces into patch "
+                << exposedPatchName_ << endl;
+        }
+    }
+}
+
+
+// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
+
+Foam::sampledCuttingPlane::~sampledCuttingPlane()
+{}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+bool Foam::sampledCuttingPlane::needsUpdate() const
+{
+    return needsUpdate_;
+}
+
+
+bool Foam::sampledCuttingPlane::expire()
+{
+    if (debug)
+    {
+        Pout<< "sampledCuttingPlane::expire :"
+            << " have-facesPtr_:" << facesPtr_.valid()
+            << " needsUpdate_:" << needsUpdate_ << endl;
+    }
+
+    // Clear any stored topologies
+    facesPtr_.clear();
+
+    // already marked as expired
+    if (needsUpdate_)
+    {
+        return false;
+    }
+
+    needsUpdate_ = true;
+    return true;
+}
+
+
+bool Foam::sampledCuttingPlane::update()
+{
+    if (debug)
+    {
+        Pout<< "sampledCuttingPlane::update :"
+            << " have-facesPtr_:" << facesPtr_.valid()
+            << " needsUpdate_:" << needsUpdate_ << endl;
+    }
+
+    if (!needsUpdate_)
+    {
+        return false;
+    }
+
+    createGeometry();
+
+    needsUpdate_ = false;
+    return true;
+}
+
+
+Foam::tmp<Foam::scalarField>
+Foam::sampledCuttingPlane::sample
+(
+    const volScalarField& vField
+) const
+{
+    return sampleField(vField);
+}
+
+
+Foam::tmp<Foam::vectorField>
+Foam::sampledCuttingPlane::sample
+(
+    const volVectorField& vField
+) const
+{
+    return sampleField(vField);
+}
+
+
+Foam::tmp<Foam::sphericalTensorField>
+Foam::sampledCuttingPlane::sample
+(
+    const volSphericalTensorField& vField
+) const
+{
+    return sampleField(vField);
+}
+
+
+Foam::tmp<Foam::symmTensorField>
+Foam::sampledCuttingPlane::sample
+(
+    const volSymmTensorField& vField
+) const
+{
+    return sampleField(vField);
+}
+
+
+Foam::tmp<Foam::tensorField>
+Foam::sampledCuttingPlane::sample
+(
+    const volTensorField& vField
+) const
+{
+    return sampleField(vField);
+}
+
+
+Foam::tmp<Foam::scalarField>
+Foam::sampledCuttingPlane::interpolate
+(
+    const interpolation<scalar>& interpolator
+) const
+{
+    return interpolateField(interpolator);
+}
+
+
+Foam::tmp<Foam::vectorField>
+Foam::sampledCuttingPlane::interpolate
+(
+    const interpolation<vector>& interpolator
+) const
+{
+    return interpolateField(interpolator);
+}
+
+Foam::tmp<Foam::sphericalTensorField>
+Foam::sampledCuttingPlane::interpolate
+(
+    const interpolation<sphericalTensor>& interpolator
+) const
+{
+    return interpolateField(interpolator);
+}
+
+
+Foam::tmp<Foam::symmTensorField>
+Foam::sampledCuttingPlane::interpolate
+(
+    const interpolation<symmTensor>& interpolator
+) const
+{
+    return interpolateField(interpolator);
+}
+
+
+Foam::tmp<Foam::tensorField>
+Foam::sampledCuttingPlane::interpolate
+(
+    const interpolation<tensor>& interpolator
+) const
+{
+    return interpolateField(interpolator);
+}
+
+
+void Foam::sampledCuttingPlane::print(Ostream& os) const
+{
+    os  << "sampledCuttingPlane: " << name() << " :"
+        << "  plane:" << plane_
+        << "  faces:" << faces().size()
+        << "  points:" << points().size();
+}
+
+
+// ************************************************************************* //
diff --git a/src/sampling/sampledSurface/sampledCuttingPlane/sampledCuttingPlane.H b/src/sampling/sampledSurface/sampledCuttingPlane/sampledCuttingPlane.H
new file mode 100644
index 0000000000000000000000000000000000000000..fcf14db8bd7f1dfe02602eef6867b0a0c1733c47
--- /dev/null
+++ b/src/sampling/sampledSurface/sampledCuttingPlane/sampledCuttingPlane.H
@@ -0,0 +1,258 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software; you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by the
+    Free Software Foundation; either version 2 of the License, or (at your
+    option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM; if not, write to the Free Software Foundation,
+    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+Class
+    Foam::sampledCuttingPlane
+
+Description
+    A sampledSurface defined by a plane
+
+SourceFiles
+    sampledCuttingPlane.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef sampledCuttingPlane_H
+#define sampledCuttingPlane_H
+
+#include "sampledSurface.H"
+#include "isoSurface.H"
+#include "plane.H"
+#include "ZoneIDs.H"
+#include "fvMeshSubset.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+                       Class sampledCuttingPlane Declaration
+\*---------------------------------------------------------------------------*/
+
+class sampledCuttingPlane
+:
+    public sampledSurface
+{
+    // Private data
+
+        //- Plane
+        const plane plane_;
+
+        //- Merge tolerance
+        const scalar mergeTol_;
+
+        //- Whether to coarsen
+        const Switch regularise_;
+
+        //- zone name/index (if restricted to zones)
+        mutable cellZoneID zoneID_;
+
+        //- for zones: patch to put exposed faces into
+        mutable word exposedPatchName_;
+
+        //- Track if the surface needs an update
+        mutable bool needsUpdate_;
+
+
+        //- Optional subsetted mesh
+        autoPtr<fvMeshSubset> subMeshPtr_;
+
+        //- Distance to cell centres
+        autoPtr<volScalarField> cellDistancePtr_;
+
+        //- Distance to points
+        scalarField pointDistance_;
+
+        //- Constructed iso surface
+        autoPtr<isoSurface> isoSurfPtr_;
+
+        //- triangles converted to faceList
+        mutable autoPtr<faceList> facesPtr_;
+
+
+    // Private Member Functions
+
+        //- Create iso surface
+        void createGeometry();
+
+        //- sample field on faces
+        template <class Type>
+        tmp<Field<Type> > sampleField
+        (
+            const GeometricField<Type, fvPatchField, volMesh>& vField
+        ) const;
+
+
+        template <class Type>
+        tmp<Field<Type> >
+        interpolateField(const interpolation<Type>&) const;
+
+
+public:
+
+    //- Runtime type information
+    TypeName("sampledCuttingPlane");
+
+
+    // Constructors
+
+        //- Construct from dictionary
+        sampledCuttingPlane
+        (
+            const word& name,
+            const polyMesh& mesh,
+            const dictionary& dict
+        );
+
+
+    // Destructor
+
+        virtual ~sampledCuttingPlane();
+
+
+    // Member Functions
+
+        //- Does the surface need an update?
+        virtual bool needsUpdate() const;
+
+        //- Mark the surface as needing an update.
+        //  May also free up unneeded data.
+        //  Return false if surface was already marked as expired.
+        virtual bool expire();
+
+        //- Update the surface as required.
+        //  Do nothing (and return false) if no update was needed
+        virtual bool update();
+
+        //- Points of surface
+        virtual const pointField& points() const
+        {
+            return surface().points();
+        }
+
+        //- Faces of surface
+        virtual const faceList& faces() const
+        {
+            if (facesPtr_.empty())
+            {
+                const triSurface& s = surface();
+
+                facesPtr_.reset(new faceList(s.size()));
+
+                forAll(s, i)
+                {
+                    facesPtr_()[i] = s[i].triFaceFace();
+                }
+            }
+            return facesPtr_;
+        }
+
+
+        const isoSurface& surface() const
+        {
+            return isoSurfPtr_();
+        }
+
+        //- sample field on surface
+        virtual tmp<scalarField> sample
+        (
+            const volScalarField&
+        ) const;
+
+        //- sample field on surface
+        virtual tmp<vectorField> sample
+        (
+            const volVectorField&
+        ) const;
+
+        //- sample field on surface
+        virtual tmp<sphericalTensorField> sample
+        (
+            const volSphericalTensorField&
+        ) const;
+
+        //- sample field on surface
+        virtual tmp<symmTensorField> sample
+        (
+            const volSymmTensorField&
+        ) const;
+
+        //- sample field on surface
+        virtual tmp<tensorField> sample
+        (
+            const volTensorField&
+        ) const;
+
+
+        //- interpolate field on surface
+        virtual tmp<scalarField> interpolate
+        (
+            const interpolation<scalar>&
+        ) const;
+
+        //- interpolate field on surface
+        virtual tmp<vectorField> interpolate
+        (
+            const interpolation<vector>&
+        ) const;
+
+        //- interpolate field on surface
+        virtual tmp<sphericalTensorField> interpolate
+        (
+            const interpolation<sphericalTensor>&
+        ) const;
+
+        //- interpolate field on surface
+        virtual tmp<symmTensorField> interpolate
+        (
+            const interpolation<symmTensor>&
+        ) const;
+
+        //- interpolate field on surface
+        virtual tmp<tensorField> interpolate
+        (
+            const interpolation<tensor>&
+        ) const;
+
+        //- Write
+        virtual void print(Ostream&) const;
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#ifdef NoRepository
+#   include "sampledCuttingPlaneTemplates.C"
+#endif
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/sampling/sampledSurface/sampledCuttingPlane/sampledCuttingPlaneTemplates.C b/src/sampling/sampledSurface/sampledCuttingPlane/sampledCuttingPlaneTemplates.C
new file mode 100644
index 0000000000000000000000000000000000000000..f83aeca4e5fe75a2e0505212d299bd447cfa2a5d
--- /dev/null
+++ b/src/sampling/sampledSurface/sampledCuttingPlane/sampledCuttingPlaneTemplates.C
@@ -0,0 +1,97 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software; you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by the
+    Free Software Foundation; either version 2 of the License, or (at your
+    option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM; if not, write to the Free Software Foundation,
+    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+\*---------------------------------------------------------------------------*/
+
+#include "volPointInterpolation.H"
+#include "sampledCuttingPlane.H"
+#include "isoSurface.H"
+#include "volFieldsFwd.H"
+#include "pointFields.H"
+#include "volPointInterpolation.H"
+
+// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
+
+template <class Type>
+Foam::tmp<Foam::Field<Type> >
+Foam::sampledCuttingPlane::sampleField
+(
+    const GeometricField<Type, fvPatchField, volMesh>& vField
+) const
+{
+    return tmp<Field<Type> >(new Field<Type>(vField, surface().meshCells()));
+}
+
+
+template <class Type>
+Foam::tmp<Foam::Field<Type> >
+Foam::sampledCuttingPlane::interpolateField
+(
+    const interpolation<Type>& interpolator
+) const
+{
+    // Get fields to sample. Assume volPointInterpolation!
+    const GeometricField<Type, fvPatchField, volMesh>& volFld =
+        interpolator.psi();
+
+    if (subMeshPtr_.valid())
+    {
+        tmp<GeometricField<Type, fvPatchField, volMesh> > tvolSubFld =
+            subMeshPtr_().interpolate(volFld);
+
+        const GeometricField<Type, fvPatchField, volMesh>& volSubFld =
+            tvolSubFld();
+
+        tmp<GeometricField<Type, pointPatchField, pointMesh> > tpointSubFld =
+            volPointInterpolation::New(volSubFld.mesh()).interpolate(volSubFld);
+
+        // Sample.
+        return surface().interpolate
+        (
+            cellDistancePtr_(),
+            pointDistance_,
+            volSubFld,
+            tpointSubFld()
+        );
+    }
+    else
+    {
+        tmp<GeometricField<Type, pointPatchField, pointMesh> > tpointFld
+        (
+            volPointInterpolation::New(volFld.mesh()).interpolate(volFld)
+        );
+
+        // Sample.
+        return surface().interpolate
+        (
+            cellDistancePtr_(),
+            pointDistance_,
+            volFld,
+            tpointFld()
+        );
+    }
+}
+
+
+// ************************************************************************* //
diff --git a/src/surfMesh/BasicMeshedSurface/BasicMeshedSurface.C b/src/surfMesh/BasicMeshedSurface/BasicMeshedSurface.C
index 6135f703787c87a988bc4f355677adcdf8ea21a4..c495cb4afd581194b73a7db3cb2131d743d0c680 100644
--- a/src/surfMesh/BasicMeshedSurface/BasicMeshedSurface.C
+++ b/src/surfMesh/BasicMeshedSurface/BasicMeshedSurface.C
@@ -27,6 +27,7 @@ License
 #include "BasicMeshedSurface.H"
 #include "boundBox.H"
 #include "mergePoints.H"
+
 // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
 
 template<class Face>
@@ -162,7 +163,7 @@ void Foam::BasicMeshedSurface<Face>::cleanup(const bool verbose)
     stitchFaces(SMALL, verbose);
 
     checkFaces(verbose);
-    this->checkEdges(verbose);
+    this->checkTopology(verbose);
 }
 
 
diff --git a/src/surfMesh/BasicMeshedSurface/BasicMeshedSurface.H b/src/surfMesh/BasicMeshedSurface/BasicMeshedSurface.H
index bb31595d0a3b1ef119760f1f93388bf642eea4d5..89120b255e232619a6c7174081a07a2197301265 100644
--- a/src/surfMesh/BasicMeshedSurface/BasicMeshedSurface.H
+++ b/src/surfMesh/BasicMeshedSurface/BasicMeshedSurface.H
@@ -36,7 +36,8 @@ SourceFiles
 #ifndef BasicMeshedSurface_H
 #define BasicMeshedSurface_H
 
-#include "PrimitivePatchExtra.H"
+#include "PrimitivePatch.H"
+#include "PatchTools.H"
 #include "pointField.H"
 #include "face.H"
 #include "triFace.H"
@@ -55,11 +56,11 @@ namespace Foam
 template<class Face>
 class BasicMeshedSurface
 :
-    public PrimitivePatchExtra<Face, ::Foam::List, pointField, point>
+    public PrimitivePatch<Face, ::Foam::List, pointField, point>
 {
 
     //- Typedefs for convenience
-        typedef PrimitivePatchExtra
+        typedef PrimitivePatch
         <
             Face,
             ::Foam::List,
@@ -83,7 +84,7 @@ protected:
             return static_cast<List<Face> &>(*this);
         }
 
-        //- Set new regions/patches from faceMap
+        //- Set new regions from faceMap
         virtual void remapFaces(const UList<label>& faceMap);
 
 public:
diff --git a/src/surfMesh/Make/files b/src/surfMesh/Make/files
index 19c5eee8b532a48ed7527d6d84faf1e5908bf782..21733262f0049cfe0374d468986c59954f6c2844 100644
--- a/src/surfMesh/Make/files
+++ b/src/surfMesh/Make/files
@@ -1,6 +1,6 @@
-surfGroup/surfGroup.C
-surfGroup/surfGroupIOList.C
-surfPatchIdentifier/surfPatchIdentifier.C
+surfRegion/surfRegion/surfRegion.C
+surfRegion/surfRegion/surfRegionIOList.C
+surfRegion/surfRegionIdentifier/surfRegionIdentifier.C
 
 MeshedSurface/MeshedSurfaces.C
 UnsortedMeshedSurface/UnsortedMeshedSurfaces.C
diff --git a/src/surfMesh/MeshedSurface/MeshedSurface.C b/src/surfMesh/MeshedSurface/MeshedSurface.C
index 7c0dc9cdcdb565e0109d0ae3b311c4c1c5c7a05a..99f54c3a6d5e9fbf376173dd390ef59f7b977733 100644
--- a/src/surfMesh/MeshedSurface/MeshedSurface.C
+++ b/src/surfMesh/MeshedSurface/MeshedSurface.C
@@ -166,11 +166,11 @@ Foam::MeshedSurface<Face>::MeshedSurface
 (
     const Xfer<pointField>& pointLst,
     const Xfer<List<Face> >& faceLst,
-    const Xfer<surfGroupList>& patchLst
+    const Xfer<surfRegionList>& regionLst
 )
 :
     ParentType(pointLst, faceLst),
-    patches_(patchLst)
+    regions_(regionLst)
 {}
 
 
@@ -179,26 +179,26 @@ Foam::MeshedSurface<Face>::MeshedSurface
 (
     const Xfer<pointField>& pointLst,
     const Xfer<List<Face> >& faceLst,
-    const UList<label>& patchSizes,
-    const UList<word>& patchNames
+    const UList<label>& regionSizes,
+    const UList<word>& regionNames
 )
 :
     ParentType(pointLst, faceLst)
 {
-    if (&patchSizes)
+    if (&regionSizes)
     {
-        if (&patchNames)
+        if (&regionNames)
         {
-            addPatches(patchSizes, patchNames);
+            addRegions(regionSizes, regionNames);
         }
         else
         {
-            addPatches(patchSizes);
+            addRegions(regionSizes);
         }
     }
     else
     {
-        onePatch();
+        oneRegion();
     }
 }
 
@@ -238,15 +238,15 @@ Foam::MeshedSurface<Face>::MeshedSurface
     );
 
 
-    // create patch list
-    surfGroupList newPatches(bPatches.size());
+    // create region list
+    surfRegionList newRegions(bPatches.size());
 
     label startFaceI = 0;
     forAll(bPatches, patchI)
     {
         const polyPatch& p = bPatches[patchI];
 
-        newPatches[patchI] = surfGroup
+        newRegions[patchI] = surfRegion
         (
             p.name(),
             p.size(),
@@ -262,7 +262,7 @@ Foam::MeshedSurface<Face>::MeshedSurface
     (
         xferCopy(bPoints),
         xferCopy(bFaces),
-        xferMove(newPatches)
+        xferMove(newRegions)
     );
 
 
@@ -285,7 +285,7 @@ Foam::MeshedSurface<Face>::MeshedSurface
         origFaces.clear();
 
         this->storedFaces().transfer(newFaces);
-        patches_.transfer(surf.patches_);
+        regions_.transfer(surf.regions_);
     }
     else
     {
@@ -305,15 +305,15 @@ Foam::MeshedSurface<Face>::MeshedSurface
 {
     const surfPatchList& sPatches = sMesh.boundaryMesh();
 
-    // create patch list
-    List<surfGroup> newPatches(sPatches.size());
+    // create regions list
+    List<surfRegion> newRegions(sPatches.size());
 
     label startFaceI = 0;
     forAll(sPatches, patchI)
     {
         const surfPatch& p = sPatches[patchI];
 
-        newPatches[patchI] = surfGroup
+        newRegions[patchI] = surfRegion
         (
             p.name(),
             p.size(),
@@ -324,7 +324,7 @@ Foam::MeshedSurface<Face>::MeshedSurface
         startFaceI += p.size();
     }
 
-    patches_.transfer(newPatches);
+    regions_.transfer(newRegions);
 }
 #endif
 
@@ -336,8 +336,8 @@ Foam::MeshedSurface<Face>::MeshedSurface
 )
 {
     labelList faceMap;
-    surfGroupList patchLst = surf.sortedRegions(faceMap);
-    patches_.transfer(patchLst);
+    surfRegionList regionLst = surf.sortedRegions(faceMap);
+    regions_.transfer(regionLst);
 
     const List<Face>& origFaces = surf.faces();
     List<Face> newFaces(origFaces.size());
@@ -388,7 +388,7 @@ template<class Face>
 Foam::MeshedSurface<Face>::MeshedSurface(const MeshedSurface& surf)
 :
     ParentType(surf),
-    patches_(surf.patches_)
+    regions_(surf.regions_)
 {}
 
 
@@ -420,70 +420,70 @@ Foam::MeshedSurface<Face>::~MeshedSurface()
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
 template<class Face>
-void Foam::MeshedSurface<Face>::onePatch(const word& name)
+void Foam::MeshedSurface<Face>::oneRegion(const word& name)
 {
-    word patchName(name);
-    if (patchName.empty())
+    word regionName(name);
+    if (regionName.empty())
     {
-        if (patches_.size())
+        if (regions_.size())
         {
-            patchName = patches_[0].name();
+            regionName = regions_[0].name();
         }
-        if (patchName.empty())
+        if (regionName.empty())
         {
-            patchName = "patch0";
+            regionName = "region0";
         }
     }
 
-    // set single default patch
-    patches_.setSize(1);
-    patches_[0] = surfGroup
+    // set single default region
+    regions_.setSize(1);
+    regions_[0] = surfRegion
     (
-        patchName,
-        size(),         // patch size
-        0,              // patch start
-        0               // patch index
+        regionName,
+        size(),         // region size
+        0,              // region start
+        0               // region index
     );
 }
 
 
 template<class Face>
-void Foam::MeshedSurface<Face>::checkPatches()
+void Foam::MeshedSurface<Face>::checkRegions()
 {
-    // extra safety, ensure we have at some patches,
+    // extra safety, ensure we have at some regions
     // and they cover all the faces - fix start silently
-    if (patches_.size() <= 1)
+    if (regions_.size() <= 1)
     {
-        onePatch();
+        oneRegion();
     }
     else
     {
         label count = 0;
-        forAll(patches_, patchI)
+        forAll(regions_, regionI)
         {
-            patches_[patchI].start() = count;
-            count += patches_[patchI].size();
+            regions_[regionI].start() = count;
+            count += regions_[regionI].size();
         }
 
         if (count < size())
         {
             WarningIn
             (
-                "MeshedSurface::checkPatches()\n"
+                "MeshedSurface::checkRegions()\n"
             )
-                << "more face " << size() << " than patches " << count
-                << " ... extending final patch"
+                << "more face " << size() << " than regions " << count
+                << " ... extending final region"
                 << endl;
 
-            patches_[patches_.size()-1].size() += count - size();
+            regions_[regions_.size()-1].size() += count - size();
         }
         else if (count > size())
         {
             FatalErrorIn
             (
-                "MeshedSurface::checkPatches()\n"
+                "MeshedSurface::checkRegions()\n"
             )
-                << "more patches " << count << " than faces " << size()
+                << "more regions " << count << " than faces " << size()
                 << exit(FatalError);
         }
     }
@@ -534,33 +534,33 @@ void Foam::MeshedSurface<Face>::remapFaces
     const UList<label>& faceMap
 )
 {
-    // recalculate the patch start/size
+    // recalculate the region start/size
     if (&faceMap && faceMap.size())
     {
-        if (patches_.empty())
+        if (regions_.empty())
         {
-            onePatch();
+            oneRegion();
         }
-        else if (patches_.size() == 1)
+        else if (regions_.size() == 1)
         {
-            // optimized for one-patch case
-            patches_[0].size() = faceMap.size();
+            // optimized for single region case
+            regions_[0].size() = faceMap.size();
         }
         else
         {
             label newFaceI = 0;
-            label oldPatchEnd = 0;
-            forAll(patches_, patchI)
+            label origEndI = 0;
+            forAll(regions_, regionI)
             {
-                surfGroup& p = patches_[patchI];
+                surfRegion& reg = regions_[regionI];
 
-                // adjust patch start
-                p.start() = newFaceI;
-                oldPatchEnd += p.size();
+                // adjust region start
+                reg.start() = newFaceI;
+                origEndI += reg.size();
 
                 for (label faceI = newFaceI; faceI < faceMap.size(); ++faceI)
                 {
-                    if (faceMap[faceI] < oldPatchEnd)
+                    if (faceMap[faceI] < origEndI)
                     {
                         ++newFaceI;
                     }
@@ -570,8 +570,8 @@ void Foam::MeshedSurface<Face>::remapFaces
                     }
                 }
 
-                // adjust patch size
-                p.size() = newFaceI - p.start();
+                // adjust region size
+                reg.size() = newFaceI - reg.start();
             }
         }
     }
@@ -586,14 +586,14 @@ template<class Face>
 void Foam::MeshedSurface<Face>::clear()
 {
     ParentType::clear();
-    patches_.clear();
+    regions_.clear();
 }
 
 
 template<class Face>
 Foam::MeshedSurface<Face> Foam::MeshedSurface<Face>::subsetMesh
 (
-    const UList<bool>& include,
+    const labelHashSet& include,
     labelList& pointMap,
     labelList& faceMap
 ) const
@@ -603,7 +603,7 @@ Foam::MeshedSurface<Face> Foam::MeshedSurface<Face>::subsetMesh
 
 
     // Fill pointMap, faceMap
-    this->subsetMap(include, pointMap, faceMap);
+    PatchTools::subsetMap(*this, include, pointMap, faceMap);
 
     // Create compact coordinate list and forward mapping array
     pointField newPoints(pointMap.size());
@@ -614,11 +614,11 @@ Foam::MeshedSurface<Face> Foam::MeshedSurface<Face>::subsetMesh
         oldToNew[pointMap[pointI]] = pointI;
     }
 
-    // create/copy a new patch list, each patch with zero size
-    surfGroupList newPatches(patches_);
-    forAll(newPatches, patchI)
+    // create/copy a new region list, each region with zero size
+    surfRegionList newRegions(regions_);
+    forAll(newRegions, regionI)
     {
-        newPatches[patchI].size() = 0;
+        newRegions[regionI].size() = 0;
     }
 
     // Renumber face node labels
@@ -637,22 +637,22 @@ Foam::MeshedSurface<Face> Foam::MeshedSurface<Face>::subsetMesh
     }
     oldToNew.clear();
 
-    // recalculate the patch start/size
+    // recalculate the region start/size
     label newFaceI = 0;
-    label oldPatchEnd = 0;
+    label origEndI = 0;
 
-    // adjust patch sizes
-    forAll(newPatches, patchI)
+    // adjust region sizes
+    forAll(newRegions, regionI)
     {
-        surfGroup& p = newPatches[patchI];
+        surfRegion& reg = newRegions[regionI];
 
-        // adjust patch start
-        p.start() = newFaceI;
-        oldPatchEnd += p.size();
+        // adjust region start
+        reg.start() = newFaceI;
+        origEndI += reg.size();
 
         for (label faceI = newFaceI; faceI < faceMap.size(); ++faceI)
         {
-            if (faceMap[faceI] < oldPatchEnd)
+            if (faceMap[faceI] < origEndI)
             {
                 ++newFaceI;
             }
@@ -662,8 +662,8 @@ Foam::MeshedSurface<Face> Foam::MeshedSurface<Face>::subsetMesh
             }
         }
 
-        // adjust patch size
-        p.size() = newFaceI - p.start();
+        // adjust region size
+        reg.size() = newFaceI - reg.start();
     }
 
 
@@ -672,15 +672,16 @@ Foam::MeshedSurface<Face> Foam::MeshedSurface<Face>::subsetMesh
     (
         xferMove(newPoints),
         xferMove(newFaces),
-        xferMove(newPatches)
+        xferMove(newRegions)
     );
 }
 
 
 template<class Face>
-Foam::MeshedSurface<Face> Foam::MeshedSurface<Face>::subsetMesh
+Foam::MeshedSurface<Face>
+Foam::MeshedSurface<Face>::subsetMesh
 (
-    const UList<bool>& include
+    const labelHashSet& include
 ) const
 {
     labelList pointMap, faceMap;
@@ -689,85 +690,85 @@ Foam::MeshedSurface<Face> Foam::MeshedSurface<Face>::subsetMesh
 
 
 template<class Face>
-void Foam::MeshedSurface<Face>::addPatches
+void Foam::MeshedSurface<Face>::addRegions
 (
-    const UList<surfGroup>& patches,
+    const UList<surfRegion>& regions,
     const bool cullEmpty
 )
 {
-    label nPatch = 0;
+    label nRegion = 0;
 
-    patches_.setSize(patches.size());
-    forAll(patches_, patchI)
+    regions_.setSize(regions.size());
+    forAll(regions_, regionI)
     {
-        if (patches[patchI].size() || !cullEmpty)
+        if (regions[regionI].size() || !cullEmpty)
         {
-            patches_[nPatch] = surfGroup(patches[patchI], nPatch);
-            nPatch++;
+            regions_[nRegion] = surfRegion(regions[regionI], nRegion);
+            nRegion++;
         }
     }
-    patches_.setSize(nPatch);
+    regions_.setSize(nRegion);
 }
 
 
 template<class Face>
-void Foam::MeshedSurface<Face>::addPatches
+void Foam::MeshedSurface<Face>::addRegions
 (
     const UList<label>& sizes,
     const UList<word>& names,
     const bool cullEmpty
 )
 {
-    label start  = 0;
-    label nPatch = 0;
+    label start   = 0;
+    label nRegion = 0;
 
-    patches_.setSize(sizes.size());
-    forAll(patches_, patchI)
+    regions_.setSize(sizes.size());
+    forAll(regions_, regionI)
     {
-        if (sizes[patchI] || !cullEmpty)
+        if (sizes[regionI] || !cullEmpty)
         {
-            patches_[nPatch] = surfGroup
+            regions_[nRegion] = surfRegion
             (
-                names[patchI],
-                sizes[patchI],
+                names[regionI],
+                sizes[regionI],
                 start,
-                nPatch
+                nRegion
             );
-            start += sizes[patchI];
-            nPatch++;
+            start += sizes[regionI];
+            nRegion++;
         }
     }
-    patches_.setSize(nPatch);
+    regions_.setSize(nRegion);
 }
 
 
 template<class Face>
-void Foam::MeshedSurface<Face>::addPatches
+void Foam::MeshedSurface<Face>::addRegions
 (
     const UList<label>& sizes,
     const bool cullEmpty
 )
 {
-    label start  = 0;
-    label nPatch = 0;
+    label start   = 0;
+    label nRegion = 0;
 
-    patches_.setSize(sizes.size());
-    forAll(patches_, patchI)
+    regions_.setSize(sizes.size());
+    forAll(regions_, regionI)
     {
-        if (sizes[patchI] || !cullEmpty)
+        if (sizes[regionI] || !cullEmpty)
         {
-            patches_[nPatch] = surfGroup
+            regions_[nRegion] = surfRegion
             (
-                word("patch") + ::Foam::name(nPatch),
-                sizes[patchI],
+                word("region") + ::Foam::name(nRegion),
+                sizes[regionI],
                 start,
-                nPatch
+                nRegion
             );
-            start += sizes[patchI];
-            nPatch++;
+            start += sizes[regionI];
+            nRegion++;
         }
     }
-    patches_.setSize(nPatch);
+    regions_.setSize(nRegion);
 }
 
 
@@ -778,7 +779,7 @@ void Foam::MeshedSurface<Face>::transfer
 )
 {
     reset(xferMove(surf.storedPoints()), xferMove(surf.storedFaces()));
-    patches_.transfer(surf.patches_);
+    regions_.transfer(surf.regions_);
 
     surf.clear();
 }
@@ -793,7 +794,7 @@ void Foam::MeshedSurface<Face>::transfer
     clear();
 
     labelList faceMap;
-    surfGroupList patchLst = surf.sortedRegions(faceMap);
+    surfRegionList regionLst = surf.sortedRegions(faceMap);
     List<Face>& oldFaces = surf.storedFaces();
 
     List<Face> newFaces(faceMap.size());
@@ -804,7 +805,7 @@ void Foam::MeshedSurface<Face>::transfer
     faceMap.clear();
 
     reset(xferMove(surf.storedPoints()), xferMove(newFaces));
-    patches_.transfer(patchLst);
+    regions_.transfer(regionLst);
 
     surf.clear();
 }
@@ -864,7 +865,7 @@ void Foam::MeshedSurface<Face>::operator=(const MeshedSurface& surf)
 
     this->storedPoints() = surf.points();
     this->storedFaces()  = surf.faces();
-    patches_ = surf.patches_;
+    regions_ = surf.regions_;
 }
 
 // * * * * * * * * * * * * * * * Friend Functions  * * * * * * * * * * * * * //
diff --git a/src/surfMesh/MeshedSurface/MeshedSurface.H b/src/surfMesh/MeshedSurface/MeshedSurface.H
index e2a1c008fa517cfcfe8b104c422338e7241461ab..493a7ffece1743afc145cb728db6b74af48b79e1 100644
--- a/src/surfMesh/MeshedSurface/MeshedSurface.H
+++ b/src/surfMesh/MeshedSurface/MeshedSurface.H
@@ -26,13 +26,13 @@ Class
     Foam::MeshedSurface
 
 Description
-    A surface geometry mesh with patch information, not to be confused
+    A surface geometry mesh with region information, not to be confused
     with a similarily named surfaceMesh, which actually refers to
     the cell faces of a volume mesh.
 
    The MeshedSurface is intended to surfaces from a variety of sources.
-   - A set of points and faces without any patch information.
-   - A set of points and faces with randomly sorted patch information.
+   - A set of points and faces without any region information.
+   - A set of points and faces with randomly sorted region information.
      This could arise, for example, from reading external file formats
      such as STL, etc.
 
@@ -45,7 +45,7 @@ SourceFiles
 #define MeshedSurface_H
 
 #include "BasicMeshedSurface.H"
-#include "surfGroupList.H"
+#include "surfRegionList.H"
 #include "surfaceFormatsCore.H"
 #include "runTimeSelectionTables.H"
 #include "memberFunctionSelectionTables.H"
@@ -88,9 +88,9 @@ private:
 
     // Private Member Data
 
-        //- Patch information (face ordering nFaces/startFace only used
-        //  during reading and writing)
-        List<surfGroup> patches_;
+        //- Region information
+        // (face ordering nFaces/startFace only used during reading/writing)
+        List<surfRegion> regions_;
 
     // Private member functions
 
@@ -101,8 +101,8 @@ protected:
 
     // Protected Member functions
 
-        //- basic sanity check on patches
-        void checkPatches();
+        //- basic sanity check on regions
+        void checkRegions();
 
         //- sort faces by regions and store sorted faces
         void sortFacesAndStore
@@ -139,22 +139,22 @@ public:
         //- Construct null
         MeshedSurface();
 
-        //- Construct by transferring components (points, faces, patches).
+        //- Construct by transferring components (points, faces, regions).
         MeshedSurface
         (
             const Xfer<pointField>&,
             const Xfer<List<Face> >&,
-            const Xfer<surfGroupList>&
+            const Xfer<surfRegionList>&
         );
 
         //- Construct by transferring points, faces.
-        //  Use patch information, or set single default patch.
+        //  Use region information, or set single default region.
         MeshedSurface
         (
             const Xfer<pointField>&,
             const Xfer<List<Face> >&,
-            const UList<label>& patchSizes = UList<label>::null(),
-            const UList<word>& patchNames = UList<word>::null()
+            const UList<label>& regionSizes = UList<label>::null(),
+            const UList<word>& regionNames = UList<word>::null()
         );
 
         //- Construct from a boundary mesh with local points/faces
@@ -250,31 +250,31 @@ public:
             return ParentType::size();
         }
 
-        const List<surfGroup>& patches() const
+        const List<surfRegion>& regions() const
         {
-            return patches_;
+            return regions_;
         }
 
-        //- set a single patch, optionally with a specific name
-        void onePatch(const word& name = word::null);
+        //- set a single region, optionally with a specific name
+        void oneRegion(const word& name = word::null);
 
-        //- add patches
-        void addPatches
+        //- Add regions
+        void addRegions
         (
-            const UList<surfGroup>&,
+            const UList<surfRegion>&,
             const bool cullEmpty=false
         );
 
-        //- add patches
-        void addPatches
+        //- Add regions
+        void addRegions
         (
             const UList<label>& sizes,
             const UList<word>& names,
             const bool cullEmpty=false
         );
 
-        //- add patches
-        void addPatches
+        //- Add regions
+        void addRegions
         (
             const UList<label>& sizes,
             const bool cullEmpty=false
@@ -289,7 +289,7 @@ public:
         //  Returns return pointMap, faceMap from subsetMeshMap
         MeshedSurface subsetMesh
         (
-            const UList<bool>& include,
+            const labelHashSet& include,
             labelList& pointMap,
             labelList& faceMap
         ) const;
@@ -297,7 +297,7 @@ public:
         //- Return new surface.
         MeshedSurface subsetMesh
         (
-            const UList<bool>& include
+            const labelHashSet& include
         ) const;
 
         //- Transfer the contents of the argument and annull the argument
diff --git a/src/surfMesh/MeshedSurface/MeshedSurfaceIO.C b/src/surfMesh/MeshedSurface/MeshedSurfaceIO.C
index 0d147477c47784cc5f00b7f4c5208f691e8a6400..76e3a23f60e2ed72dae20bb14e6357b4b2f9ce21 100644
--- a/src/surfMesh/MeshedSurface/MeshedSurfaceIO.C
+++ b/src/surfMesh/MeshedSurface/MeshedSurfaceIO.C
@@ -37,16 +37,16 @@ bool Foam::MeshedSurface<Face>::read(Istream& is)
 {
     clear();
 
-    List<surfGroup> patchLst(is);
+    List<surfRegion> regionLst(is);
 
     // copy and set the indices
-    patches_.setSize(patchLst.size());
-    forAll(patchLst, patchI)
+    regions_.setSize(regionLst.size());
+    forAll(regionLst, regionI)
     {
-        patches_[patchI] = surfGroup
+        regions_[regionI] = surfRegion
         (
-            patchLst[patchI],
-            patchI
+            regionLst[regionI],
+            regionI
         );
     }
 
@@ -64,11 +64,11 @@ bool Foam::MeshedSurface<Face>::read(Istream& is)
             Xfer<pointField>::null(),
             faceLst.xfer()
         );
-        surf.addPatches(patches_);
+        surf.addRegions(regions_);
 
         // this will break if the triangulation needed points
         surf.triangulate();
-        patches_ = surf.patches();
+        regions_ = surf.regions();
 
         // transcribe from face -> triFace (Face)
         const List<face>& origFaces = surf.faces();
@@ -102,11 +102,11 @@ void Foam::MeshedSurface<Face>::write(Ostream& os) const
     os  << "// OpenFOAM Surface Format" << nl
         << "// ~~~~~~~~~~~~~~~~~~~~~~~" << nl
         << "// regions:" << nl
-        << patches_.size() << nl << token::BEGIN_LIST << incrIndent << nl;
+        << regions_.size() << nl << token::BEGIN_LIST << incrIndent << nl;
 
-    forAll(patches_, patchI)
+    forAll(regions_, regionI)
     {
-        patches_[patchI].writeDict(os);
+        regions_[regionI].writeDict(os);
     }
     os  << decrIndent << token::END_LIST << nl;
 
diff --git a/src/surfMesh/UnsortedMeshedSurface/UnsortedMeshedSurface.C b/src/surfMesh/UnsortedMeshedSurface/UnsortedMeshedSurface.C
index cb1997c2251d4500f5fb4ec8f8d0859a48e0f5a9..7387b64cfa0ac2c31a90c224ec8526edf203a7dd 100644
--- a/src/surfMesh/UnsortedMeshedSurface/UnsortedMeshedSurface.C
+++ b/src/surfMesh/UnsortedMeshedSurface/UnsortedMeshedSurface.C
@@ -164,12 +164,12 @@ Foam::UnsortedMeshedSurface<Face>::UnsortedMeshedSurface
     const Xfer<pointField>& pointLst,
     const Xfer<List<Face> >& faceLst,
     const Xfer<List<label> >& regionIds,
-    const Xfer<surfPatchIdentifierList>& patchLst
+    const Xfer<surfRegionIdentifierList>& regionTofc
 )
 :
     ParentType(pointLst, faceLst),
-    regions_(regionIds),
-    patches_(patchLst)
+    regionIds_(regionIds),
+    regionToc_(regionTofc)
 {}
 
 
@@ -178,26 +178,26 @@ Foam::UnsortedMeshedSurface<Face>::UnsortedMeshedSurface
 (
     const Xfer<pointField>& pointLst,
     const Xfer<List<Face> >& faceLst,
-    const UList<label>& patchSizes,
-    const UList<word>& patchNames
+    const UList<label>& regionSizes,
+    const UList<word>& regionNames
 )
 :
     ParentType(pointLst, faceLst)
 {
-    if (&patchSizes)
+    if (&regionSizes)
     {
-        if (&patchNames)
+        if (&regionNames)
         {
-            setPatches(patchSizes, patchNames);
+            setRegions(regionSizes, regionNames);
         }
         else
         {
-            setPatches(patchSizes);
+            setRegions(regionSizes);
         }
     }
     else
     {
-        onePatch();
+        oneRegion();
     }
 }
 
@@ -223,7 +223,7 @@ Foam::UnsortedMeshedSurface<Face>::UnsortedMeshedSurface
 :
     ParentType(xferCopy(surf.points()), xferCopy(surf.faces()))
 {
-    setPatches(surf.patches());
+    setRegions(surf.regions());
 }
 
 
@@ -266,8 +266,8 @@ Foam::UnsortedMeshedSurface<Face>::UnsortedMeshedSurface
 )
 :
     ParentType(xferCopy(surf.points()), xferCopy(surf.faces())),
-    regions_(surf.regions_),
-    patches_(surf.patches_)
+    regionIds_(surf.regionIds_),
+    regionToc_(surf.regionToc_)
 {}
 
 
@@ -296,101 +296,105 @@ template<class Face>
 Foam::UnsortedMeshedSurface<Face>::~UnsortedMeshedSurface()
 {}
 
+
 // * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * * //
 
 // * * * * * * * * * * * * Protected Member Functions  * * * * * * * * * * * //
 
 template<class Face>
-void Foam::UnsortedMeshedSurface<Face>::onePatch(const word& name)
+void Foam::UnsortedMeshedSurface<Face>::oneRegion(const word& name)
 {
-    regions_.setSize(size());
-    regions_ = 0;
+    regionIds_.setSize(size());
+    regionIds_ = 0;
 
-    word patchName(name);
-    if (patchName.empty())
+    word regionName(name);
+    if (regionName.empty())
     {
-        if (patches_.size())
+        if (regionToc_.size())
         {
-            patchName = patches_[0].name();
+            regionName = regionToc_[0].name();
         }
-        if (patchName.empty())
+        if (regionName.empty())
         {
-            patchName = "patch0";
+            regionName = "region0";
         }
     }
 
-    // set single default patch
-    patches_.setSize(1);
-    patches_[0] = surfPatchIdentifier(patchName, 0);
+    // set single default region
+    regionToc_.setSize(1);
+    regionToc_[0] = surfRegionIdentifier(regionName, 0);
 }
 
 
 template<class Face>
-void Foam::UnsortedMeshedSurface<Face>::setPatches
+void Foam::UnsortedMeshedSurface<Face>::setRegions
 (
-    const surfGroupList& patches
+    const surfRegionList& regionLst
 )
 {
-    regions_.setSize(size());
-    patches_.setSize(patches.size());
+    regionIds_.setSize(size());
+    regionToc_.setSize(regionLst.size());
 
-    forAll(patches, patchI)
+    forAll(regionToc_, regionI)
     {
-        const surfGroup& p = patches[patchI];
+        const surfRegion& reg = regionLst[regionI];
 
-        patches_[patchI] = p;
+        regionToc_[regionI] = reg;
 
-        SubList<label> subRegion(regions_, p.size(), p.start());
-        subRegion = patchI;
+        // assign sub-region Ids
+        SubList<label> subRegion(regionIds_, reg.size(), reg.start());
+        subRegion = regionI;
     }
 }
 
 
 template<class Face>
-void Foam::UnsortedMeshedSurface<Face>::setPatches
+void Foam::UnsortedMeshedSurface<Face>::setRegions
 (
     const UList<label>& sizes,
     const UList<word>& names
 )
 {
-    regions_.setSize(size());
-    patches_.setSize(sizes.size());
+    regionIds_.setSize(size());
+    regionToc_.setSize(sizes.size());
 
     label start = 0;
-    forAll(patches_, patchI)
+    forAll(regionToc_, regionI)
     {
-        patches_[patchI] = surfPatchIdentifier(names[patchI], patchI);
+        regionToc_[regionI] = surfRegionIdentifier(names[regionI], regionI);
 
-        SubList<label> subRegion(regions_, sizes[patchI], start);
-        subRegion = patchI;
+        // assign sub-region Ids
+        SubList<label> subRegion(regionIds_, sizes[regionI], start);
+        subRegion = regionI;
 
-        start += sizes[patchI];
+        start += sizes[regionI];
     }
 }
 
 
 template<class Face>
-void Foam::UnsortedMeshedSurface<Face>::setPatches
+void Foam::UnsortedMeshedSurface<Face>::setRegions
 (
     const UList<label>& sizes
 )
 {
-    regions_.setSize(size());
-    patches_.setSize(sizes.size());
+    regionIds_.setSize(size());
+    regionToc_.setSize(sizes.size());
 
     label start = 0;
-    forAll(patches_, patchI)
+    forAll(regionToc_, regionI)
     {
-        patches_[patchI] = surfPatchIdentifier
+        regionToc_[regionI] = surfRegionIdentifier
         (
-            word("patch") + ::Foam::name(patchI),
-            patchI
+            word("region") + ::Foam::name(regionI),
+            regionI
         );
 
-        SubList<label> subRegion(regions_, sizes[patchI], start);
-        subRegion = patchI;
+        // assign sub-region Ids
+        SubList<label> subRegion(regionIds_, sizes[regionI], start);
+        subRegion = regionI;
 
-        start += sizes[patchI];
+        start += sizes[regionI];
     }
 }
 
@@ -404,14 +408,14 @@ void Foam::UnsortedMeshedSurface<Face>::remapFaces
     // re-assign the region Ids
     if (&faceMap && faceMap.size())
     {
-        if (patches_.empty())
+        if (regionToc_.empty())
         {
-            onePatch();
+            oneRegion();
         }
-        else if (patches_.size() == 1)
+        else if (regionToc_.size() == 1)
         {
-            // optimized for one-patch case
-            regions_ = 0;
+            // optimized for single-region case
+            regionIds_ = 0;
         }
         else
         {
@@ -419,9 +423,9 @@ void Foam::UnsortedMeshedSurface<Face>::remapFaces
 
             forAll(faceMap, faceI)
             {
-                newRegions[faceI] = regions_[faceMap[faceI]];
+                newRegions[faceI] = regionIds_[faceMap[faceI]];
             }
-            regions_.transfer(newRegions);
+            regionIds_.transfer(newRegions);
         }
     }
 }
@@ -433,8 +437,8 @@ template<class Face>
 void Foam::UnsortedMeshedSurface<Face>::setSize(const label s)
 {
     ParentType::setSize(s);
-    // if regions extend: set with last patchId
-    regions_.setSize(s, patches_.size() - 1);
+    // if regions extend: set with last regionId
+    regionIds_.setSize(s, regionToc_.size() - 1);
 }
 
 
@@ -442,32 +446,32 @@ template<class Face>
 void Foam::UnsortedMeshedSurface<Face>::clear()
 {
     ParentType::clear();
-    regions_.clear();
-    patches_.clear();
+    regionIds_.clear();
+    regionToc_.clear();
 }
 
 
 template<class Face>
-Foam::surfGroupList Foam::UnsortedMeshedSurface<Face>::sortedRegions
+Foam::surfRegionList Foam::UnsortedMeshedSurface<Face>::sortedRegions
 (
     labelList& faceMap
 ) const
 {
-    // supply some patch names
-    Map<word> patchNames;
-    forAll(patches_, patchI)
+    // supply some region names
+    Map<word> regionNames;
+    forAll(regionToc_, regionI)
     {
-        patchNames.insert(patchI, patches_[patchI].name());
+        regionNames.insert(regionI, regionToc_[regionI].name());
     }
 
-    return sortedPatchRegions(regions_, patchNames, faceMap);
+    return sortedRegionsById(regionIds_, regionNames, faceMap);
 }
 
 
 template<class Face>
 Foam::UnsortedMeshedSurface<Face> Foam::UnsortedMeshedSurface<Face>::subsetMesh
 (
-    const UList<bool>& include,
+    const labelHashSet& include,
     labelList& pointMap,
     labelList& faceMap
 ) const
@@ -476,7 +480,7 @@ Foam::UnsortedMeshedSurface<Face> Foam::UnsortedMeshedSurface<Face>::subsetMesh
     const List<Face>&  locFaces  = this->localFaces();
 
     // Fill pointMap, faceMap
-    this->subsetMap(include, pointMap, faceMap);
+    PatchTools::subsetMap(*this, include, pointMap, faceMap);
 
     // Create compact coordinate list and forward mapping array
     pointField newPoints(pointMap.size());
@@ -503,7 +507,7 @@ Foam::UnsortedMeshedSurface<Face> Foam::UnsortedMeshedSurface<Face>::subsetMesh
             f[fp] = oldToNew[f[fp]];
         }
 
-        newRegions[faceI] = regions_[origFaceI];
+        newRegions[faceI] = regionIds_[origFaceI];
     }
     oldToNew.clear();
 
@@ -513,7 +517,7 @@ Foam::UnsortedMeshedSurface<Face> Foam::UnsortedMeshedSurface<Face>::subsetMesh
         xferMove(newPoints),
         xferMove(newFaces),
         xferMove(newRegions),
-        xferCopy(patches_)
+        xferCopy(regionToc_)
     );
 }
 
@@ -521,7 +525,7 @@ Foam::UnsortedMeshedSurface<Face> Foam::UnsortedMeshedSurface<Face>::subsetMesh
 template<class Face>
 Foam::UnsortedMeshedSurface<Face> Foam::UnsortedMeshedSurface<Face>::subsetMesh
 (
-    const UList<bool>& include
+    const labelHashSet& include
 ) const
 {
     labelList pointMap, faceMap;
@@ -541,7 +545,7 @@ void Foam::UnsortedMeshedSurface<Face>::reset
 
     if (&regionIds)
     {
-        regions_.transfer(regionIds());
+        regionIds_.transfer(regionIds());
     }
 }
 
@@ -556,9 +560,9 @@ void Foam::UnsortedMeshedSurface<Face>::transfer
     (
         xferMove(surf.storedPoints()),
         xferMove(surf.storedFaces()),
-        xferMove(surf.regions_)
+        xferMove(surf.regionIds_)
     );
-    patches_.transfer(surf.patches_);
+    regionToc_.transfer(surf.regionToc_);
 
     surf.clear();
 }
@@ -571,7 +575,7 @@ void Foam::UnsortedMeshedSurface<Face>::transfer
 )
 {
     reset(xferMove(surf.storedPoints()), xferMove(surf.storedFaces()));
-    setPatches(surf.patches());
+    setRegions(surf.regions());
     surf.clear();
 }
 
@@ -634,8 +638,8 @@ void Foam::UnsortedMeshedSurface<Face>::operator=
 
     this->storedPoints() = surf.points();
     this->storedFaces()  = surf.faces();
-    regions_ = surf.regions_;
-    patches_ = surf.patches_;
+    regionIds_ = surf.regionIds_;
+    regionToc_ = surf.regionToc_;
 }
 
 
diff --git a/src/surfMesh/UnsortedMeshedSurface/UnsortedMeshedSurface.H b/src/surfMesh/UnsortedMeshedSurface/UnsortedMeshedSurface.H
index bd692647abe38ab333e254acd05b12101c032f75..8caabb0776ac3fa868eb863741973944f9072c39 100644
--- a/src/surfMesh/UnsortedMeshedSurface/UnsortedMeshedSurface.H
+++ b/src/surfMesh/UnsortedMeshedSurface/UnsortedMeshedSurface.H
@@ -26,18 +26,18 @@ Class
     Foam::UnsortedMeshedSurface
 
 Description
-    A surface geometry mesh, in which the patch information is conveyed by
-    the 'region' associated with each face.
+    A surface geometry mesh, in which the region information is conveyed by
+    the 'regionId' associated with each face.
 
     This form of surface description is particularly useful for reading in
     surface meshes from third-party formats (eg, obj, stl, gts, etc.). It
     can also be particularly useful for situations in which the surface
     many be adjusted in an arbitrary manner without worrying about needed
-    to adjust the patch information (eg, surface refinement).
+    to adjust the region information (eg, surface refinement).
 
 See Also
-    The Foam::meshedSurface - which is organized as a surface mesh, but
-    with independent patch information.
+    The Foam::MeshedSurface - which is organized as a surface mesh, but
+    with independent region information.
 
 SourceFiles
     UnsortedMeshedSurface.C
@@ -48,8 +48,8 @@ SourceFiles
 #define UnsortedMeshedSurface_H
 
 #include "BasicMeshedSurface.H"
-#include "surfPatchIdentifierList.H"
-#include "surfGroupList.H"
+#include "surfRegionIdentifierList.H"
+#include "surfRegionList.H"
 #include "surfaceFormatsCore.H"
 #include "runTimeSelectionTables.H"
 #include "memberFunctionSelectionTables.H"
@@ -70,7 +70,7 @@ template<class Face> class MeshedSurface;
 class polyBoundaryMesh;
 
 template<class Face>
-    Ostream& operator<<(Ostream&, const UnsortedMeshedSurface<Face>&);
+Ostream& operator<<(Ostream&, const UnsortedMeshedSurface<Face>&);
 
 
 /*---------------------------------------------------------------------------*\
@@ -93,12 +93,12 @@ private:
 
     // Private Member Data
 
-        //- The regions associated with the faces
-        labelList regions_;
+        //- The region Ids associated with the faces
+        labelList regionIds_;
 
-        //- Patch information (face ordering nFaces/startFace only used
+        //- Region information (face ordering nFaces/startFace only used
         //  during reading and writing)
-        List<surfPatchIdentifier> patches_;
+        List<surfRegionIdentifier> regionToc_;
 
     // Private member functions
 
@@ -115,16 +115,16 @@ protected:
 
     // Protected Member functions
 
-        //- Return non-const access to the faces
-        List<label>& storedRegions()
+        //- Return non-const access to the region Ids
+        List<label>& storedRegionIds()
         {
-            return regions_;
+            return regionIds_;
         }
 
-        //- Return non-const access to the patches
-        List<surfPatchIdentifier>& storedPatches()
+        //- Return non-const access to the region table-of-contents
+        List<surfRegionIdentifier>& storedRegionToc()
         {
-            return patches_;
+            return regionToc_;
         }
 
         //- Set new regions from faceMap
@@ -155,23 +155,23 @@ public:
         UnsortedMeshedSurface();
 
         //- Construct by transferring components
-        //  (points, faces, region ids, patches).
+        //  (points, faces, region ids, region info).
         UnsortedMeshedSurface
         (
             const Xfer<pointField>&,
             const Xfer<List<Face> >&,
             const Xfer<List<label> >& regionIds,
-            const Xfer<surfPatchIdentifierList>&
+            const Xfer<surfRegionIdentifierList>&
         );
 
         //- Construct by transferring points, faces.
-        //  Use patch information, or set single default patch
+        //  Use region information, or set single default region
         UnsortedMeshedSurface
         (
             const Xfer<pointField>&,
             const Xfer<List<Face> >&,
-            const UList<label>& patchSizes = UList<label>::null(),
-            const UList<word>& patchNames = UList<word>::null()
+            const UList<label>& regionSizes = UList<label>::null(),
+            const UList<word>& regionNames = UList<word>::null()
         );
 
         //- Construct from a boundary mesh with local points/faces
@@ -267,34 +267,34 @@ public:
         //- Reset size of face and region list
         void setSize(const label);
 
-        //- Return const access to the regions
-        const List<label>& regions() const
+        //- Return const access to the regions ids
+        const List<label>& regionIds() const
         {
-            return regions_;
+            return regionIds_;
         }
 
-        //- Return const access to the patches
-        const List<surfPatchIdentifier>& patches() const
+        //- Return const access to the region table-of-contents
+        const List<surfRegionIdentifier>& regionToc() const
         {
-            return patches_;
+            return regionToc_;
         }
 
         //- Sort faces according to region.
-        //  Returns patch list and sets faceMap to index within faces()
-        List<surfGroup> sortedRegions(labelList& faceMap) const;
+        //  Returns a surfRegionList and sets faceMap to index within faces()
+        surfRegionList sortedRegions(labelList& faceMap) const;
 
-        //- Set regions to 0 and set a single patch
+        //- Set regions to 0 and set a single region
         //  Optionally with a specific name
-        void onePatch(const word& name = word::null);
+        void oneRegion(const word& name = word::null);
 
-        //- Set regions and patches
-        void setPatches(const surfGroupList&);
+        //- Set region ids and regions
+        void setRegions(const surfRegionList&);
 
-        //- Set regions and patches
-        void setPatches(const UList<label>& sizes, const UList<word>& names);
+        //- Set region ids and regions
+        void setRegions(const UList<label>& sizes, const UList<word>& names);
 
-        //- Set regions and patches with default names
-        void setPatches(const UList<label>& sizes);
+        //- Set region ids and set regions with default names
+        void setRegions(const UList<label>& sizes);
 
 
     // Edit
@@ -306,7 +306,7 @@ public:
         //  Returns return pointMap, faceMap from subsetMeshMap
         UnsortedMeshedSurface subsetMesh
         (
-            const UList<bool>& include,
+            const labelHashSet& include,
             labelList& pointMap,
             labelList& faceMap
         ) const;
@@ -314,7 +314,7 @@ public:
         //- Return new surface.
         UnsortedMeshedSurface subsetMesh
         (
-            const UList<bool>& include
+            const labelHashSet& include
         ) const;
 
         //- Transfer components (points, faces, region ids).
diff --git a/src/surfMesh/UnsortedMeshedSurface/UnsortedMeshedSurfaceIO.C b/src/surfMesh/UnsortedMeshedSurface/UnsortedMeshedSurfaceIO.C
index 6a05b7e3d336e9e777c506864de997325e8d2ade..70049bd020a47332c156b5a500cb5914f5a44ce2 100644
--- a/src/surfMesh/UnsortedMeshedSurface/UnsortedMeshedSurfaceIO.C
+++ b/src/surfMesh/UnsortedMeshedSurface/UnsortedMeshedSurfaceIO.C
@@ -49,18 +49,18 @@ void Foam::UnsortedMeshedSurface<Face>::write(Ostream& os) const
     const List<Face>& faceLst = this->faces();
 
     labelList faceMap;
-    List<surfGroup> patchLst = sortedRegions(faceMap);
+    surfRegionList regionLst = sortedRegions(faceMap);
 
     // just emit some information until we get a nice IOobject
     IOobject::writeBanner(os);
     os  << "// OpenFOAM Surface Format" << nl
         << "// ~~~~~~~~~~~~~~~~~~~~~~~" << nl
         << "// regions:" << nl
-        << patchLst.size() << nl << token::BEGIN_LIST << incrIndent << nl;
+        << regionLst.size() << nl << token::BEGIN_LIST << incrIndent << nl;
 
-    forAll(patchLst, patchI)
+    forAll(regionLst, regionI)
     {
-        patchLst[patchI].writeDict(os);
+        regionLst[regionI].writeDict(os);
     }
     os  << decrIndent << token::END_LIST << nl;
 
@@ -74,12 +74,12 @@ void Foam::UnsortedMeshedSurface<Face>::write(Ostream& os) const
     os  << faceLst.size() << nl << token::BEGIN_LIST << nl;
 
     label faceI = 0;
-    forAll(patchLst, patchI)
+    forAll(regionLst, regionI)
     {
         // Print all faces belonging to this region
-        const surfGroup& patch = patchLst[patchI];
+        const surfRegion& reg = regionLst[regionI];
 
-        forAll(patch, patchFaceI)
+        forAll(reg, localFaceI)
         {
             os << faceLst[faceMap[faceI++]] << nl;
         }
diff --git a/src/surfMesh/surfGroup/surfGroup.C b/src/surfMesh/surfRegion/surfRegion/surfRegion.C
similarity index 65%
rename from src/surfMesh/surfGroup/surfGroup.C
rename to src/surfMesh/surfRegion/surfRegion/surfRegion.C
index 750c238e76e254c6e3fe8d04d78e780f67223cab..8c7e3a23a3189830d8382ba0818f6237d7e4e07f 100644
--- a/src/surfMesh/surfGroup/surfGroup.C
+++ b/src/surfMesh/surfRegion/surfRegion/surfRegion.C
@@ -26,28 +26,28 @@ Description
 
 \*---------------------------------------------------------------------------*/
 
-#include "surfGroup.H"
+#include "surfRegion.H"
 #include "dictionary.H"
 #include "word.H"
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
-defineTypeNameAndDebug(Foam::surfGroup, 0);
+defineTypeNameAndDebug(Foam::surfRegion, 0);
 
 
 
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
-Foam::surfGroup::surfGroup()
+Foam::surfRegion::surfRegion()
 :
-    surfPatchIdentifier(),
+    surfRegionIdentifier(),
     size_(0),
     start_(0)
 {}
 
 
 
-Foam::surfGroup::surfGroup
+Foam::surfRegion::surfRegion
 (
     const word& name,
     const label size,
@@ -56,68 +56,68 @@ Foam::surfGroup::surfGroup
     const word& geometricType
 )
 :
-    surfPatchIdentifier(name, index, geometricType),
+    surfRegionIdentifier(name, index, geometricType),
     size_(size),
     start_(start)
 {}
 
 
-Foam::surfGroup::surfGroup(Istream& is, const label index)
+Foam::surfRegion::surfRegion(Istream& is, const label index)
 :
-    surfPatchIdentifier(),
+    surfRegionIdentifier(),
     size_(0),
     start_(0)
 {
     word name(is);
     dictionary dict(is);
 
-    operator=(surfGroup(name, dict, index));
+    operator=(surfRegion(name, dict, index));
 }
 
 
-Foam::surfGroup::surfGroup
+Foam::surfRegion::surfRegion
 (
     const word& name,
     const dictionary& dict,
     const label index
 )
 :
-    surfPatchIdentifier(name, dict, index),
+    surfRegionIdentifier(name, dict, index),
     size_(readLabel(dict.lookup("nFaces"))),
     start_(readLabel(dict.lookup("startFace")))
 {}
 
 
-Foam::surfGroup::surfGroup(const surfGroup& p)
+Foam::surfRegion::surfRegion(const surfRegion& reg)
 :
-    surfPatchIdentifier(p, p.index()),
-    size_(p.size()),
-    start_(p.start())
+    surfRegionIdentifier(reg, reg.index()),
+    size_(reg.size()),
+    start_(reg.start())
 {}
 
 
-Foam::surfGroup::surfGroup(const surfGroup& p, const label index)
+Foam::surfRegion::surfRegion(const surfRegion& reg, const label index)
 :
-    surfPatchIdentifier(p, index),
-    size_(p.size()),
-    start_(p.start())
+    surfRegionIdentifier(reg, index),
+    size_(reg.size()),
+    start_(reg.start())
 {}
 
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
-void Foam::surfGroup::write(Ostream& os) const
+void Foam::surfRegion::write(Ostream& os) const
 {
     writeDict(os);
 }
 
 
-void Foam::surfGroup::writeDict(Ostream& os) const
+void Foam::surfRegion::writeDict(Ostream& os) const
 {
     os  << indent << name() << nl
         << indent << token::BEGIN_BLOCK << incrIndent << nl;
 
-    surfPatchIdentifier::write(os);
+    surfRegionIdentifier::write(os);
     os.writeKeyword("nFaces") << size() << token::END_STATEMENT << nl;
     os.writeKeyword("startFace") << start() << token::END_STATEMENT << nl;
 
@@ -127,38 +127,38 @@ void Foam::surfGroup::writeDict(Ostream& os) const
 
 // * * * * * * * * * * * * * * * Member Operators  * * * * * * * * * * * * * //
 
-bool Foam::surfGroup::operator!=(const surfGroup& p) const
+bool Foam::surfRegion::operator!=(const surfRegion& reg) const
 {
-    return !(*this == p);
+    return !(*this == reg);
 }
 
 
-bool Foam::surfGroup::operator==(const surfGroup& p) const
+bool Foam::surfRegion::operator==(const surfRegion& reg) const
 {
     return
     (
-        (geometricType() == p.geometricType())
-     && (size() == p.size())
-     && (start() == p.start())
+        (geometricType() == reg.geometricType())
+     && (size() == reg.size())
+     && (start() == reg.start())
     );
 }
 
 
 // * * * * * * * * * * * * * * * Friend Operators  * * * * * * * * * * * * * //
 
-Foam::Istream& Foam::operator>>(Istream& is, surfGroup& p)
+Foam::Istream& Foam::operator>>(Istream& is, surfRegion& reg)
 {
-    p = surfGroup(is, 0);
+    reg = surfRegion(is, 0);
 
-    is.check("Istream& operator>>(Istream&, surfGroup&)");
+    is.check("Istream& operator>>(Istream&, surfRegion&)");
     return is;
 }
 
 
-Foam::Ostream& Foam::operator<<(Ostream& os, const surfGroup& p)
+Foam::Ostream& Foam::operator<<(Ostream& os, const surfRegion& reg)
 {
-    p.write(os);
-    os.check("Ostream& operator<<(Ostream& f, const surfGroup& p");
+    reg.write(os);
+    os.check("Ostream& operator<<(Ostream&, const surfRegion&");
     return os;
 }
 
diff --git a/src/surfMesh/surfGroup/surfGroup.H b/src/surfMesh/surfRegion/surfRegion/surfRegion.H
similarity index 69%
rename from src/surfMesh/surfGroup/surfGroup.H
rename to src/surfMesh/surfRegion/surfRegion/surfRegion.H
index 15db3809bcfb3b43b57d70e0ab1d0b44f4cf0f2b..4a5bf629510614f62cb98b67b7c79ccdba2f47e5 100644
--- a/src/surfMesh/surfGroup/surfGroup.H
+++ b/src/surfMesh/surfRegion/surfRegion/surfRegion.H
@@ -23,23 +23,24 @@ License
     Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 
 Class
-    Foam::surfGroup
+    Foam::surfRegion
 
 Description
-    'Patch' on surface as subset of triSurface.
+    A region on a meshed surface.
+    Similar in concept to a faceZone on the surface.
 
 SourceFiles
-    surfGroup.C
+    surfRegion.C
 
 \*---------------------------------------------------------------------------*/
 
-#ifndef surfGroup_H
-#define surfGroup_H
+#ifndef surfRegion_H
+#define surfRegion_H
 
 #include "word.H"
 #include "label.H"
 #include "className.H"
-#include "surfPatchIdentifier.H"
+#include "surfRegionIdentifier.H"
 #include "autoPtr.H"
 #include "dictionary.H"
 
@@ -50,18 +51,18 @@ namespace Foam
 
 // Forward declaration of friend functions and operators
 
-class surfGroup;
+class surfRegion;
 
-Istream& operator>>(Istream&, surfGroup&);
-Ostream& operator<<(Ostream&, const surfGroup&);
+Istream& operator>>(Istream&, surfRegion&);
+Ostream& operator<<(Ostream&, const surfRegion&);
 
 /*---------------------------------------------------------------------------*\
-                           Class surfGroup Declaration
+                           Class surfRegion Declaration
 \*---------------------------------------------------------------------------*/
 
-class surfGroup
+class surfRegion
 :
-    public surfPatchIdentifier
+    public surfRegionIdentifier
 {
     // Private data
 
@@ -74,16 +75,16 @@ class surfGroup
 public:
 
     //- Runtime type information
-    ClassName("surfGroup");
+    ClassName("surfRegion");
 
 
     // Constructors
 
         //- Construct null
-        surfGroup();
+        surfRegion();
 
         //- Construct from components
-        surfGroup
+        surfRegion
         (
             const word& name,
             const label size,
@@ -93,10 +94,10 @@ public:
         );
 
         //- Construct from Istream
-        surfGroup(Istream& is, const label index);
+        surfRegion(Istream& is, const label index);
 
         //- Construct from dictionary
-        surfGroup
+        surfRegion
         (
             const word& name,
             const dictionary& dict,
@@ -104,48 +105,48 @@ public:
         );
 
         //- Construct as copy
-        surfGroup(const surfGroup&);
+        surfRegion(const surfRegion&);
 
-        //- Construct from another patch, resetting the index
-        surfGroup(const surfGroup&, const label index);
+        //- Construct from another region, resetting the index
+        surfRegion(const surfRegion&, const label index);
 
         //- Return clone
-        autoPtr<surfGroup> clone() const
+        autoPtr<surfRegion> clone() const
         {
-            notImplemented("autoPtr<surfGroup> clone() const");
-            return autoPtr<surfGroup>(NULL);
+            notImplemented("autoPtr<surfRegion> clone() const");
+            return autoPtr<surfRegion>(NULL);
         }
 
-        static autoPtr<surfGroup> New(Istream& is)
+        static autoPtr<surfRegion> New(Istream& is)
         {
             word name(is);
             dictionary dict(is);
 
-            return autoPtr<surfGroup>(new surfGroup(name, dict, 0));
+            return autoPtr<surfRegion>(new surfRegion(name, dict, 0));
         }
 
 
     // Member Functions
 
-        //- Return start label of this patch in the face list
+        //- Return start label of this region in the face list
         label start() const
         {
             return start_;
         }
 
-        //- Return start label of this patch in the face list
+        //- Return start label of this region in the face list
         label& start()
         {
             return start_;
         }
 
-        //- Return size of this patch in the face list
+        //- Return size of this region in the face list
         label size() const
         {
             return size_;
         }
 
-        //- Return size of this patch in the face list
+        //- Return size of this region in the face list
         label& size()
         {
             return size_;
@@ -160,15 +161,15 @@ public:
 
     // Member Operators
 
-        bool operator!=(const surfGroup&) const;
+        bool operator!=(const surfRegion&) const;
 
         //- compare.
-        bool operator==(const surfGroup&) const;
+        bool operator==(const surfRegion&) const;
 
     // IOstream Operators
 
-        friend Istream& operator>>(Istream&, surfGroup&);
-        friend Ostream& operator<<(Ostream&, const surfGroup&);
+        friend Istream& operator>>(Istream&, surfRegion&);
+        friend Ostream& operator<<(Ostream&, const surfRegion&);
 };
 
 
diff --git a/src/surfMesh/surfGroup/surfGroupIOList.C b/src/surfMesh/surfRegion/surfRegion/surfRegionIOList.C
similarity index 72%
rename from src/surfMesh/surfGroup/surfGroupIOList.C
rename to src/surfMesh/surfRegion/surfRegion/surfRegionIOList.C
index 0adb4c684b6135a6af4d02baf0db790be7f4c058..731664ae0875ee4e182c01afc10296d06cbeb0bb 100644
--- a/src/surfMesh/surfGroup/surfGroupIOList.C
+++ b/src/surfMesh/surfRegion/surfRegion/surfRegionIOList.C
@@ -24,71 +24,71 @@ License
 
 \*---------------------------------------------------------------------------*/
 
-#include "surfGroupIOList.H"
+#include "surfRegionIOList.H"
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
-defineTypeNameAndDebug(Foam::surfGroupIOList, 0);
+defineTypeNameAndDebug(Foam::surfRegionIOList, 0);
 
 
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
-Foam::surfGroupIOList::surfGroupIOList
+Foam::surfRegionIOList::surfRegionIOList
 (
     const IOobject& io
 )
 :
-    surfGroupList(),
+    surfRegionList(),
     regIOobject(io)
 {
     Foam::string functionName =
-        "surfGroupIOList::surfGroupIOList"
+        "surfRegionIOList::surfRegionIOList"
         "(const IOobject& io)";
 
 
     if (readOpt() == IOobject::MUST_READ)
     {
-        surfGroupList& patches = *this;
+        surfRegionList& regions = *this;
 
         // read polyPatchList
         Istream& is = readStream(typeName);
 
-        PtrList<entry> patchEntries(is);
-        patches.setSize(patchEntries.size());
+        PtrList<entry> dictEntries(is);
+        regions.setSize(dictEntries.size());
 
         label faceI = 0;
-        forAll(patches, patchI)
+        forAll(regions, regionI)
         {
-            const dictionary& dict = patchEntries[patchI].dict();
+            const dictionary& dict = dictEntries[regionI].dict();
 
-            label patchSize  = readLabel(dict.lookup("nFaces"));
+            label regionSize = readLabel(dict.lookup("nFaces"));
             label startFaceI = readLabel(dict.lookup("startFace"));
 
-            patches[patchI] = surfGroup
+            regions[regionI] = surfRegion
             (
-                patchEntries[patchI].keyword(),
-                patchSize,
+                dictEntries[regionI].keyword(),
+                regionSize,
                 startFaceI,
-                patchI
+                regionI
             );
 
             word geoType;
             if (dict.readIfPresent("geometricType", geoType))
             {
-                patches[patchI].geometricType() = geoType;
+                regions[regionI].geometricType() = geoType;
             }
 
             if (startFaceI != faceI)
             {
                 FatalErrorIn(functionName)
-                    << "Patches are not ordered. Start of patch " << patchI
-                    << " does not correspond to sum of preceding patches."
+                    << "Regions are not ordered. Start of region " << regionI
+                    << " does not correspond to sum of preceding regions."
                     << endl
                     << "while reading " << io.objectPath()
                     << exit(FatalError);
             }
 
-            faceI += patchSize;
+            faceI += regionSize;
         }
 
         // Check state of IOstream
@@ -99,20 +99,20 @@ Foam::surfGroupIOList::surfGroupIOList
 }
 
 // Construct from IOObject
-Foam::surfGroupIOList::surfGroupIOList
+Foam::surfRegionIOList::surfRegionIOList
 (
     const IOobject& io,
-    const surfGroupList& patches
+    const surfRegionList& regions
 )
 :
-    surfGroupList(patches),
+    surfRegionList(regions),
     regIOobject(io)
 {}
 
 
 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
 
-Foam::surfGroupIOList::~surfGroupIOList()
+Foam::surfRegionIOList::~surfRegionIOList()
 {}
 
 
@@ -120,7 +120,7 @@ Foam::surfGroupIOList::~surfGroupIOList()
 
 
 // writeData member function required by regIOobject
-bool Foam::surfGroupIOList::writeData(Ostream& os) const
+bool Foam::surfRegionIOList::writeData(Ostream& os) const
 {
     os << *this;
     return os.good();
@@ -129,13 +129,13 @@ bool Foam::surfGroupIOList::writeData(Ostream& os) const
 
 // * * * * * * * * * * * * * * * Friend Operators  * * * * * * * * * * * * * //
 
-Foam::Ostream& Foam::operator<<(Ostream& os, const surfGroupIOList& patches)
+Foam::Ostream& Foam::operator<<(Ostream& os, const surfRegionIOList& L)
 {
-    os  << patches.size() << nl << token::BEGIN_LIST;
+    os  << L.size() << nl << token::BEGIN_LIST;
 
-    forAll(patches, patchI)
+    forAll(L, i)
     {
-        patches[patchI].writeDict(os);
+        L[i].writeDict(os);
     }
 
     os  << token::END_LIST;
diff --git a/src/surfMesh/surfGroup/surfGroupIOList.H b/src/surfMesh/surfRegion/surfRegion/surfRegionIOList.H
similarity index 79%
rename from src/surfMesh/surfGroup/surfGroupIOList.H
rename to src/surfMesh/surfRegion/surfRegion/surfRegionIOList.H
index 4fffa5edcbd630cf8f9fa71f234864ea6156db51..0e1abb2785a001a1431e4272679f8d4299f07d79 100644
--- a/src/surfMesh/surfGroup/surfGroupIOList.H
+++ b/src/surfMesh/surfRegion/surfRegion/surfRegionIOList.H
@@ -23,20 +23,20 @@ License
     Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 
 Class
-    Foam::surfGroupIOList
+    Foam::surfRegionIOList
 
 Description
-    IOobject for a surfGroupList
+    IOobject for a surfRegionList
 
 SourceFiles
-    surfGroupIOList.C
+    surfRegionIOList.C
 
 \*---------------------------------------------------------------------------*/
 
-#ifndef surfGroupIOList_H
-#define surfGroupIOList_H
+#ifndef surfRegionIOList_H
+#define surfRegionIOList_H
 
-#include "surfGroupList.H"
+#include "surfRegionList.H"
 #include "regIOobject.H"
 #include "faceList.H"
 #include "className.H"
@@ -49,12 +49,12 @@ namespace Foam
 // Forward declaration of classes
 
 /*---------------------------------------------------------------------------*\
-                           Class surfGroupIOList Declaration
+                      Class surfRegionIOList Declaration
 \*---------------------------------------------------------------------------*/
 
-class surfGroupIOList
+class surfRegionIOList
 :
-    public surfGroupList,
+    public surfRegionList,
     public regIOobject
 {
     // Private data
@@ -63,29 +63,29 @@ class surfGroupIOList
     // Private Member Functions
 
         //- Disallow default bitwise copy construct
-        surfGroupIOList(const surfGroupIOList&);
+        surfRegionIOList(const surfRegionIOList&);
 
         //- Disallow default bitwise assignment
-        void operator=(const surfGroupIOList&);
+        void operator=(const surfRegionIOList&);
 
 
 public:
 
     //- Runtime type information
-    TypeName("surfGroupIOList");
+    TypeName("surfRegionIOList");
 
 
     // Constructors
 
         //- Construct from IOobject
-        explicit surfGroupIOList(const IOobject& io);
+        explicit surfRegionIOList(const IOobject&);
 
         //- Construct from IOobject
-        surfGroupIOList(const IOobject& io, const surfGroupList&);
+        surfRegionIOList(const IOobject&, const surfRegionList&);
 
     // Destructor
 
-        ~surfGroupIOList();
+        ~surfRegionIOList();
 
 
     // Member Functions
@@ -102,7 +102,7 @@ public:
 
     // IOstream Operators
 
-        friend Ostream& operator<<(Ostream&, const surfGroupIOList&);
+        friend Ostream& operator<<(Ostream&, const surfRegionIOList&);
 };
 
 
diff --git a/src/surfMesh/surfGroup/surfGroupList.H b/src/surfMesh/surfRegion/surfRegion/surfRegionList.H
similarity index 90%
rename from src/surfMesh/surfGroup/surfGroupList.H
rename to src/surfMesh/surfRegion/surfRegion/surfRegionList.H
index 00c22611b6625f024ccf5d922d7fd49bce3643d4..a6dd1b0703b1d8e10fa2f6a73acad8444451e4bb 100644
--- a/src/surfMesh/surfGroup/surfGroupList.H
+++ b/src/surfMesh/surfRegion/surfRegion/surfRegionList.H
@@ -23,17 +23,18 @@ License
     Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 
 Typedef
-    Foam::surfGroupList
+    Foam::surfRegionList
 
 Description
 
 \*---------------------------------------------------------------------------*/
 
-#ifndef surfGroupList_H
-#define surfGroupList_H
+#ifndef surfRegionList_H
+#define surfRegionList_H
 
-#include "surfGroup.H"
+#include "surfRegion.H"
 #include "List.H"
+#include "surfRegionIdentifierList.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -42,7 +43,7 @@ namespace Foam
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-typedef List<surfGroup>  surfGroupList;
+typedef List<surfRegion>  surfRegionList;
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
diff --git a/src/surfMesh/surfPatchIdentifier/surfPatchIdentifier.C b/src/surfMesh/surfRegion/surfRegionIdentifier/surfRegionIdentifier.C
similarity index 78%
rename from src/surfMesh/surfPatchIdentifier/surfPatchIdentifier.C
rename to src/surfMesh/surfRegion/surfRegionIdentifier/surfRegionIdentifier.C
index 9b9b94a0b81028d4a7fa1551d82dd8cd08f68ad5..12ea17658f45485ae334d109c64e6ccd59c9505f 100644
--- a/src/surfMesh/surfPatchIdentifier/surfPatchIdentifier.C
+++ b/src/surfMesh/surfRegion/surfRegionIdentifier/surfRegionIdentifier.C
@@ -24,14 +24,14 @@ License
 
 \*---------------------------------------------------------------------------*/
 
-#include "surfPatchIdentifier.H"
+#include "surfRegionIdentifier.H"
 #include "dictionary.H"
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
-Foam::surfPatchIdentifier::surfPatchIdentifier()
+Foam::surfRegionIdentifier::surfRegionIdentifier()
 :
     name_(word::null),
     boundaryIndex_(0),
@@ -39,7 +39,7 @@ Foam::surfPatchIdentifier::surfPatchIdentifier()
 {}
 
 
-Foam::surfPatchIdentifier::surfPatchIdentifier
+Foam::surfRegionIdentifier::surfRegionIdentifier
 (
     const word& name,
     const label index,
@@ -52,7 +52,7 @@ Foam::surfPatchIdentifier::surfPatchIdentifier
 {}
 
 
-Foam::surfPatchIdentifier::surfPatchIdentifier
+Foam::surfRegionIdentifier::surfRegionIdentifier
 (
     const word& name,
     const dictionary& dict,
@@ -66,9 +66,9 @@ Foam::surfPatchIdentifier::surfPatchIdentifier
 }
 
 
-Foam::surfPatchIdentifier::surfPatchIdentifier
+Foam::surfRegionIdentifier::surfRegionIdentifier
 (
-    const surfPatchIdentifier& p,
+    const surfRegionIdentifier& p,
     const label index
 )
 :
@@ -79,14 +79,14 @@ Foam::surfPatchIdentifier::surfPatchIdentifier
 
 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
 
-Foam::surfPatchIdentifier::~surfPatchIdentifier()
+Foam::surfRegionIdentifier::~surfRegionIdentifier()
 {}
 
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
 
-void Foam::surfPatchIdentifier::write(Ostream& os) const
+void Foam::surfRegionIdentifier::write(Ostream& os) const
 {
     if (geometricType_.size())
     {
@@ -98,18 +98,18 @@ void Foam::surfPatchIdentifier::write(Ostream& os) const
 
 // * * * * * * * * * * * * * * * Member Operators  * * * * * * * * * * * * * //
 
-// bool Foam::surfPatchIdentifier::operator!=
+// bool Foam::surfRegionIdentifier::operator!=
 // (
-//     const surfPatchIdentifier& p
+//     const surfRegionIdentifier& p
 // ) const
 // {
 //     return !(*this == p);
 // }
 //
 //
-// bool Foam::surfPatchIdentifier::operator==
+// bool Foam::surfRegionIdentifier::operator==
 // (
-//     const surfPatchIdentifier& p
+//     const surfRegionIdentifier& p
 // ) const
 // {
 //     return geometricType() == p.geometricType() && name() == p.name();
@@ -118,7 +118,7 @@ void Foam::surfPatchIdentifier::write(Ostream& os) const
 
 // * * * * * * * * * * * * * * * Friend Operators  * * * * * * * * * * * * * //
 
-// Foam::Istream& Foam::operator>>(Istream& is, surfPatchIdentifier& p)
+// Foam::Istream& Foam::operator>>(Istream& is, surfRegionIdentifier& p)
 // {
 //     is >> p.name_ >> p.geometricType_;
 //
@@ -126,12 +126,12 @@ void Foam::surfPatchIdentifier::write(Ostream& os) const
 // }
 
 
-Foam::Ostream& Foam::operator<<(Ostream& os, const surfPatchIdentifier& p)
+Foam::Ostream& Foam::operator<<(Ostream& os, const surfRegionIdentifier& p)
 {
     p.write(os);
     os.check
     (
-        "Ostream& operator<<(Ostream&, const surfPatchIdentifier&)"
+        "Ostream& operator<<(Ostream&, const surfRegionIdentifier&)"
     );
     return os;
 }
diff --git a/src/surfMesh/surfPatchIdentifier/surfPatchIdentifier.H b/src/surfMesh/surfRegion/surfRegionIdentifier/surfRegionIdentifier.H
similarity index 67%
rename from src/surfMesh/surfPatchIdentifier/surfPatchIdentifier.H
rename to src/surfMesh/surfRegion/surfRegionIdentifier/surfRegionIdentifier.H
index 906cc1b0d9ed543d9495ff4ca1b2b739c22e0731..a4f0609665397a9e019c1ff7d9f76c87e535f7d4 100644
--- a/src/surfMesh/surfPatchIdentifier/surfPatchIdentifier.H
+++ b/src/surfMesh/surfRegion/surfRegionIdentifier/surfRegionIdentifier.H
@@ -23,19 +23,23 @@ License
     Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 
 Class
-    Foam::surfPatchIdentifier
+    Foam::surfRegionIdentifier
 
 Description
-    Like patchIdentifier but for surfaces with "geometricType" rather
-    than "physicalType".
+    An identifier for a region on a meshed surface.
+
+    Similar in concept to a faceZone on the surface, but can also have a
+    "geometricType" rather.  Despite the similarity to a 'patch' for
+    volume meshes (with a "physicalType"), the region does not have any
+    patch information per se.
 
 SourceFiles
-    surfPatchIdentifier.C
+    surfRegionIdentifier.C
 
 \*---------------------------------------------------------------------------*/
 
-#ifndef surfPatchIdentifier_H
-#define surfPatchIdentifier_H
+#ifndef surfRegionIdentifier_H
+#define surfRegionIdentifier_H
 
 #include "word.H"
 #include "label.H"
@@ -50,24 +54,24 @@ class dictionary;
 
 // Forward declaration of friend functions and operators
 
-class surfPatchIdentifier;
-Ostream& operator<<(Ostream&, const surfPatchIdentifier&);
+class surfRegionIdentifier;
+Ostream& operator<<(Ostream&, const surfRegionIdentifier&);
 
 /*---------------------------------------------------------------------------*\
-                    Class surfPatchIdentifier Declaration
+                    Class surfRegionIdentifier Declaration
 \*---------------------------------------------------------------------------*/
 
-class surfPatchIdentifier
+class surfRegionIdentifier
 {
     // Private data
 
-        //- Name of patch
+        //- Name of region
         word name_;
 
-        //- Index of patch in boundary
+        //- Index of region in surface mesh
         label boundaryIndex_;
 
-        //- Type name of patch
+        //- Type name of region
         mutable word geometricType_;
 
 public:
@@ -75,10 +79,10 @@ public:
     // Constructors
 
         //- Construct null
-        surfPatchIdentifier();
+        surfRegionIdentifier();
 
         //- Construct from components
-        surfPatchIdentifier
+        surfRegionIdentifier
         (
             const word& name,
             const label index,
@@ -87,24 +91,24 @@ public:
         );
 
         //- Construct from dictionary
-        surfPatchIdentifier
+        surfRegionIdentifier
         (
             const word& name,
             const dictionary&,
             const label index
         );
 
-        //- Construct from another patch, resetting the index
-        surfPatchIdentifier
+        //- Construct from another region identifier, resetting the index
+        surfRegionIdentifier
         (
-            const surfPatchIdentifier&,
+            const surfRegionIdentifier&,
             const label index
         );
 
 
     // Destructor
 
-        virtual ~surfPatchIdentifier();
+        virtual ~surfRegionIdentifier();
 
 
     // Member Functions
@@ -121,42 +125,42 @@ public:
             return name_;
         }
 
-        //- Return the geometric type of the patch
+        //- Return the geometric type of the region
         const word& geometricType() const
         {
             return geometricType_;
         }
 
-        //- Return the geometric type of the patch for modification
+        //- Return the geometric type of the region for modification
         word& geometricType()
         {
             return geometricType_;
         }
 
-        //- Return the index of this patch in the boundaryMesh
+        //- Return the index of this region in the surface mesh
         label index() const
         {
             return boundaryIndex_;
         }
 
-        //- Write surfPatchIdentifier as a dictionary
+        //- Write surfRegionIdentifier as a dictionary
         void write(Ostream&) const;
 
-        //- Write surfPatchIdentifier as a dictionary
+        //- Write surfRegionIdentifier as a dictionary
 //        void writeDict(Ostream&) const;
 
 
     // Member Operators
 
-//        bool operator!=(const surfPatchIdentifier&) const;
+//        bool operator!=(const surfRegionIdentifier&) const;
 //
 //        //- compare.
-//        bool operator==(const surfPatchIdentifier&) const;
+//        bool operator==(const surfRegionIdentifier&) const;
 
     // Ostream Operator
 
-        friend Ostream& operator<<(Ostream&, const surfPatchIdentifier&);
-//        friend Istream& operator>>(Istream&, surfPatchIdentifier&);
+        friend Ostream& operator<<(Ostream&, const surfRegionIdentifier&);
+//        friend Istream& operator>>(Istream&, surfRegionIdentifier&);
 };
 
 
diff --git a/src/surfMesh/surfPatchIdentifier/surfPatchIdentifierList.H b/src/surfMesh/surfRegion/surfRegionIdentifier/surfRegionIdentifierList.H
similarity index 89%
rename from src/surfMesh/surfPatchIdentifier/surfPatchIdentifierList.H
rename to src/surfMesh/surfRegion/surfRegionIdentifier/surfRegionIdentifierList.H
index fe46d76727f3d7d29bcf6dd0f77f4c431447a871..2a8efb0086a19df84ea8c8171d2e58e2eec64c72 100644
--- a/src/surfMesh/surfPatchIdentifier/surfPatchIdentifierList.H
+++ b/src/surfMesh/surfRegion/surfRegionIdentifier/surfRegionIdentifierList.H
@@ -23,16 +23,16 @@ License
     Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 
 Typedef
-    Foam::surfPatchIdentifierList
+    Foam::surfRegionIdentifierList
 
 Description
 
 \*---------------------------------------------------------------------------*/
 
-#ifndef surfPatchIdentifierList_H
-#define surfPatchIdentifierList_H
+#ifndef surfRegionIdentifierList_H
+#define surfRegionIdentifierList_H
 
-#include "surfPatchIdentifier.H"
+#include "surfRegionIdentifier.H"
 #include "List.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@@ -42,7 +42,7 @@ namespace Foam
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-typedef List<surfPatchIdentifier>  surfPatchIdentifierList;
+typedef List<surfRegionIdentifier>  surfRegionIdentifierList;
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
diff --git a/src/surfMesh/surfaceFormats/ac3d/AC3DsurfaceFormat.C b/src/surfMesh/surfaceFormats/ac3d/AC3DsurfaceFormat.C
index fdc916ed97d2f239560fff54e55559bb253fa289..1cc11e6c7a0c9a8100278d78d227b2cd075b110b 100644
--- a/src/surfMesh/surfaceFormats/ac3d/AC3DsurfaceFormat.C
+++ b/src/surfMesh/surfaceFormats/ac3d/AC3DsurfaceFormat.C
@@ -99,42 +99,42 @@ bool Foam::fileFormats::AC3DsurfaceFormat<Face>::read
             << exit(FatalError);
     }
 
-    // # of kids is the # of patches
+    // # of kids is the # of regions
     args = cueToOrDie(is, "kids");
-    label nPatches = parse<int>(args);
+    label nRegions = parse<int>(args);
 
-    // Start of vertices for object/patch
-    label patchVertOffset = 0;
+    // Start of vertices for object/region
+    label vertexOffset = 0;
 
     DynamicList<point> dynPoints;
     DynamicList<Face>  dynFaces;
-    List<word>         names(nPatches);
-    List<label>        sizes(nPatches, 0);
+    List<word>         names(nRegions);
+    List<label>        sizes(nRegions, 0);
 
-    for (label patchI = 0; patchI < nPatches; ++patchI)
+    for (label regionI = 0; regionI < nRegions; ++regionI)
     {
-        names[patchI] = word("patch") + Foam::name(patchI);
+        names[regionI] = word("region") + Foam::name(regionI);
 
-        args = cueToOrDie(is, "OBJECT", "while reading " + names[patchI]);
+        args = cueToOrDie(is, "OBJECT", "while reading " + names[regionI]);
 
-        // number of vertices for this patch
-        label  nPatchPoints = 0;
+        // number of vertices for this region
+        label  nRegionPoints = 0;
         vector location(pTraits<vector>::zero);
         // tensor rotation(I);
 
-        // Read all info for current patch
+        // Read all info for current region
         while (is.good())
         {
             // Read line and get first word. If end of file break since
-            // patch should always end with 'kids' command ?not sure.
+            // region should always end with 'kids' command ?not sure.
             if (!readCmd(is, cmd, args))
             {
                 FatalErrorIn
                 (
                     "fileFormats::AC3DsurfaceFormat::read(const fileName&)"
                 )
-                    << "Did not read up to \"kids 0\" while reading patch "
-                    << patchI << " from file " << filename
+                    << "Did not read up to \"kids 0\" while reading region "
+                    << regionI << " from file " << filename
                     << exit(FatalError);
             }
 
@@ -144,7 +144,7 @@ bool Foam::fileFormats::AC3DsurfaceFormat<Face>::read
                 string str = parse<string>(args);
                 string::stripInvalid<word>(str);
 
-                names[patchI] = str;
+                names[regionI] = str;
             }
             else if (cmd == "rot")
             {
@@ -164,7 +164,7 @@ bool Foam::fileFormats::AC3DsurfaceFormat<Face>::read
                 )
                     << "rot (rotation tensor) command not implemented"
                     << "Line:" << cmd << ' ' << args << endl
-                    << "while reading patch " << patchI << endl;
+                    << "while reading region " << regionI << endl;
             }
             else if (cmd == "loc")
             {
@@ -179,9 +179,9 @@ bool Foam::fileFormats::AC3DsurfaceFormat<Face>::read
             else if (cmd == "numvert")
             {
                 // numvert  %d
-                nPatchPoints = parse<int>(args);
+                nRegionPoints = parse<int>(args);
 
-                for (label vertI = 0; vertI < nPatchPoints; ++vertI)
+                for (label vertI = 0; vertI < nRegionPoints; ++vertI)
                 {
                     is.getLine(line);
                     IStringStream lineStream(line);
@@ -202,8 +202,8 @@ bool Foam::fileFormats::AC3DsurfaceFormat<Face>::read
                 {
                     static string errorMsg =
                         string(" while reading face ")
-                            + Foam::name(faceI) + " on patch "
-                            + Foam::name(patchI)
+                            + Foam::name(faceI) + " on region "
+                            + Foam::name(regionI)
                             + " from file " + filename;
 
                     cueToOrDie(is, "SURF", errorMsg);
@@ -216,7 +216,7 @@ bool Foam::fileFormats::AC3DsurfaceFormat<Face>::read
                     forAll(verts, vertI)
                     {
                         is.getLine(line);
-                        verts[vertI] = parse<int>(line) + patchVertOffset;
+                        verts[vertI] = parse<int>(line) + vertexOffset;
                     }
 
                     UList<label>& f = static_cast<UList<label>&>(verts);
@@ -230,23 +230,23 @@ bool Foam::fileFormats::AC3DsurfaceFormat<Face>::read
                             label fp2 = (fp1 + 1) % f.size();
 
                             dynFaces.append(triFace(f[0], f[fp1], f[fp2]));
-                            sizes[patchI]++;
+                            sizes[regionI]++;
                         }
                     }
                     else
                     {
                         dynFaces.append(Face(f));
-                        sizes[patchI]++;
+                        sizes[regionI]++;
                     }
                 }
 
-                // Done the current patch.
+                // Done the current region.
                 // Increment the offset vertices are stored at
-                patchVertOffset += nPatchPoints;
+                vertexOffset += nRegionPoints;
             }
             else if (cmd == "kids")
             {
-                // 'kids' denotes the end of the current patch.
+                // 'kids' denotes the end of the current region.
                 label nKids = parse<int>(args);
 
                 if (nKids != 0)
@@ -257,11 +257,11 @@ bool Foam::fileFormats::AC3DsurfaceFormat<Face>::read
                     )
                         << "Can only read objects without kids."
                         << " Encountered " << nKids << " kids when"
-                        << " reading patch " << patchI
+                        << " reading region " << regionI
                         << exit(FatalError);
                 }
 
-                // Done reading current patch
+                // Done reading current region
                 break;
             }
         }
@@ -271,8 +271,8 @@ bool Foam::fileFormats::AC3DsurfaceFormat<Face>::read
     this->storedPoints().transfer(dynPoints);
     this->storedFaces().transfer(dynFaces);
 
-    // add patches, culling empty groups
-    this->addPatches(sizes, names, true);
+    // add regions, culling empty ones
+    this->addRegions(sizes, names, true);
     this->stitchFaces(SMALL);
     return true;
 }
@@ -287,16 +287,16 @@ void Foam::fileFormats::AC3DsurfaceFormat<Face>::write
 {
     const pointField& pointLst = surf.points();
     const List<Face>& faceLst = surf.faces();
-    const List<surfGroup>& patchLst = surf.patches();
+    const List<surfRegion>& regionLst = surf.regions();
 
-    writeHeader(os, patchLst);
+    writeHeader(os, regionLst);
 
-    forAll(patchLst, patchI)
+    forAll(regionLst, regionI)
     {
-        const surfGroup& p = patchLst[patchI];
+        const surfRegion& reg = regionLst[regionI];
 
         os  << "OBJECT poly" << nl
-            << "name \"" << p.name() << '"' << endl;
+            << "name \"" << reg.name() << '"' << endl;
 
         // Temporary PrimitivePatch to calculate compact points & faces
         // use 'UList' to avoid allocations!
@@ -317,12 +317,12 @@ void Foam::fileFormats::AC3DsurfaceFormat<Face>::write
 
         os << "numsurf " << patch.localFaces().size() << endl;
 
-        forAll(patch.localFaces(), faceI)
+        forAll(patch.localFaces(), localFaceI)
         {
-            const Face& f = patch.localFaces()[faceI];
+            const Face& f = patch.localFaces()[localFaceI];
 
             os  << "SURF 0x20" << nl          // polygon
-                << "mat " << patchI << nl
+                << "mat " << regionI << nl
                 << "refs " << f.size() << nl;
 
             forAll(f, fp)
@@ -344,25 +344,25 @@ void Foam::fileFormats::AC3DsurfaceFormat<Face>::write
 )
 {
     labelList faceMap;
-    List<surfGroup> patchLst = surf.sortedRegions(faceMap);
+    List<surfRegion> regionLst = surf.sortedRegions(faceMap);
 
-    writeHeader(os, patchLst);
+    writeHeader(os, regionLst);
 
     label faceIndex = 0;
-    forAll(patchLst, patchI)
+    forAll(regionLst, regionI)
     {
-        const surfGroup& p = patchLst[patchI];
+        const surfRegion& reg = regionLst[regionI];
 
         os  << "OBJECT poly" << nl
-            << "name \"" << p.name() << '"' << endl;
+            << "name \"" << reg.name() << '"' << endl;
 
-        // Create patch with only patch faces included for ease of addressing
-        boolList include(surf.size(), false);
+        // Create region with only region faces included for ease of addressing
+        labelHashSet include(surf.size());
 
-        forAll(p, patchFaceI)
+        forAll(reg, localFaceI)
         {
             const label faceI = faceMap[faceIndex++];
-            include[faceI] = true;
+            include.insert(faceI);
         }
 
         UnsortedMeshedSurface<Face> subm = surf.subsetMesh(include);
@@ -379,12 +379,12 @@ void Foam::fileFormats::AC3DsurfaceFormat<Face>::write
 
         os << "numsurf " << subm.localFaces().size() << endl;
 
-        forAll(subm.localFaces(), faceI)
+        forAll(subm.localFaces(), localFaceI)
         {
-            const Face& f = subm.localFaces()[faceI];
+            const Face& f = subm.localFaces()[localFaceI];
 
             os  << "SURF 0x20" << nl          // polygon
-                << "mat " << patchI << nl
+                << "mat " << regionI << nl
                 << "refs " << f.size() << nl;
 
             forAll(f, fp)
diff --git a/src/surfMesh/surfaceFormats/ac3d/AC3DsurfaceFormat.H b/src/surfMesh/surfaceFormats/ac3d/AC3DsurfaceFormat.H
index 120235eedf1e50f0388d6ca03b8a6f9dd94c6011..3ccfeeda23565863dcc679350edd4cf20d1a2cef 100644
--- a/src/surfMesh/surfaceFormats/ac3d/AC3DsurfaceFormat.H
+++ b/src/surfMesh/surfaceFormats/ac3d/AC3DsurfaceFormat.H
@@ -31,7 +31,7 @@ Description
     http://www.inivis.com/ac3d/man/ac3dfileformat.html
 
 Note
-   The faces are already organized as patches.
+   The faces are already organized as regions.
    The output is always sorted by regions.
 
 SourceFiles
diff --git a/src/surfMesh/surfaceFormats/ac3d/AC3DsurfaceFormatCore.C b/src/surfMesh/surfaceFormats/ac3d/AC3DsurfaceFormatCore.C
index e47ec990d6b8ce0d16475be8c935873a6f71c6ba..e31c59f796f3085fd514bd3e772cbb633b0c5778 100644
--- a/src/surfMesh/surfaceFormats/ac3d/AC3DsurfaceFormatCore.C
+++ b/src/surfMesh/surfaceFormats/ac3d/AC3DsurfaceFormatCore.C
@@ -116,12 +116,12 @@ Foam::string Foam::fileFormats::AC3DsurfaceFormatCore::cueToOrDie
 void Foam::fileFormats::AC3DsurfaceFormatCore::writeHeader
 (
     Ostream& os,
-    const List<surfGroup>& patchLst
+    const UList<surfRegion>& regionLst
 )
 {
-    // Write with patches as separate objects under "world" object.
+    // Write with regions as separate objects under "world" object.
     // Header is taken over from sample file.
-    // Defines separate materials for all patches. Recycle colours.
+    // Defines separate materials for all regions. Recycle colours.
 
     // Define 8 standard colours as r,g,b components
     static scalar colourMap[] =
@@ -139,14 +139,12 @@ void Foam::fileFormats::AC3DsurfaceFormatCore::writeHeader
     // Write header. Define materials.
     os  << "AC3Db" << nl;
 
-    forAll(patchLst, patchI)
+    forAll(regionLst, regionI)
     {
-        const word& pName = patchLst[patchI].name();
-
-        label colourI = patchI % 8;
+        label colourI = regionI % 8;
         label colourCompI = 3 * colourI;
 
-        os  << "MATERIAL \"" << pName << "Mat\" rgb "
+        os  << "MATERIAL \"" << regionLst[regionI].name() << "Mat\" rgb "
             << colourMap[colourCompI] << ' ' << colourMap[colourCompI+1]
             << ' ' << colourMap[colourCompI+2]
             << "  amb 0.2 0.2 0.2  emis 0 0 0  spec 0.5 0.5 0.5  shi 10"
@@ -155,7 +153,7 @@ void Foam::fileFormats::AC3DsurfaceFormatCore::writeHeader
     }
 
     os  << "OBJECT world" << nl
-        << "kids " << patchLst.size() << endl;
+        << "kids " << regionLst.size() << endl;
 }
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
diff --git a/src/surfMesh/surfaceFormats/ac3d/AC3DsurfaceFormatCore.H b/src/surfMesh/surfaceFormats/ac3d/AC3DsurfaceFormatCore.H
index d8ecc3c0ee6fe28165e5ee6084ce4e5a446394ab..574f7da1f5d920f36dcb4cc5979b45ef9095d934 100644
--- a/src/surfMesh/surfaceFormats/ac3d/AC3DsurfaceFormatCore.H
+++ b/src/surfMesh/surfaceFormats/ac3d/AC3DsurfaceFormatCore.H
@@ -49,7 +49,7 @@ namespace fileFormats
 {
 
 /*---------------------------------------------------------------------------*\
-                      Class AC3DfileFormat Declaration
+                       Class AC3DfileFormat Declaration
 \*---------------------------------------------------------------------------*/
 
 class AC3DsurfaceFormatCore
@@ -77,7 +77,7 @@ protected:
     );
 
     //- Write header with materials
-    static void writeHeader(Ostream&, const List<surfGroup>&);
+    static void writeHeader(Ostream&, const UList<surfRegion>&);
 
 };
 
diff --git a/src/surfMesh/surfaceFormats/ftr/FTRsurfaceFormat.C b/src/surfMesh/surfaceFormats/ftr/FTRsurfaceFormat.C
index aaa00d9a1861a16303992ca3658a28acaecfee13..3840bfaea711ce25a7ec72c02aece3d96323d75e 100644
--- a/src/surfMesh/surfaceFormats/ftr/FTRsurfaceFormat.C
+++ b/src/surfMesh/surfaceFormats/ftr/FTRsurfaceFormat.C
@@ -63,40 +63,40 @@ bool Foam::fileFormats::FTRsurfaceFormat<Face>::read
             << exit(FatalError);
     }
 
-    List<ftrPatch> readPatches(is);
+    List<ftrPatch> ftrPatches(is);
 
     // read points directly
     is >> this->storedPoints();
 
-    // read faces with keys
-    List<Keyed<triFace> > readFaces(is);
+    // faces read with keys
+    List<Keyed<triFace> > facesRead(is);
 
-    List<Face>  faceLst(readFaces.size());
-    List<label> regionLst(readFaces.size());
+    List<Face>  faceLst(facesRead.size());
+    List<label> regionIds(facesRead.size());
 
     // disentangle faces/keys - already triangulated
-    forAll(readFaces, faceI)
+    forAll(facesRead, faceI)
     {
         // unfortunately cannot transfer to save memory
-        faceLst[faceI]   = readFaces[faceI];
-        regionLst[faceI] = readFaces[faceI].key();
+        faceLst[faceI]   = facesRead[faceI];
+        regionIds[faceI] = facesRead[faceI].key();
     }
 
     this->storedFaces().transfer(faceLst);
-    this->storedRegions().transfer(regionLst);
+    this->storedRegionIds().transfer(regionIds);
 
-    // cast ftrPatch into new form
-    List<surfPatchIdentifier> newPatches(readPatches.size());
-    forAll(newPatches, patchI)
+    // change ftrPatch into surfRegionIdentifier
+    List<surfRegionIdentifier> newRegions(ftrPatches.size());
+    forAll(newRegions, regionI)
     {
-        newPatches[patchI] = surfPatchIdentifier
+        newRegions[regionI] = surfRegionIdentifier
         (
-            readPatches[patchI].name(),
-            patchI
+            ftrPatches[regionI].name(),
+            regionI
         );
     }
 
-    this->storedPatches().transfer(newPatches);
+    this->storedRegionToc().transfer(newRegions);
     return true;
 }
 
diff --git a/src/surfMesh/surfaceFormats/gts/GTSsurfaceFormat.C b/src/surfMesh/surfaceFormats/gts/GTSsurfaceFormat.C
index bac8cda4e3cfaf4b38c77b09310e1d264c476be2..ab3cf269f235e90a8fc4ad56fec6ee32c0ce2d19 100644
--- a/src/surfMesh/surfaceFormats/gts/GTSsurfaceFormat.C
+++ b/src/surfMesh/surfaceFormats/gts/GTSsurfaceFormat.C
@@ -80,13 +80,13 @@ bool Foam::fileFormats::GTSsurfaceFormat<Face>::read
 
 
     // write directly into the lists:
-    pointField& pointLst = this->storedPoints();
-    List<Face>& faceLst  = this->storedFaces();
-    List<label>& regionLst = this->storedRegions();
+    pointField&  pointLst  = this->storedPoints();
+    List<Face>&  faceLst   = this->storedFaces();
+    List<label>& regionIds = this->storedRegionIds();
 
     pointLst.setSize(nPoints);
     faceLst.setSize(nElems);
-    regionLst.setSize(nElems);
+    regionIds.setSize(nElems);
 
     // Read points
     forAll(pointLst, pointI)
@@ -118,7 +118,7 @@ bool Foam::fileFormats::GTSsurfaceFormat<Face>::read
 
 
     // Read triangles. Convert references to edges into pointlabels
-    label maxPatch = 0;
+    label maxRegion = 0;
     forAll(faceLst, faceI)
     {
         label e0Label, e1Label, e2Label;
@@ -138,9 +138,9 @@ bool Foam::fileFormats::GTSsurfaceFormat<Face>::read
                 if (!lineStream.bad())
                 {
                     regionI = num;
-                    if (maxPatch < regionI)
+                    if (maxRegion < regionI)
                     {
-                        maxPatch = regionI;
+                        maxRegion = regionI;
                     }
                 }
             }
@@ -202,21 +202,21 @@ bool Foam::fileFormats::GTSsurfaceFormat<Face>::read
         }
 
         faceLst[faceI] = triFace(e0Far, common01, e1Far);
-        regionLst[faceI] = regionI;
+        regionIds[faceI] = regionI;
     }
 
 
-    List<surfPatchIdentifier> newPatches(maxPatch+1);
-    forAll(newPatches, patchI)
+    List<surfRegionIdentifier> newRegions(maxRegion+1);
+    forAll(newRegions, regionI)
     {
-        newPatches[patchI] = surfPatchIdentifier
+        newRegions[regionI] = surfRegionIdentifier
         (
-            "patch" + ::Foam::name(patchI),
-            patchI
+            "region" + ::Foam::name(regionI),
+            regionI
         );
     }
 
-    this->storedPatches().transfer(newPatches);
+    this->storedRegionToc().transfer(newRegions);
     return true;
 }
 
@@ -230,13 +230,12 @@ void Foam::fileFormats::GTSsurfaceFormat<Face>::write
 {
     const pointField& pointLst = surf.points();
     const List<Face>& faceLst  = surf.faces();
-    const List<surfGroup>& patchLst = surf.patches();
+    const List<surfRegion>& regionLst = surf.regions();
 
 
     // check if output triangulation would be required
     // It is too annoying to triangulate on-the-fly
     // just issue a warning and get out
-    //
     if (!surf.isTri())
     {
         label nNonTris = 0;
@@ -261,14 +260,14 @@ void Foam::fileFormats::GTSsurfaceFormat<Face>::write
         }
     }
 
-    // Write header, print patch names as comment
+    // Write header, print region names as comment
     os  << "# GTS file" << nl
         << "# Regions:" << nl;
 
-    forAll(patchLst, patchI)
+    forAll(regionLst, regionI)
     {
-        os  << "#     " << patchI << "    "
-            << patchLst[patchI].name() << nl;
+        os  << "#     " << regionI << "    "
+            << regionLst[regionI].name() << nl;
     }
     os  << "#" << endl;
 
@@ -301,18 +300,18 @@ void Foam::fileFormats::GTSsurfaceFormat<Face>::write
     const labelListList& faceEs = surf.faceEdges();
 
     label faceIndex = 0;
-    forAll(patchLst, patchI)
+    forAll(regionLst, regionI)
     {
-        const surfGroup& patch = patchLst[patchI];
+        const surfRegion& reg = regionLst[regionI];
 
-        forAll(patch, patchFaceI)
+        forAll(reg, localFaceI)
         {
             const labelList& fEdges = faceEs[faceIndex++];
 
             os  << fEdges[0] + 1 << ' '
                 << fEdges[1] + 1 << ' '
                 << fEdges[2] + 1 << ' '
-                << patchI << endl;
+                << regionI << endl;
         }
     }
 }
@@ -327,8 +326,8 @@ void Foam::fileFormats::GTSsurfaceFormat<Face>::write
 {
     const pointField& pointLst   = surf.points();
     const List<Face>& faceLst    = surf.faces();
-    const List<label>& regionLst = surf.regions();
-    const List<surfPatchIdentifier>& patchInfo = surf.patches();
+    const List<label>& regionIds = surf.regionIds();
+    const List<surfRegionIdentifier>& regionToc = surf.regionToc();
 
     // check if output triangulation would be required
     // It is too annoying to triangulate on-the-fly
@@ -357,18 +356,14 @@ void Foam::fileFormats::GTSsurfaceFormat<Face>::write
         }
     }
 
-    labelList faceMap;
-    List<surfGroup> patchLst = surf.sortedRegions(faceMap);
-
-
-    // Write header, print patch names as comment
+    // Write header, print region names as comment
     os  << "# GTS file" << nl
         << "# Regions:" << nl;
 
-    forAll(patchInfo, patchI)
+    forAll(regionToc, regionI)
     {
-        os  << "#     " << patchI << "    "
-            << patchInfo[patchI].name() << nl;
+        os  << "#     " << regionI << "    "
+            << regionToc[regionI].name() << nl;
     }
     os  << "#" << endl;
 
@@ -409,7 +404,7 @@ void Foam::fileFormats::GTSsurfaceFormat<Face>::write
         os  << fEdges[0] + 1 << ' '
             << fEdges[1] + 1 << ' '
             << fEdges[2] + 1 << ' '
-            << regionLst[faceI] << endl;
+            << regionIds[faceI] << endl;
     }
 }
 
diff --git a/src/surfMesh/surfaceFormats/gts/GTSsurfaceFormat.H b/src/surfMesh/surfaceFormats/gts/GTSsurfaceFormat.H
index 081a92c8f6903185dee9f624c51fb23e5d65f39f..62d218274d5757685198dd10e2cbb2ddbf4d05a0 100644
--- a/src/surfMesh/surfaceFormats/gts/GTSsurfaceFormat.H
+++ b/src/surfMesh/surfaceFormats/gts/GTSsurfaceFormat.H
@@ -27,7 +27,7 @@ Class
 
 Description
     Provide a means of reading/writing GTS format.
-    The output is never sorted by patch.
+    The output is never sorted by region.
 
 SourceFiles
     GTSsurfaceFormat.C
diff --git a/src/surfMesh/surfaceFormats/nas/NASsurfaceFormat.C b/src/surfMesh/surfaceFormats/nas/NASsurfaceFormat.C
index 7f4cad25dc411d0159b1b0fe2b65062d21b49dd1..6a4da1ec8066cda65a28dc714bb2e24ae88f357a 100644
--- a/src/surfMesh/surfaceFormats/nas/NASsurfaceFormat.C
+++ b/src/surfMesh/surfaceFormats/nas/NASsurfaceFormat.C
@@ -85,7 +85,7 @@ bool Foam::fileFormats::NASsurfaceFormat<Face>::read
     // Ansa tags. Denoted by $ANSA_NAME.
     // These will appear just before the first use of a type.
     // We read them and store the PSHELL types which are used to name
-    // the patches.
+    // the regions.
     label ansaId = -1;
     word  ansaType, ansaName;
 
@@ -211,7 +211,7 @@ bool Foam::fileFormats::NASsurfaceFormat<Face>::read
             fTri[1] = readLabel(IStringStream(line.substr(32,8))());
             fTri[2] = readLabel(IStringStream(line.substr(40,8))());
 
-            // Convert groupID into patchID
+            // Convert groupID into regionId
             Map<label>::const_iterator fnd = lookup.find(groupId);
             if (fnd != lookup.end())
             {
@@ -227,7 +227,7 @@ bool Foam::fileFormats::NASsurfaceFormat<Face>::read
                 regionI = dynSizes.size();
                 lookup.insert(groupId, regionI);
                 dynSizes.append(0);
-                // Info<< "patch" << regionI << " => group " << groupId <<endl;
+                // Info<< "region" << regionI << " => group " << groupId <<endl;
             }
 
             dynFaces.append(fTri);
@@ -245,7 +245,7 @@ bool Foam::fileFormats::NASsurfaceFormat<Face>::read
             fQuad[2] = readLabel(IStringStream(line.substr(40,8))());
             fQuad[3] = readLabel(IStringStream(line.substr(48,8))());
 
-            // Convert groupID into patchID
+            // Convert groupID into regionId
             Map<label>::const_iterator fnd = lookup.find(groupId);
             if (fnd != lookup.end())
             {
@@ -261,7 +261,7 @@ bool Foam::fileFormats::NASsurfaceFormat<Face>::read
                 regionI = dynSizes.size();
                 lookup.insert(groupId, regionI);
                 dynSizes.append(0);
-                // Info<< "patch" << regionI << " => group " << groupId <<endl;
+                // Info<< "region" << regionI << " => group " << groupId <<endl;
             }
 
 
@@ -322,7 +322,7 @@ bool Foam::fileFormats::NASsurfaceFormat<Face>::read
         }
         else if (cmd == "PSHELL")
         {
-            // pshell type for patch names with the Ansa extension
+            // pshell type for region names with the Ansa extension
             label groupId = readLabel(IStringStream(line.substr(8,8))());
 
             if (groupId == ansaId && ansaType == "PSHELL")
@@ -370,29 +370,29 @@ bool Foam::fileFormats::NASsurfaceFormat<Face>::read
     mapPointId.clear();
 
 
-    // create default patch names, or from ANSA/Hypermesh information
+    // create default region names, or from ANSA/Hypermesh information
     List<word> names(dynSizes.size());
     forAllConstIter(Map<label>, lookup, iter)
     {
-        const label patchI = iter();
-        const label groupI = iter.key();
+        const label regionI = iter();
+        const label groupI  = iter.key();
 
         Map<word>::const_iterator fnd = nameLookup.find(groupI);
         if (fnd != nameLookup.end())
         {
-            names[patchI] = fnd();
+            names[regionI] = fnd();
         }
         else
         {
-            names[patchI] = word("patch") + ::Foam::name(patchI);
+            names[regionI] = word("region") + ::Foam::name(regionI);
         }
     }
 
 
     sortFacesAndStore(dynFaces.xfer(), dynRegions.xfer(), sorted);
 
-    // add patches, culling empty groups
-    this->addPatches(dynSizes, names, true);
+    // add regions, culling empty ones
+    this->addRegions(dynSizes, names, true);
 
     return true;
 }
diff --git a/src/surfMesh/surfaceFormats/nas/NASsurfaceFormat.H b/src/surfMesh/surfaceFormats/nas/NASsurfaceFormat.H
index 19cd25f5f536b2a49a385dd8ad0930fb3784c8f4..c4b9c0b2edd37583b5b872c5a90e466fb1044a04 100644
--- a/src/surfMesh/surfaceFormats/nas/NASsurfaceFormat.H
+++ b/src/surfMesh/surfaceFormats/nas/NASsurfaceFormat.H
@@ -29,7 +29,7 @@ Description
     Nastran surface reader.
 
     - Uses the Ansa "$ANSA_NAME" or the Hypermesh "$HMNAME COMP" extensions
-      to obtain patch names.
+      to obtain region names.
     - Handles Nastran short and long formats, but not free format.
     - Properly handles the Nastran compact floating point notation: \n
     @verbatim
diff --git a/src/surfMesh/surfaceFormats/nas/NASsurfaceFormatCore.C b/src/surfMesh/surfaceFormats/nas/NASsurfaceFormatCore.C
index 2700b16deb9ef186e255fdec515ff6a7426e6dc4..568f902e3153341b750ee0726292a8755e01926a 100644
--- a/src/surfMesh/surfaceFormats/nas/NASsurfaceFormatCore.C
+++ b/src/surfMesh/surfaceFormats/nas/NASsurfaceFormatCore.C
@@ -49,7 +49,7 @@ Foam::scalar Foam::fileFormats::NASsurfaceFormatCore::parseNASCoord
         {
             exponent = -exponent;
         }
-        return mantissa*pow(10, exponent);
+        return mantissa * pow(10, exponent);
     }
     else
     {
diff --git a/src/surfMesh/surfaceFormats/obj/OBJsurfaceFormat.C b/src/surfMesh/surfaceFormats/obj/OBJsurfaceFormat.C
index 93bee6e7379a8423a768782ee5fa95495f6d4b46..bdebe7e0d5f7e44474d875404897b077aabe0e46 100644
--- a/src/surfMesh/surfaceFormats/obj/OBJsurfaceFormat.C
+++ b/src/surfMesh/surfaceFormats/obj/OBJsurfaceFormat.C
@@ -75,10 +75,10 @@ bool Foam::fileFormats::OBJsurfaceFormat<Face>::read
     DynamicList<label> dynSizes;
     HashTable<label>   lookup;
 
-    // place faces without a group in patch0
+    // place faces without a group in region0
     label regionI = 0;
-    lookup.insert("patch0", regionI);
-    dynNames.append("patch0");
+    lookup.insert("region0", regionI);
+    dynNames.append("region0");
     dynSizes.append(0);
 
     while (is.good())
@@ -204,8 +204,8 @@ bool Foam::fileFormats::OBJsurfaceFormat<Face>::read
 
     sortFacesAndStore(dynFaces.xfer(), dynRegions.xfer(), sorted);
 
-    // add patches, culling empty groups
-    this->addPatches(dynSizes, dynNames, true);
+    // add regions, culling empty ones
+    this->addRegions(dynSizes, dynNames, true);
     return true;
 }
 
@@ -218,18 +218,18 @@ void Foam::fileFormats::OBJsurfaceFormat<Face>::write
 )
 {
     const List<Face>& faceLst = surf.faces();
-    const List<surfGroup>& patchLst = surf.patches();
+    const List<surfRegion>& regionLst = surf.regions();
 
-    writeHeader(os, surf.points(), faceLst.size(), patchLst);
+    writeHeader(os, surf.points(), faceLst.size(), regionLst);
 
     label faceIndex = 0;
-    forAll(patchLst, patchI)
+    forAll(regionLst, regionI)
     {
-        const surfGroup& patch = patchLst[patchI];
+        const surfRegion& reg = regionLst[regionI];
 
-        os << "g " << patch.name() << endl;
+        os << "g " << reg.name() << endl;
 
-        forAll(patch, patchFaceI)
+        forAll(reg, localFaceI)
         {
             const Face& f = faceLst[faceIndex++];
 
@@ -255,19 +255,19 @@ void Foam::fileFormats::OBJsurfaceFormat<Face>::write
     const List<Face>& faceLst = surf.faces();
 
     labelList faceMap;
-    List<surfGroup> patchLst = surf.sortedRegions(faceMap);
+    List<surfRegion> regionLst = surf.sortedRegions(faceMap);
 
-    writeHeader(os, surf.points(), faceLst.size(), patchLst);
+    writeHeader(os, surf.points(), faceLst.size(), regionLst);
 
     label faceIndex = 0;
-    forAll(patchLst, patchI)
+    forAll(regionLst, regionI)
     {
         // Print all faces belonging to this region
-        const surfGroup& patch = patchLst[patchI];
+        const surfRegion& reg = regionLst[regionI];
 
-        os << "g " << patch.name() << endl;
+        os << "g " << reg.name() << endl;
 
-        forAll(patch, patchFaceI)
+        forAll(reg, localFaceI)
         {
             const Face& f = faceLst[faceMap[faceIndex++]];
 
diff --git a/src/surfMesh/surfaceFormats/obj/OBJsurfaceFormat.H b/src/surfMesh/surfaceFormats/obj/OBJsurfaceFormat.H
index 12afceff7d65e1ae8da245a9ec5908411e7d0faf..87d573c1c5e5a126501303e49c6e1f7c928812ef 100644
--- a/src/surfMesh/surfaceFormats/obj/OBJsurfaceFormat.H
+++ b/src/surfMesh/surfaceFormats/obj/OBJsurfaceFormat.H
@@ -63,14 +63,6 @@ class OBJsurfaceFormat
 {
     // Private Member Functions
 
-        static void writeHead
-        (
-            Ostream&,
-            const pointField&,
-            const List<Face>&,
-            const List<surfGroup>&
-        );
-
         //- Disallow default bitwise copy construct
         OBJsurfaceFormat(const OBJsurfaceFormat<Face>&);
 
diff --git a/src/surfMesh/surfaceFormats/obj/OBJsurfaceFormatCore.C b/src/surfMesh/surfaceFormats/obj/OBJsurfaceFormatCore.C
index f35c53980806075f9da1587dc592417c60c0eb80..24c538de3ed85684e36fcc16b99054c7f08c4439 100644
--- a/src/surfMesh/surfaceFormats/obj/OBJsurfaceFormatCore.C
+++ b/src/surfMesh/surfaceFormats/obj/OBJsurfaceFormatCore.C
@@ -36,7 +36,7 @@ void Foam::fileFormats::OBJsurfaceFormatCore::writeHeader
     Ostream& os,
     const pointField& pointLst,
     const label nFaces,
-    const List<surfGroup>& patchLst
+    const UList<surfRegion>& regionLst
 )
 {
     os  << "# Wavefront OBJ file written " << clock::dateTime().c_str() << nl
@@ -44,13 +44,13 @@ void Foam::fileFormats::OBJsurfaceFormatCore::writeHeader
         << nl
         << "# points : " << pointLst.size() << nl
         << "# faces  : " << nFaces << nl
-        << "# patches: " << patchLst.size() << nl;
+        << "# region : " << regionLst.size() << nl;
 
-    // Print patch names as comment
-    forAll(patchLst, patchI)
+    // Print region names as comment
+    forAll(regionLst, regionI)
     {
-        os  << "#   " << patchI << "  " << patchLst[patchI].name()
-            << "  (nFaces: " << patchLst[patchI].size() << ")" << nl;
+        os  << "#   " << regionI << "  " << regionLst[regionI].name()
+            << "  (nFaces: " << regionLst[regionI].size() << ")" << nl;
     }
 
     os  << nl
diff --git a/src/surfMesh/surfaceFormats/obj/OBJsurfaceFormatCore.H b/src/surfMesh/surfaceFormats/obj/OBJsurfaceFormatCore.H
index 539b1b690301a4c3215a2787808174ba5ed59539..00869aaaf3bc383a89b9c8dd2a9c96a543a1b5d8 100644
--- a/src/surfMesh/surfaceFormats/obj/OBJsurfaceFormatCore.H
+++ b/src/surfMesh/surfaceFormats/obj/OBJsurfaceFormatCore.H
@@ -63,7 +63,7 @@ protected:
         Ostream&,
         const pointField&,
         const label nFaces,
-        const List<surfGroup>&
+        const UList<surfRegion>&
     );
 
 };
diff --git a/src/surfMesh/surfaceFormats/off/OFFsurfaceFormat.C b/src/surfMesh/surfaceFormats/off/OFFsurfaceFormat.C
index c679edc963cae3815ae05f69242365296292096b..0d1f6ee5aa63383923b8a5301e39cfcfc3b7076e 100644
--- a/src/surfMesh/surfaceFormats/off/OFFsurfaceFormat.C
+++ b/src/surfMesh/surfaceFormats/off/OFFsurfaceFormat.C
@@ -146,7 +146,7 @@ bool Foam::fileFormats::OFFsurfaceFormat<Face>::read
     reset(pointLst.xfer(), dynFaces.xfer());
 
     // no region information
-    this->onePatch();
+    this->oneRegion();
     return true;
 }
 
@@ -161,16 +161,16 @@ void Foam::fileFormats::OFFsurfaceFormat<Face>::write
     const List<Face>& faceLst = surf.faces();
 
     labelList faceMap;
-    List<surfGroup> patchLst = surf.sortedRegions(faceMap);
+    List<surfRegion> regionLst = surf.sortedRegions(faceMap);
 
-    writeHeader(os, surf.points(), faceLst.size(), patchLst);
+    writeHeader(os, surf.points(), faceLst.size(), regionLst);
 
     label faceIndex = 0;
-    forAll(patchLst, patchI)
+    forAll(regionLst, regionI)
     {
-        os << "# <patch name=\"" << patchLst[patchI].name() << "\">" << endl;
+        os << "# <region name=\"" << regionLst[regionI].name() << "\">" << endl;
 
-        forAll(patchLst[patchI], patchFaceI)
+        forAll(regionLst[regionI], localFaceI)
         {
             const Face& f = faceLst[faceMap[faceIndex++]];
 
@@ -181,9 +181,9 @@ void Foam::fileFormats::OFFsurfaceFormat<Face>::write
             }
 
             // add optional region information
-            os << ' ' << patchI << endl;
+            os << ' ' << regionI << endl;
         }
-        os << "# </patch>" << endl;
+        os << "# </region>" << endl;
     }
     os << "# </faces>" << endl;
 }
@@ -197,16 +197,16 @@ void Foam::fileFormats::OFFsurfaceFormat<Face>::write
 )
 {
     const List<Face>& faceLst = surf.faces();
-    const List<surfGroup>& patchLst = surf.patches();
+    const List<surfRegion>& regionLst = surf.regions();
 
-    writeHeader(os, surf.points(), faceLst.size(), patchLst);
+    writeHeader(os, surf.points(), faceLst.size(), regionLst);
 
     label faceIndex = 0;
-    forAll(patchLst, patchI)
+    forAll(regionLst, regionI)
     {
-        os << "# <patch name=\"" << patchLst[patchI].name() << "\">" << endl;
+        os << "# <region name=\"" << regionLst[regionI].name() << "\">" << endl;
 
-        forAll(patchLst[patchI], patchFaceI)
+        forAll(regionLst[regionI], localFaceI)
         {
             const Face& f = faceLst[faceIndex++];
 
@@ -217,9 +217,9 @@ void Foam::fileFormats::OFFsurfaceFormat<Face>::write
             }
 
             // add optional region information
-            os << ' ' << patchI << endl;
+            os << ' ' << regionI << endl;
         }
-        os << "# </patch>" << endl;
+        os << "# </region>" << endl;
     }
     os << "# </faces>" << endl;
 }
diff --git a/src/surfMesh/surfaceFormats/off/OFFsurfaceFormat.H b/src/surfMesh/surfaceFormats/off/OFFsurfaceFormat.H
index 28eda006ef083989c7e233a90270c6e5a97189de..89e82aee62d10fda41bf7d6bc01ef638bd0d80d6 100644
--- a/src/surfMesh/surfaceFormats/off/OFFsurfaceFormat.H
+++ b/src/surfMesh/surfaceFormats/off/OFFsurfaceFormat.H
@@ -71,14 +71,6 @@ class OFFsurfaceFormat
 {
     // Private Member Functions
 
-        static void writeHead
-        (
-            Ostream&,
-            const pointField&,
-            const List<Face>&,
-            const List<surfGroup>&
-        );
-
         //- Disallow default bitwise copy construct
         OFFsurfaceFormat(const OFFsurfaceFormat&);
 
diff --git a/src/surfMesh/surfaceFormats/off/OFFsurfaceFormatCore.C b/src/surfMesh/surfaceFormats/off/OFFsurfaceFormatCore.C
index 5e4097993601d9e95248ca5cb3f35f8b6d15e4d7..b3866bdbc72a3a0f5833e370d46414a344a25e0c 100644
--- a/src/surfMesh/surfaceFormats/off/OFFsurfaceFormatCore.C
+++ b/src/surfMesh/surfaceFormats/off/OFFsurfaceFormatCore.C
@@ -34,7 +34,7 @@ void Foam::fileFormats::OFFsurfaceFormatCore::writeHeader
     Ostream& os,
     const pointField& pointLst,
     const label nFaces,
-    const List<surfGroup>& patchLst
+    const UList<surfRegion>& regionLst
 )
 {
     // Write header
@@ -43,13 +43,13 @@ void Foam::fileFormats::OFFsurfaceFormatCore::writeHeader
         << nl
         << "# points : " << pointLst.size() << nl
         << "# faces  : " << nFaces << nl
-        << "# patches: " << patchLst.size() << nl;
+        << "# regions: " << regionLst.size() << nl;
 
-    // Print patch names as comment
-    forAll(patchLst, patchI)
+    // Print region names as comment
+    forAll(regionLst, regionI)
     {
-        os  << "#   " << patchI << "  " << patchLst[patchI].name()
-            << "  (nFaces: " << patchLst[patchI].size() << ")" << nl;
+        os  << "#   " << regionI << "  " << regionLst[regionI].name()
+            << "  (nFaces: " << regionLst[regionI].size() << ")" << nl;
     }
 
     os  << nl
diff --git a/src/surfMesh/surfaceFormats/off/OFFsurfaceFormatCore.H b/src/surfMesh/surfaceFormats/off/OFFsurfaceFormatCore.H
index 6a847ecc04d40ed93d49b37383833f4a1ef60fe8..8706d1fb94784424a48760efbefd8810d58b7dda 100644
--- a/src/surfMesh/surfaceFormats/off/OFFsurfaceFormatCore.H
+++ b/src/surfMesh/surfaceFormats/off/OFFsurfaceFormatCore.H
@@ -63,7 +63,7 @@ protected:
         Ostream&,
         const pointField&,
         const label nFaces,
-        const List<surfGroup>&
+        const UList<surfRegion>&
     );
 
 };
diff --git a/src/surfMesh/surfaceFormats/smesh/SMESHsurfaceFormat.C b/src/surfMesh/surfaceFormats/smesh/SMESHsurfaceFormat.C
index 2e6cd1d6783b859ef767542af5ec11d002ab735d..f256d308fc6f96744cdd1e37ccc492a220c40e14 100644
--- a/src/surfMesh/surfaceFormats/smesh/SMESHsurfaceFormat.C
+++ b/src/surfMesh/surfaceFormats/smesh/SMESHsurfaceFormat.C
@@ -46,14 +46,14 @@ void Foam::fileFormats::SMESHsurfaceFormat<Face>::write
 )
 {
     const List<Face>& faceLst = surf.faces();
-    const List<surfGroup>& patchLst = surf.patches();
+    const List<surfRegion>& regionLst = surf.regions();
 
     writeHeader(os, surf.points(), faceLst.size());
 
     label faceIndex = 0;
-    forAll(patchLst, patchI)
+    forAll(regionLst, regionI)
     {
-        forAll(patchLst[patchI], patchFaceI)
+        forAll(regionLst[regionI], localFaceI)
         {
             const Face& f = faceLst[faceIndex++];
 
@@ -62,7 +62,7 @@ void Foam::fileFormats::SMESHsurfaceFormat<Face>::write
             {
                 os << ' ' << f[fp];
             }
-            os << ' ' << patchI << endl;
+            os << ' ' << regionI << endl;
         }
     }
 
@@ -82,12 +82,12 @@ void Foam::fileFormats::SMESHsurfaceFormat<Face>::write
     writeHeader(os, surf.points(), faceLst.size());
 
     labelList faceMap;
-    List<surfGroup> patchLst = surf.sortedRegions(faceMap);
+    List<surfRegion> regionLst = surf.sortedRegions(faceMap);
 
     label faceIndex = 0;
-    forAll(patchLst, patchI)
+    forAll(regionLst, regionI)
     {
-        forAll(patchLst[patchI], patchFaceI)
+        forAll(regionLst[regionI], localFaceI)
         {
             const Face& f = faceLst[faceMap[faceIndex++]];
 
@@ -96,7 +96,7 @@ void Foam::fileFormats::SMESHsurfaceFormat<Face>::write
             {
                 os << ' ' << f[fp];
             }
-            os << ' ' << patchI << endl;
+            os << ' ' << regionI << endl;
         }
     }
 
diff --git a/src/surfMesh/surfaceFormats/starcd/STARCDsurfaceFormat.C b/src/surfMesh/surfaceFormats/starcd/STARCDsurfaceFormat.C
index f6aa76f30781f5efafb89334c966080db773bf79..05b82cd1f42c240f128a41e8487a8d475c274d7c 100644
--- a/src/surfMesh/surfaceFormats/starcd/STARCDsurfaceFormat.C
+++ b/src/surfMesh/surfaceFormats/starcd/STARCDsurfaceFormat.C
@@ -40,8 +40,7 @@ inline void Foam::fileFormats::STARCDsurfaceFormat<Face>::writeShell
     const label cellTableId
 )
 {
-    os
-        << cellId                    // includes 1 offset
+    os  << cellId                    // includes 1 offset
         << " " << starcdShellShape_  // 3(shell) shape
         << " " << f.size()
         << " " << cellTableId
@@ -54,9 +53,7 @@ inline void Foam::fileFormats::STARCDsurfaceFormat<Face>::writeShell
     {
         if ((count % 8) == 0)
         {
-            os
-                << nl
-                << "  " << cellId;
+            os  << nl << "  " << cellId;
         }
         os  << " " << f[fp] + 1;
         count++;
@@ -160,7 +157,7 @@ bool Foam::fileFormats::STARCDsurfaceFormat<Face>::read
 
         if (typeId == starcdShellType_)
         {
-            // Convert groupID into patchID
+            // Convert groupID into regionID
             Map<label>::const_iterator fnd = lookup.find(cellTableId);
             if (fnd != lookup.end())
             {
@@ -214,8 +211,8 @@ bool Foam::fileFormats::STARCDsurfaceFormat<Face>::read
 
     sortFacesAndStore(dynFaces.xfer(), dynRegions.xfer(), sorted);
 
-    // add patches, culling empty groups
-    this->addPatches(dynSizes, dynNames, true);
+    // add regions, culling empty ones
+    this->addRegions(dynSizes, dynNames, true);
     return true;
 }
 
@@ -234,17 +231,17 @@ void Foam::fileFormats::STARCDsurfaceFormat<Face>::write
     writeHeader(os, "CELL");
 
     const List<Face>& faceLst = surf.faces();
-    const List<surfGroup>& patchLst = surf.patches();
+    const List<surfRegion>& regionLst = surf.regions();
 
     label faceIndex = 0;
-    forAll(patchLst, patchI)
+    forAll(regionLst, regionI)
     {
-        const surfGroup& patch = patchLst[patchI];
+        const surfRegion& reg = regionLst[regionI];
 
-        forAll(patch, patchFaceI)
+        forAll(reg, localFaceI)
         {
             const Face& f = faceLst[faceIndex++];
-            writeShell(os, f, faceIndex, patchI + 1);
+            writeShell(os, f, faceIndex, regionI + 1);
         }
     }
 
@@ -254,7 +251,7 @@ void Foam::fileFormats::STARCDsurfaceFormat<Face>::write
         OFstream(baseName + ".inp")(),
         surf.points(),
         surf.size(),
-        patchLst
+        regionLst
     );
 }
 
@@ -275,17 +272,17 @@ void Foam::fileFormats::STARCDsurfaceFormat<Face>::write
 
     const List<Face>& faceLst = surf.faces();
     labelList faceMap;
-    List<surfGroup> patchLst = surf.sortedRegions(faceMap);
+    List<surfRegion> regionLst = surf.sortedRegions(faceMap);
 
     label faceIndex = 0;
-    forAll(patchLst, patchI)
+    forAll(regionLst, regionI)
     {
-        const surfGroup& patch = patchLst[patchI];
+        const surfRegion& reg = regionLst[regionI];
 
-        forAll(patch, patchFaceI)
+        forAll(reg, localFaceI)
         {
             const Face& f = faceLst[faceMap[faceIndex++]];
-            writeShell(os, f, faceIndex, patchI + 1);
+            writeShell(os, f, faceIndex, regionI + 1);
         }
     }
 
@@ -295,7 +292,7 @@ void Foam::fileFormats::STARCDsurfaceFormat<Face>::write
         OFstream(baseName + ".inp")(),
         surf.points(),
         surf.size(),
-        patchLst
+        regionLst
     );
 }
 
diff --git a/src/surfMesh/surfaceFormats/starcd/STARCDsurfaceFormatCore.C b/src/surfMesh/surfaceFormats/starcd/STARCDsurfaceFormatCore.C
index c8b413f662c021ea0e64e9d0a0a1cda6c5f8214a..b7691491e21cf4c97f6ac59b9acdc6bbfce9a3bf 100644
--- a/src/surfMesh/surfaceFormats/starcd/STARCDsurfaceFormatCore.C
+++ b/src/surfMesh/surfaceFormats/starcd/STARCDsurfaceFormatCore.C
@@ -166,7 +166,7 @@ void Foam::fileFormats::STARCDsurfaceFormatCore::writeCase
     Ostream& os,
     const pointField& pointLst,
     const label nFaces,
-    const List<surfGroup>& patchLst
+    const UList<surfRegion>& regionLst
 )
 {
     word caseName = os.name().lessExt().name();
@@ -176,10 +176,11 @@ void Foam::fileFormats::STARCDsurfaceFormatCore::writeCase
         << "! case " << caseName << nl
         << "! ------------------------------" << nl;
 
-    forAll(patchLst, patchI)
+    forAll(regionLst, regionI)
     {
-        os  << "ctable " << patchI + 1 << " shell" << nl
-            << "ctname " << patchI + 1 << " " << patchLst[patchI].name() << nl;
+        os  << "ctable " << regionI + 1 << " shell" << nl
+            << "ctname " << regionI + 1 << " "
+            << regionLst[regionI].name() << nl;
     }
 
     os  << "! ------------------------------" << nl
diff --git a/src/surfMesh/surfaceFormats/starcd/STARCDsurfaceFormatCore.H b/src/surfMesh/surfaceFormats/starcd/STARCDsurfaceFormatCore.H
index 3ee15cc67b46e64844673b81e7daf3bed7355379..481cedd1c2bbe9c4cc8a535bf778520d6fe77d99 100644
--- a/src/surfMesh/surfaceFormats/starcd/STARCDsurfaceFormatCore.H
+++ b/src/surfMesh/surfaceFormats/starcd/STARCDsurfaceFormatCore.H
@@ -70,7 +70,7 @@ protected:
         Ostream&,
         const pointField&,
         const label nFaces,
-        const List<surfGroup>&
+        const UList<surfRegion>&
     );
 
 };
diff --git a/src/surfMesh/surfaceFormats/stl/STLsurfaceFormat.C b/src/surfMesh/surfaceFormats/stl/STLsurfaceFormat.C
index d60e49180c0e1c527481971b5844df425104617c..919f6d98e2fd082c7811394b70463128c631fdaa 100644
--- a/src/surfMesh/surfaceFormats/stl/STLsurfaceFormat.C
+++ b/src/surfMesh/surfaceFormats/stl/STLsurfaceFormat.C
@@ -70,7 +70,7 @@ inline void Foam::fileFormats::STLsurfaceFormat<Face>::writeShell
     const pointField& pointLst,
     const Face& f,
     const vector& norm,
-    const label patchI
+    const label regionI
 )
 {
     // simple triangulation about f[0].
@@ -86,7 +86,7 @@ inline void Foam::fileFormats::STLsurfaceFormat<Face>::writeShell
             p0,
             pointLst[f[fp1]],
             pointLst[f[fp2]],
-            patchI
+            regionI
         );
 
         stlTri.write(os);
@@ -104,22 +104,22 @@ void Foam::fileFormats::STLsurfaceFormat<Face>::writeASCII
 {
     const pointField& pointLst = surf.points();
     const List<Face>& faceLst = surf.faces();
-    const List<surfGroup>& patchLst = surf.patches();
+    const List<surfRegion>& regionLst = surf.regions();
     const vectorField& normLst = surf.faceNormals();
 
     label faceIndex = 0;
-    forAll(patchLst, patchI)
+    forAll(regionLst, regionI)
     {
         // Print all faces belonging to this region
-        const surfGroup& patch = patchLst[patchI];
+        const surfRegion& reg = regionLst[regionI];
 
-        os << "solid " << patch.name() << endl;
-        forAll(patch, patchFaceI)
+        os << "solid " << reg.name() << endl;
+        forAll(reg, localFaceI)
         {
             const label faceI = faceIndex++;
             writeShell(os, pointLst, faceLst[faceI], normLst[faceI]);
         }
-        os << "endsolid " << patch.name() << endl;
+        os << "endsolid " << reg.name() << endl;
     }
 }
 
@@ -136,34 +136,34 @@ void Foam::fileFormats::STLsurfaceFormat<Face>::writeASCII
     const List<Face>& faceLst  = surf.faces();
     const vectorField& normLst = surf.faceNormals();
 
-    if (surf.patches().size() == 1)
+    if (surf.regionToc().size() == 1)
     {
         // a single region - we can skip sorting
-        os << "solid " << surf.patches()[0].name() << endl;
+        os << "solid " << surf.regionToc()[0].name() << endl;
         forAll(faceLst, faceI)
         {
             writeShell(os, pointLst, faceLst[faceI], normLst[faceI]);
         }
-        os << "endsolid " << surf.patches()[0].name() << endl;
+        os << "endsolid " << surf.regionToc()[0].name() << endl;
     }
    else
    {
         labelList faceMap;
-        List<surfGroup> patchLst = surf.sortedRegions(faceMap);
+        List<surfRegion> regionLst = surf.sortedRegions(faceMap);
 
         label faceIndex = 0;
-        forAll(patchLst, patchI)
+        forAll(regionLst, regionI)
         {
             // Print all faces belonging to this region
-            const surfGroup& patch = patchLst[patchI];
+            const surfRegion& reg = regionLst[regionI];
 
-            os << "solid " << patch.name() << endl;
-            forAll(patch, patchFaceI)
+            os << "solid " << reg.name() << endl;
+            forAll(reg, localFaceI)
             {
                 const label faceI = faceMap[faceIndex++];
                 writeShell(os, pointLst, faceLst[faceI], normLst[faceI]);
             }
-            os << "endsolid " << patch.name() << endl;
+            os << "endsolid " << reg.name() << endl;
         }
    }
 }
@@ -177,10 +177,10 @@ void Foam::fileFormats::STLsurfaceFormat<Face>::writeBINARY
     const MeshedSurface<Face>& surf
 )
 {
-    const pointField& pointLst = surf.points();
-    const List<Face>& faceLst  = surf.faces();
+    const pointField&  pointLst = surf.points();
+    const List<Face>&  faceLst  = surf.faces();
     const vectorField& normLst = surf.faceNormals();
-    const List<surfGroup>& patchLst = surf.patches();
+    const List<surfRegion>& regionLst = surf.regions();
 
     unsigned int nTris = 0;
     if (surf.isTri())
@@ -200,9 +200,9 @@ void Foam::fileFormats::STLsurfaceFormat<Face>::writeBINARY
     STLsurfaceFormatCore::writeHeaderBINARY(os, nTris);
 
     label faceIndex = 0;
-    forAll(patchLst, patchI)
+    forAll(regionLst, regionI)
     {
-        forAll(patchLst[patchI], patchFaceI)
+        forAll(regionLst[regionI], regionFaceI)
         {
             writeShell
             (
@@ -210,7 +210,7 @@ void Foam::fileFormats::STLsurfaceFormat<Face>::writeBINARY
                 pointLst,
                 faceLst[faceIndex],
                 normLst[faceIndex],
-                patchI
+                regionI
             );
 
             ++faceIndex;
@@ -227,9 +227,9 @@ void Foam::fileFormats::STLsurfaceFormat<Face>::writeBINARY
     const UnsortedMeshedSurface<Face>& surf
 )
 {
-    const pointField& pointLst = surf.points();
+    const pointField&  pointLst = surf.points();
     const List<Face>&  faceLst = surf.faces();
-    const List<label>& regionLst = surf.regions();
+    const List<label>& regionIds = surf.regionIds();
     const vectorField& normLst = surf.faceNormals();
 
     unsigned int nTris = 0;
@@ -258,7 +258,7 @@ void Foam::fileFormats::STLsurfaceFormat<Face>::writeBINARY
             pointLst,
             faceLst[faceI],
             normLst[faceI],
-            regionLst[faceI]
+            regionIds[faceI]
         );
     }
 }
@@ -295,10 +295,10 @@ bool Foam::fileFormats::STLsurfaceFormat<Face>::read
     // retrieve the original region information
     List<word>  names(reader.names().xfer());
     List<label> sizes(reader.sizes().xfer());
-    List<label> regions(reader.regions().xfer());
+    List<label> regionIds(reader.regionIds().xfer());
 
     // generate the (sorted) faces
-    List<Face> faceLst(regions.size());
+    List<Face> faceLst(regionIds.size());
 
     if (reader.sorted())
     {
@@ -314,7 +314,7 @@ bool Foam::fileFormats::STLsurfaceFormat<Face>::read
         // unsorted - determine the sorted order:
         // avoid SortableList since we discard the main list anyhow
         List<label> faceMap;
-        sortedOrder(regions, faceMap);
+        sortedOrder(regionIds, faceMap);
 
         // generate sorted faces
         forAll(faceMap, faceI)
@@ -323,18 +323,18 @@ bool Foam::fileFormats::STLsurfaceFormat<Face>::read
             faceLst[faceI] = triFace(startPt, startPt+1, startPt+2);
         }
     }
-    regions.clear();
+    regionIds.clear();
 
     // transfer:
     this->storedFaces().transfer(faceLst);
 
     if (names.size())
     {
-        this->addPatches(sizes, names);
+        this->addRegions(sizes, names);
     }
     else
     {
-        this->addPatches(sizes);
+        this->addRegions(sizes);
     }
 
     this->stitchFaces(SMALL);
diff --git a/src/surfMesh/surfaceFormats/stl/STLsurfaceFormat.H b/src/surfMesh/surfaceFormats/stl/STLsurfaceFormat.H
index 0321f67acf286552f2e0acf646efb39c2d812df7..ebeeb7eafe417ee7e414ecd20007a75f6cd2ff34 100644
--- a/src/surfMesh/surfaceFormats/stl/STLsurfaceFormat.H
+++ b/src/surfMesh/surfaceFormats/stl/STLsurfaceFormat.H
@@ -79,7 +79,7 @@ class STLsurfaceFormat
             const pointField&,
             const Face&,
             const vector&,
-            const label patchI
+            const label regionI
         );
 
 
diff --git a/src/surfMesh/surfaceFormats/stl/STLsurfaceFormatASCII.L b/src/surfMesh/surfaceFormats/stl/STLsurfaceFormatASCII.L
index 520c22e0d5ed6d2e2bb911ae7cc3ff9c1186e7d0..14779d4d6155549eb26dc84bb6b2001bd68a5954 100644
--- a/src/surfMesh/surfaceFormats/stl/STLsurfaceFormatASCII.L
+++ b/src/surfMesh/surfaceFormats/stl/STLsurfaceFormatASCII.L
@@ -417,7 +417,7 @@ bool Foam::fileFormats::STLsurfaceFormatCore::readASCII
 
     // transfer to normal lists
     points_.transfer(lexer.points());
-    regions_.transfer(lexer.facets());
+    regionIds_.transfer(lexer.facets());
     names_.transfer(lexer.names());
     sizes_.transfer(lexer.sizes());
 
diff --git a/src/surfMesh/surfaceFormats/stl/STLsurfaceFormatCore.C b/src/surfMesh/surfaceFormats/stl/STLsurfaceFormatCore.C
index 087f7d0d88a48f9b76cf19a7725774c8b25bdd8f..afe81aebac385ac2796d20eeb9280b2cf9a146b8 100644
--- a/src/surfMesh/surfaceFormats/stl/STLsurfaceFormatCore.C
+++ b/src/surfMesh/surfaceFormats/stl/STLsurfaceFormatCore.C
@@ -142,14 +142,14 @@ bool Foam::fileFormats::STLsurfaceFormatCore::readBINARY
 #endif
 
     points_.setSize(3*nTris);
-    regions_.setSize(nTris);
+    regionIds_.setSize(nTris);
 
     Map<label> lookup;
     DynamicList<label> dynSizes;
 
     label ptI = 0;
     label regionI = -1;
-    forAll(regions_, faceI)
+    forAll(regionIds_, faceI)
     {
         // Read an STL triangle
         STLtriangle stlTri(is);
@@ -179,7 +179,7 @@ bool Foam::fileFormats::STLsurfaceFormatCore::readBINARY
             dynSizes.append(0);
         }
 
-        regions_[faceI] = regionI;
+        regionIds_[faceI] = regionI;
         dynSizes[regionI]++;
 
 #ifdef DEBUG_STLBINARY
@@ -220,7 +220,7 @@ Foam::fileFormats::STLsurfaceFormatCore::STLsurfaceFormatCore
 :
     sorted_(true),
     points_(0),
-    regions_(0),
+    regionIds_(0),
     names_(0),
     sizes_(0)
 {
diff --git a/src/surfMesh/surfaceFormats/stl/STLsurfaceFormatCore.H b/src/surfMesh/surfaceFormats/stl/STLsurfaceFormatCore.H
index f5463161e6612b68a50d880748b8cde985ee8371..56607fa0a04aad991b3e2852ecef46088e28a4e1 100644
--- a/src/surfMesh/surfaceFormats/stl/STLsurfaceFormatCore.H
+++ b/src/surfMesh/surfaceFormats/stl/STLsurfaceFormatCore.H
@@ -65,7 +65,7 @@ class STLsurfaceFormatCore
         pointField points_;
 
         //- The regions associated with the faces
-        List<label> regions_;
+        List<label> regionIds_;
 
         //- The solid names, in the order of their first appearance
         List<word> names_;
@@ -124,7 +124,7 @@ public:
         {
             sorted_ = true;
             points_.clear();
-            regions_.clear();
+            regionIds_.clear();
             names_.clear();
             sizes_.clear();
         }
@@ -135,10 +135,10 @@ public:
             return points_;
         }
 
-        //- Return full access to the regions
-        List<label>& regions()
+        //- Return full access to the regionIds
+        List<label>& regionIds()
         {
-            return regions_;
+            return regionIds_;
         }
 
         //- The list of solid names in the order of their first appearance
diff --git a/src/surfMesh/surfaceFormats/surfaceFormatsCore.C b/src/surfMesh/surfaceFormats/surfaceFormatsCore.C
index 252773be6b689b0c06d4023824f6c0a72d175cc3..3552d4f4046308955a3833efd017f1f6b5a3b681 100644
--- a/src/surfMesh/surfaceFormats/surfaceFormatsCore.C
+++ b/src/surfMesh/surfaceFormats/surfaceFormatsCore.C
@@ -37,7 +37,6 @@ Foam::word Foam::fileFormats::surfaceFormatsCore::nativeExt("ofs");
 
 // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
 
-//- Check if file extension corresponds to 'native' surface format
 bool
 Foam::fileFormats::surfaceFormatsCore::isNative(const word& ext)
 {
@@ -75,11 +74,11 @@ Foam::fileFormats::surfaceFormatsCore::findMeshInstance
     // closest to and lower than current time
 
     instantList ts = d.times();
-    label i;
+    label instanceI;
 
-    for (i=ts.size()-1; i>=0; i--)
+    for (instanceI = ts.size()-1; instanceI >= 0; --instanceI)
     {
-        if (ts[i].value() <= d.timeOutputValue())
+        if (ts[instanceI].value() <= d.timeOutputValue())
         {
             break;
         }
@@ -88,13 +87,13 @@ Foam::fileFormats::surfaceFormatsCore::findMeshInstance
     // Noting that the current directory has already been searched
     // for mesh data, start searching from the previously stored time directory
 
-    if (i>=0)
+    if (instanceI >= 0)
     {
-        for (label j=i; j>=0; j--)
+        for (label i = instanceI; i >= 0; --i)
         {
-            if (file(d.path()/ts[j].name()/subdirName/foamName))
+            if (file(d.path()/ts[i].name()/subdirName/foamName))
             {
-                return ts[j].name();
+                return ts[i].name();
             }
         }
     }
@@ -116,11 +115,11 @@ Foam::fileFormats::surfaceFormatsCore::findMeshName
     // closest to and lower than current time
 
     instantList ts = d.times();
-    label i;
+    label instanceI;
 
-    for (i=ts.size()-1; i>=0; i--)
+    for (instanceI = ts.size()-1; instanceI >= 0; --instanceI)
     {
-        if (ts[i].value() <= d.timeOutputValue())
+        if (ts[instanceI].value() <= d.timeOutputValue())
         {
             break;
         }
@@ -129,11 +128,11 @@ Foam::fileFormats::surfaceFormatsCore::findMeshName
     // Noting that the current directory has already been searched
     // for mesh data, start searching from the previously stored time directory
 
-    if (i>=0)
+    if (instanceI >= 0)
     {
-        for (label j=i; j>=0; j--)
+        for (label i = instanceI; i >= 0; --i)
         {
-            fileName testName(d.path()/ts[j].name()/subdirName/foamName);
+            fileName testName(d.path()/ts[i].name()/subdirName/foamName);
 
             if (file(testName))
             {
@@ -166,14 +165,14 @@ Foam::fileFormats::surfaceFormatsCore::findMeshName
 }
 
 
-// Returns patch info.
-// Sets faceMap to the indexing according to patch numbers.
-// Patch numbers start at 0.
-Foam::surfGroupList
-Foam::fileFormats::surfaceFormatsCore::sortedPatchRegions
+// Returns region info.
+// Sets faceMap to the indexing according to region numbers.
+// Region numbers start at 0.
+Foam::surfRegionList
+Foam::fileFormats::surfaceFormatsCore::sortedRegionsById
 (
-    const UList<label>& regionLst,
-    const Map<word>& patchNames,
+    const UList<label>& regionIds,
+    const Map<word>& regionNames,
     labelList& faceMap
 )
 {
@@ -185,11 +184,11 @@ Foam::fileFormats::surfaceFormatsCore::sortedPatchRegions
     // Assuming that we have relatively fewer regions compared to the
     // number of items, just do it ourselves
 
-    // step 1: get region sizes and store (regionId => patchI)
+    // step 1: get region sizes and store (regionId => regionI)
     Map<label> lookup;
-    forAll(regionLst, faceI)
+    forAll(regionIds, faceI)
     {
-        const label regId = regionLst[faceI];
+        const label regId = regionIds[faceI];
 
         Map<label>::iterator fnd = lookup.find(regId);
         if (fnd != lookup.end())
@@ -202,52 +201,53 @@ Foam::fileFormats::surfaceFormatsCore::sortedPatchRegions
         }
     }
 
-    // step 2: assign start/size (and name) to the newPatches
-    // re-use the lookup to map (regionId => patchI)
-    surfGroupList patchLst(lookup.size());
+    // step 2: assign start/size (and name) to the newRegions
+    // re-use the lookup to map (regionId => regionI)
+    surfRegionList regionLst(lookup.size());
     label start = 0;
-    label patchI = 0;
+    label regionI = 0;
     forAllIter(Map<label>, lookup, iter)
     {
         label regId = iter.key();
 
         word name;
-        Map<word>::const_iterator fnd = patchNames.find(regId);
-        if (fnd != patchNames.end())
+        Map<word>::const_iterator fnd = regionNames.find(regId);
+        if (fnd != regionNames.end())
         {
             name = fnd();
         }
         else
         {
-            name = word("patch") + ::Foam::name(patchI);
+            name = word("region") + ::Foam::name(regionI);
         }
 
-        patchLst[patchI] = surfGroup
+        regionLst[regionI] = surfRegion
         (
             name,
             0,           // initialize with zero size
             start,
-            patchI
+            regionI
         );
 
-        // increment the start for the next patch
-        // and save the (regionId => patchI) mapping
+        // increment the start for the next region
+        // and save the (regionId => regionI) mapping
         start += iter();
-        iter() = patchI++;
+        iter() = regionI++;
     }
 
 
     // step 3: build the re-ordering
-    faceMap.setSize(regionLst.size());
+    faceMap.setSize(regionIds.size());
 
-    forAll(regionLst, faceI)
+    forAll(regionIds, faceI)
     {
-        label patchI = lookup[regionLst[faceI]];
-        faceMap[faceI] = patchLst[patchI].start() + patchLst[patchI].size()++;
+        label regionI = lookup[regionIds[faceI]];
+        faceMap[faceI] =
+            regionLst[regionI].start() + regionLst[regionI].size()++;
     }
 
     // with reordered faces registered in faceMap
-    return patchLst;
+    return regionLst;
 }
 
 
diff --git a/src/surfMesh/surfaceFormats/surfaceFormatsCore.H b/src/surfMesh/surfaceFormats/surfaceFormatsCore.H
index ee578fd41556b0002506598be351cb443963a613..46ee062bdf64936df76d1581cc8068cc55e7a6b6 100644
--- a/src/surfMesh/surfaceFormats/surfaceFormatsCore.H
+++ b/src/surfMesh/surfaceFormats/surfaceFormatsCore.H
@@ -36,11 +36,11 @@ SourceFiles
 #ifndef surfaceFormatsCore_H
 #define surfaceFormatsCore_H
 
-#include "surfPatchIdentifierList.H"
-#include "surfGroupList.H"
-#include "labelList.H"
 #include "Map.H"
 #include "HashSet.H"
+#include "labelList.H"
+#include "surfRegionList.H"
+#include "surfRegionIdentifierList.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -69,6 +69,7 @@ public:
     static word meshSubDir;
 
     //- The file extension corresponding to 'native' surface format
+    //  Normally "ofs" (mnemonic: OF = OpenFOAM, S = Surface)
     static word nativeExt;
 
     // Static Member Functions
@@ -91,12 +92,12 @@ public:
         //- Name of UnsortedMeshedSurface directory to use.
         static fileName findMeshName(const Time&);
 
-        //- Determine the sort order from the region list.
-        //  Returns patch list and sets faceMap to indices within faceLst
-        static surfGroupList sortedPatchRegions
+        //- Determine the sort order from the region ids.
+        //  Returns region list and sets faceMap to indices within faceLst
+        static surfRegionList sortedRegionsById
         (
-            const UList<label>& regionLst,
-            const Map<word>& patchNames,
+            const UList<label>& regionIds,
+            const Map<word>& regionNames,
             labelList& faceMap
         );
 
diff --git a/src/surfMesh/surfaceFormats/tri/TRIsurfaceFormat.C b/src/surfMesh/surfaceFormats/tri/TRIsurfaceFormat.C
index 7aaa1369e48cfec22bc86c822abbbe64411f6c10..17110ab948cb40dcca135390d34507208bc76f73 100644
--- a/src/surfMesh/surfaceFormats/tri/TRIsurfaceFormat.C
+++ b/src/surfMesh/surfaceFormats/tri/TRIsurfaceFormat.C
@@ -37,7 +37,7 @@ inline void Foam::fileFormats::TRIsurfaceFormat<Face>::writeShell
     Ostream& os,
     const pointField& pointLst,
     const Face& f,
-    const label patchI
+    const label regionI
 )
 {
     // simple triangulation about f[0].
@@ -54,7 +54,7 @@ inline void Foam::fileFormats::TRIsurfaceFormat<Face>::writeShell
             << p1.x() << ' ' << p1.y() << ' ' << p1.z() << ' '
             << p2.x() << ' ' << p2.y() << ' ' << p2.z() << ' '
             // region as colour
-            << "0x" << hex << patchI << dec << endl;
+            << "0x" << hex << regionI << dec << endl;
     }
 }
 
@@ -89,10 +89,10 @@ bool Foam::fileFormats::TRIsurfaceFormat<Face>::read
 
     // retrieve the original region information
     List<label> sizes(reader.sizes().xfer());
-    List<label> regions(reader.regions().xfer());
+    List<label> regionIds(reader.regionIds().xfer());
 
     // generate the (sorted) faces
-    List<Face> faceLst(regions.size());
+    List<Face> faceLst(regionIds.size());
 
     if (reader.sorted())
     {
@@ -108,7 +108,7 @@ bool Foam::fileFormats::TRIsurfaceFormat<Face>::read
         // unsorted - determine the sorted order:
         // avoid SortableList since we discard the main list anyhow
         List<label> faceMap;
-        sortedOrder(regions, faceMap);
+        sortedOrder(regionIds, faceMap);
 
         // generate sorted faces
         forAll(faceMap, faceI)
@@ -117,12 +117,12 @@ bool Foam::fileFormats::TRIsurfaceFormat<Face>::read
             faceLst[faceI] = triFace(startPt, startPt+1, startPt+2);
         }
     }
-    regions.clear();
+    regionIds.clear();
 
     // transfer:
     this->storedFaces().transfer(faceLst);
 
-    this->addPatches(sizes);
+    this->addRegions(sizes);
     this->stitchFaces(SMALL);
     return true;
 }
@@ -137,15 +137,15 @@ void Foam::fileFormats::TRIsurfaceFormat<Face>::write
 {
     const pointField& pointLst = surf.points();
     const List<Face>& faceLst  = surf.faces();
-    const List<surfGroup>& patchLst = surf.patches();
+    const List<surfRegion>& regionLst = surf.regions();
 
     label faceIndex = 0;
-    forAll(patchLst, patchI)
+    forAll(regionLst, regionI)
     {
-        forAll(patchLst[patchI], patchFaceI)
+        forAll(regionLst[regionI], localFaceI)
         {
             const Face& f = faceLst[faceIndex++];
-            writeShell(os, pointLst, f, patchI);
+            writeShell(os, pointLst, f, regionI);
         }
     }
 }
@@ -163,7 +163,7 @@ void Foam::fileFormats::TRIsurfaceFormat<Face>::write
 
     bool doSort = false;
     // a single region needs no sorting
-    if (surf.patches().size() == 1)
+    if (surf.regionToc().size() == 1)
     {
         doSort = false;
     }
@@ -171,25 +171,25 @@ void Foam::fileFormats::TRIsurfaceFormat<Face>::write
     if (doSort)
     {
         labelList faceMap;
-        List<surfGroup> patchLst = surf.sortedRegions(faceMap);
+        List<surfRegion> regionLst = surf.sortedRegions(faceMap);
 
         label faceIndex = 0;
-        forAll(patchLst, patchI)
+        forAll(regionLst, regionI)
         {
-            forAll(patchLst[patchI], patchFaceI)
+            forAll(regionLst[regionI], localFaceI)
             {
                 const Face& f = faceLst[faceMap[faceIndex++]];
-                writeShell(os, pointLst, f, patchI);
+                writeShell(os, pointLst, f, regionI);
             }
         }
     }
     else
     {
-        const List<label>& regionLst  = surf.regions();
+        const List<label>& regionIds  = surf.regionIds();
 
         forAll(faceLst, faceI)
         {
-            writeShell(os, pointLst, faceLst[faceI], regionLst[faceI]);
+            writeShell(os, pointLst, faceLst[faceI], regionIds[faceI]);
         }
     }
 }
diff --git a/src/surfMesh/surfaceFormats/tri/TRIsurfaceFormat.H b/src/surfMesh/surfaceFormats/tri/TRIsurfaceFormat.H
index 8afba853140f54e32273b88fd284d279156ef0e0..062e17be0cb1052b55f33c4b3c9dbb56b5659407 100644
--- a/src/surfMesh/surfaceFormats/tri/TRIsurfaceFormat.H
+++ b/src/surfMesh/surfaceFormats/tri/TRIsurfaceFormat.H
@@ -69,7 +69,7 @@ class TRIsurfaceFormat
             Ostream&,
             const pointField&,
             const Face&,
-            const label patchI
+            const label regionI
         );
 
         //- Disallow default bitwise copy construct
diff --git a/src/surfMesh/surfaceFormats/tri/TRIsurfaceFormatCore.C b/src/surfMesh/surfaceFormats/tri/TRIsurfaceFormatCore.C
index e742d2598356ee6b6180740d4e12135f5842e772..0afd91d00fe950c77e7b86c3f1af7f0c9bf49d8b 100644
--- a/src/surfMesh/surfaceFormats/tri/TRIsurfaceFormatCore.C
+++ b/src/surfMesh/surfaceFormats/tri/TRIsurfaceFormatCore.C
@@ -43,7 +43,7 @@ Foam::fileFormats::TRIsurfaceFormatCore::TRIsurfaceFormatCore
 :
     sorted_(true),
     points_(0),
-    regions_(0),
+    regionIds_(0),
     sizes_(0)
 {
     read(filename);
@@ -83,10 +83,10 @@ bool Foam::fileFormats::TRIsurfaceFormatCore::read
     DynamicList<label> dynSizes;
     HashTable<label>   lookup;
 
-    // place faces without a group in patch0
+    // place faces without a group in region0
     label regionI = 0;
     dynSizes.append(regionI);
-    lookup.insert("patch0", regionI);
+    lookup.insert("regionI", regionI);
 
     while (is.good())
     {
@@ -132,13 +132,13 @@ bool Foam::fileFormats::TRIsurfaceFormatCore::read
 
         // Region/colour in .tri file starts with 0x. Skip.
         // ie, instead of having 0xFF, skip 0 and leave xFF to
-        // get read as a word and name it "patchFF"
+        // get read as a word and name it "regionFF"
 
         char zero;
         lineStream >> zero;
 
         word rawName(lineStream);
-        word name("patch" + rawName(1, rawName.size()-1));
+        word name("region" + rawName(1, rawName.size()-1));
 
         HashTable<label>::const_iterator fnd = lookup.find(name);
         if (fnd != lookup.end())
@@ -162,24 +162,24 @@ bool Foam::fileFormats::TRIsurfaceFormatCore::read
     }
 
     // skip empty groups
-    label nPatch = 0;
-    forAll(dynSizes, patchI)
+    label nRegion = 0;
+    forAll(dynSizes, regionI)
     {
-        if (dynSizes[patchI])
+        if (dynSizes[regionI])
         {
-            if (nPatch != patchI)
+            if (nRegion != regionI)
             {
-                dynSizes[nPatch] = dynSizes[patchI];
+                dynSizes[nRegion] = dynSizes[regionI];
             }
-            nPatch++;
+            nRegion++;
         }
     }
     // truncate addressed size
-    dynSizes.setCapacity(nPatch);
+    dynSizes.setCapacity(nRegion);
 
     // transfer to normal lists
     points_.transfer(dynPoints);
-    regions_.transfer(dynRegions);
+    regionIds_.transfer(dynRegions);
     sizes_.transfer(dynSizes);
 
     return true;
diff --git a/src/surfMesh/surfaceFormats/tri/TRIsurfaceFormatCore.H b/src/surfMesh/surfaceFormats/tri/TRIsurfaceFormatCore.H
index a41ee7b1e2f896dbb6f1d9896c6f7c93015f09de..776f40e9926e88e6e6ae738462bf36d7cbd03dc5 100644
--- a/src/surfMesh/surfaceFormats/tri/TRIsurfaceFormatCore.H
+++ b/src/surfMesh/surfaceFormats/tri/TRIsurfaceFormatCore.H
@@ -65,7 +65,7 @@ class TRIsurfaceFormatCore
         pointField points_;
 
         //- The regions associated with the faces
-        List<label> regions_;
+        List<label> regionIds_;
 
         //- The solid count, in the order of their first appearance
         List<label> sizes_;
@@ -104,7 +104,7 @@ public:
         {
             sorted_ = true;
             points_.clear();
-            regions_.clear();
+            regionIds_.clear();
             sizes_.clear();
         }
 
@@ -115,9 +115,9 @@ public:
         }
 
         //- Return full access to the regions
-        List<label>& regions()
+        List<label>& regionIds()
         {
-            return regions_;
+            return regionIds_;
         }
 
         //- The list of region sizes in the order of their first appearance
diff --git a/src/surfMesh/surfaceFormats/vtk/VTKsurfaceFormat.C b/src/surfMesh/surfaceFormats/vtk/VTKsurfaceFormat.C
index 7c9cf40a08b9fb2e02dea303bb613f78fff055b6..da52bd4d7728635df8fc79187e4af04f88b34288 100644
--- a/src/surfMesh/surfaceFormats/vtk/VTKsurfaceFormat.C
+++ b/src/surfMesh/surfaceFormats/vtk/VTKsurfaceFormat.C
@@ -33,7 +33,7 @@ template<class Face>
 void Foam::fileFormats::VTKsurfaceFormat<Face>::writeHeaderPolygons
 (
     Ostream& os,
-    const List<Face>& faceLst
+    const UList<Face>& faceLst
 )
 {
     label nNodes = 0;
@@ -66,15 +66,15 @@ void Foam::fileFormats::VTKsurfaceFormat<Face>::write
 )
 {
     const List<Face>& faceLst = surf.faces();
-    const List<surfGroup>& patchLst = surf.patches();
+    const List<surfRegion>& regionLst = surf.regions();
 
     writeHeader(os, surf.points());
     writeHeaderPolygons(os, faceLst);
 
     label faceIndex = 0;
-    forAll(patchLst, patchI)
+    forAll(regionLst, regionI)
     {
-        forAll(patchLst[patchI], patchFaceI)
+        forAll(regionLst[regionI], localFaceI)
         {
             const Face& f = faceLst[faceIndex++];
 
@@ -87,8 +87,7 @@ void Foam::fileFormats::VTKsurfaceFormat<Face>::write
         }
     }
 
-    // Print region numbers
-    writeTail(os, patchLst);
+    writeTail(os, regionLst);
 }
 
 
@@ -116,8 +115,7 @@ void Foam::fileFormats::VTKsurfaceFormat<Face>::write
         os << ' ' << nl;
     }
 
-    // Print region numbers
-    writeTail(os, surf.regions());
+    writeTail(os, surf.regionIds());
 }
 
 
diff --git a/src/surfMesh/surfaceFormats/vtk/VTKsurfaceFormat.H b/src/surfMesh/surfaceFormats/vtk/VTKsurfaceFormat.H
index 214d1f8c0292057402ce5f511e8cb3941178947a..fe9f38621cf73e958fb5ec1dbbdc415526469223 100644
--- a/src/surfMesh/surfaceFormats/vtk/VTKsurfaceFormat.H
+++ b/src/surfMesh/surfaceFormats/vtk/VTKsurfaceFormat.H
@@ -27,7 +27,7 @@ Class
 
 Description
     Provide a means of writing VTK legacy format.
-    The output is never sorted by patch.
+    The output is never sorted by region.
 
 SourceFiles
     VTKsurfaceFormat.C
@@ -63,7 +63,7 @@ class VTKsurfaceFormat
     // Private Member Functions
 
         //- Write header information about number of polygon points
-        static void writeHeaderPolygons(Ostream&, const List<Face>&);
+        static void writeHeaderPolygons(Ostream&, const UList<Face>&);
 
         //- Disallow default bitwise copy construct
         VTKsurfaceFormat(const VTKsurfaceFormat<Face>&);
diff --git a/src/surfMesh/surfaceFormats/vtk/VTKsurfaceFormatCore.C b/src/surfMesh/surfaceFormats/vtk/VTKsurfaceFormatCore.C
index f2b9141635ca6f9e87f9fc3f3fef235e8e597a00..adbb487e14fbae90f96d3b76502310145509fbd6 100644
--- a/src/surfMesh/surfaceFormats/vtk/VTKsurfaceFormatCore.C
+++ b/src/surfMesh/surfaceFormats/vtk/VTKsurfaceFormatCore.C
@@ -58,13 +58,13 @@ void Foam::fileFormats::VTKsurfaceFormatCore::writeHeader
 void Foam::fileFormats::VTKsurfaceFormatCore::writeTail
 (
     Ostream& os,
-    const List<surfGroup>& patchLst
+    const UList<surfRegion>& regionLst
 )
 {
     label nFaces = 0;
-    forAll(patchLst, patchI)
+    forAll(regionLst, regionI)
     {
-        nFaces += patchLst[patchI].size();
+        nFaces += regionLst[regionI].size();
     }
 
     // Print region numbers
@@ -74,22 +74,22 @@ void Foam::fileFormats::VTKsurfaceFormatCore::writeTail
         << "region 1 " << nFaces << " float" << nl;
 
 
-    forAll(patchLst, patchI)
+    forAll(regionLst, regionI)
     {
-        forAll(patchLst[patchI], patchFaceI)
+        forAll(regionLst[regionI], localFaceI)
         {
-            if (patchFaceI)
+            if (localFaceI)
             {
-                if ((patchFaceI % 20) == 0)
+                if (localFaceI % 20)
                 {
-                    os << nl;
+                    os << ' ';
                 }
                 else
                 {
-                    os << ' ';
+                    os << nl;
                 }
             }
-            os  << patchI + 1;
+            os  << regionI + 1;
         }
         os  << nl;
     }
@@ -99,30 +99,30 @@ void Foam::fileFormats::VTKsurfaceFormatCore::writeTail
 void Foam::fileFormats::VTKsurfaceFormatCore::writeTail
 (
     Ostream& os,
-    const List<label>& regionLst
+    const UList<label>& regionIds
 )
 {
     // Print region numbers
     os  << nl
-        << "CELL_DATA " << regionLst.size() << nl
+        << "CELL_DATA " << regionIds.size() << nl
         << "FIELD attributes 1" << nl
-        << "region 1 " << regionLst.size() << " float" << nl;
+        << "region 1 " << regionIds.size() << " float" << nl;
 
 
-    forAll(regionLst, faceI)
+    forAll(regionIds, faceI)
     {
         if (faceI)
         {
-            if ((faceI % 20) == 0)
+            if (faceI % 20)
             {
-                os << nl;
+                os << ' ';
             }
             else
             {
-                os << ' ';
+                os << nl;
             }
         }
-        os  << regionLst[faceI] + 1;
+        os  << regionIds[faceI] + 1;
     }
     os  << nl;
 }
diff --git a/src/surfMesh/surfaceFormats/vtk/VTKsurfaceFormatCore.H b/src/surfMesh/surfaceFormats/vtk/VTKsurfaceFormatCore.H
index 4cec29b1c9209ad08620c4353faf58d9cb7caddc..a68b4197cacd59f1216d08240f113f992deadd61 100644
--- a/src/surfMesh/surfaceFormats/vtk/VTKsurfaceFormatCore.H
+++ b/src/surfMesh/surfaceFormats/vtk/VTKsurfaceFormatCore.H
@@ -64,11 +64,11 @@ protected:
         const pointField&
     );
 
-    //- Write trailing information with patch information
-    static void writeTail(Ostream&, const List<surfGroup>&);
-
     //- Write trailing information with region information
-    static void writeTail(Ostream&, const List<label>& regionLst);
+    static void writeTail(Ostream&, const UList<surfRegion>&);
+
+    //- Write trailing information with region Ids
+    static void writeTail(Ostream&, const UList<label>& regionIds);
 
 };
 
diff --git a/src/thermophysicalModels/radiation/radiationModel/radiationModel/newRadiationModel.C b/src/thermophysicalModels/radiation/radiationModel/radiationModel/newRadiationModel.C
index 0a213f03d3a6ef3cfd72ec9e508363076dbceb9d..9822578114692dcfbcd05db74144e421eae87507 100644
--- a/src/thermophysicalModels/radiation/radiationModel/radiationModel/newRadiationModel.C
+++ b/src/thermophysicalModels/radiation/radiationModel/radiationModel/newRadiationModel.C
@@ -86,7 +86,7 @@ autoPtr<radiationModel> radiationModel::New
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-} // End radiation
+} // End namespace radiation
 } // End namespace Foam
 
 // ************************************************************************* //
diff --git a/src/turbulenceModels/compressible/LES/DeardorffDiffStress/DeardorffDiffStress.C b/src/turbulenceModels/compressible/LES/DeardorffDiffStress/DeardorffDiffStress.C
index aa0b47499242254882a68fdd596044f26aa76cfd..e847acda6e829d24076b3262783887d79c997811 100644
--- a/src/turbulenceModels/compressible/LES/DeardorffDiffStress/DeardorffDiffStress.C
+++ b/src/turbulenceModels/compressible/LES/DeardorffDiffStress/DeardorffDiffStress.C
@@ -41,6 +41,16 @@ namespace LESModels
 defineTypeNameAndDebug(DeardorffDiffStress, 0);
 addToRunTimeSelectionTable(LESModel, DeardorffDiffStress, dictionary);
 
+
+// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
+
+void DeardorffDiffStress::updateSubGridScaleFields(const volScalarField& K)
+{
+    muSgs_ = ck_*rho()*sqrt(K)*delta();
+    muSgs_.correctBoundaryConditions();
+}
+
+
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
 DeardorffDiffStress::DeardorffDiffStress
@@ -73,6 +83,8 @@ DeardorffDiffStress::DeardorffDiffStress
         )
     )
 {
+    updateSubGridScaleFields(0.5*tr(B_));
+
     printCoeffs();
 }
 
@@ -119,8 +131,7 @@ void DeardorffDiffStress::correct(const tmp<volTensorField>& tgradU)
     K = 0.5*tr(B_);
     bound(K, k0());
 
-    muSgs_ = ck_*rho()*sqrt(K)*delta();
-    muSgs_.correctBoundaryConditions();
+    updateSubGridScaleFields(K);
 }
 
 
diff --git a/src/turbulenceModels/compressible/LES/DeardorffDiffStress/DeardorffDiffStress.H b/src/turbulenceModels/compressible/LES/DeardorffDiffStress/DeardorffDiffStress.H
index 4371afbc6677b5c12dab489c51452737e8d9c32e..510c304f201a279a945958921ad1c0e41f91829a 100644
--- a/src/turbulenceModels/compressible/LES/DeardorffDiffStress/DeardorffDiffStress.H
+++ b/src/turbulenceModels/compressible/LES/DeardorffDiffStress/DeardorffDiffStress.H
@@ -81,6 +81,9 @@ class DeardorffDiffStress
 
     // Private Member Functions
 
+        //- Update sub-grid scale fields
+        void updateSubGridScaleFields(const volScalarField& K);
+
         // Disallow default bitwise copy construct and assignment
         DeardorffDiffStress(const DeardorffDiffStress&);
         DeardorffDiffStress& operator=(const DeardorffDiffStress&);
diff --git a/src/turbulenceModels/compressible/LES/Smagorinsky/Smagorinsky.C b/src/turbulenceModels/compressible/LES/Smagorinsky/Smagorinsky.C
index e845776031ac6221d3d366c8b7c048130ae51c8d..c89b2aeecf7c988a7140ab782e6a382ac992ad58 100644
--- a/src/turbulenceModels/compressible/LES/Smagorinsky/Smagorinsky.C
+++ b/src/turbulenceModels/compressible/LES/Smagorinsky/Smagorinsky.C
@@ -41,6 +41,24 @@ namespace LESModels
 defineTypeNameAndDebug(Smagorinsky, 0);
 addToRunTimeSelectionTable(LESModel, Smagorinsky, dictionary);
 
+
+// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
+
+void Smagorinsky::updateSubGridScaleFields(const volTensorField& gradU)
+{
+    volSymmTensorField D = symm(gradU);
+
+    volScalarField a = ce_/delta();
+    volScalarField b = (2.0/3.0)*tr(D);
+    volScalarField c = 2*ck_*delta()*(dev(D) && D);
+
+    k_ = sqr((-b + sqrt(sqr(b) + 4*a*c))/(2*a));
+
+    muSgs_ = ck_*rho()*delta()*sqrt(k_);
+    muSgs_.correctBoundaryConditions();
+}
+
+
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
 Smagorinsky::Smagorinsky
@@ -64,6 +82,8 @@ Smagorinsky::Smagorinsky
         )
     )
 {
+    updateSubGridScaleFields(fvc::grad(U));
+
     printCoeffs();
 }
 
@@ -73,17 +93,7 @@ Smagorinsky::Smagorinsky
 void Smagorinsky::correct(const tmp<volTensorField>& gradU)
 {
     GenEddyVisc::correct(gradU);
-
-    volSymmTensorField D = symm(gradU);
-
-    volScalarField a = ce_/delta();
-    volScalarField b = (2.0/3.0)*tr(D);
-    volScalarField c = 2*ck_*delta()*(dev(D) && D);
-
-    k_ = sqr((-b + sqrt(sqr(b) + 4*a*c))/(2*a));
-
-    muSgs_ = ck_*rho()*delta()*sqrt(k_);
-    muSgs_.correctBoundaryConditions();
+    updateSubGridScaleFields(gradU());
 }
 
 
diff --git a/src/turbulenceModels/compressible/LES/Smagorinsky/Smagorinsky.H b/src/turbulenceModels/compressible/LES/Smagorinsky/Smagorinsky.H
index c93745dbcbfa6e6f413e2fe0b474e727f156dbd1..ba296a87f945c6813bfba7075e4a0b95798340e3 100644
--- a/src/turbulenceModels/compressible/LES/Smagorinsky/Smagorinsky.H
+++ b/src/turbulenceModels/compressible/LES/Smagorinsky/Smagorinsky.H
@@ -76,6 +76,9 @@ class Smagorinsky
 
     // Private Member Functions
 
+        //- Update sub-grid scale fields
+        void updateSubGridScaleFields(const volTensorField& gradU);
+
         // Disallow default bitwise copy construct and assignment
         Smagorinsky(const Smagorinsky&);
         Smagorinsky& operator=(const Smagorinsky&);
diff --git a/src/turbulenceModels/compressible/LES/SpalartAllmaras/SpalartAllmaras.C b/src/turbulenceModels/compressible/LES/SpalartAllmaras/SpalartAllmaras.C
index 92d15f5cd808281a21f6b96d03c6e89c8e607178..65a6a69bde2ab2ed3a3fb98c1a9bc270a0de07d0 100644
--- a/src/turbulenceModels/compressible/LES/SpalartAllmaras/SpalartAllmaras.C
+++ b/src/turbulenceModels/compressible/LES/SpalartAllmaras/SpalartAllmaras.C
@@ -45,24 +45,29 @@ addToRunTimeSelectionTable(LESModel, SpalartAllmaras, dictionary);
 
 // * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * * //
 
+void SpalartAllmaras::updateSubGridScaleFields()
+{
+    muSgs_.internalField() = rho()*fv1()*nuTilda_.internalField();
+    muSgs_.correctBoundaryConditions();
+}
+
+
 tmp<volScalarField> SpalartAllmaras::fv1() const
 {
-    volScalarField chi3 = pow3(nuTilda_/(mu()/rho()));
+    volScalarField chi3 = pow3(rho()*nuTilda_/mu());
     return chi3/(chi3 + pow3(Cv1_));
 }
 
 
 tmp<volScalarField> SpalartAllmaras::fv2() const
 {
-    volScalarField chi = nuTilda_/(mu()/rho());
-    //return scalar(1) - chi/(scalar(1) + chi*fv1());
-    return 1.0/pow3(scalar(1) + chi/Cv2_);
+    return 1.0/pow3(scalar(1) + rho()*nuTilda_/(mu()*Cv2_));
 }
 
 
 tmp<volScalarField> SpalartAllmaras::fv3() const
 {
-    volScalarField chi = nuTilda_/(mu()/rho());
+    volScalarField chi = rho()*nuTilda_/mu();
     volScalarField chiByCv2 = (1/Cv2_)*chi;
 
     return
@@ -225,6 +230,8 @@ SpalartAllmaras::SpalartAllmaras
     )
 
 {
+    updateSubGridScaleFields();
+
     printCoeffs();
 }
 
@@ -288,10 +295,9 @@ void SpalartAllmaras::correct(const tmp<volTensorField>& tgradU)
     );
 
     bound(nuTilda_, dimensionedScalar("zero", nuTilda_.dimensions(), 0.0));
-
     nuTilda_.correctBoundaryConditions();
-    muSgs_.internalField() = rho()*fv1()*nuTilda_.internalField();
-    muSgs_.correctBoundaryConditions();
+
+    updateSubGridScaleFields();
 }
 
 
diff --git a/src/turbulenceModels/compressible/LES/SpalartAllmaras/SpalartAllmaras.H b/src/turbulenceModels/compressible/LES/SpalartAllmaras/SpalartAllmaras.H
index 437baedb49f34f141ae2a75d6ef6713925c1a16f..e119768537c319c3205661c9ef842ab5bbfe3c7f 100644
--- a/src/turbulenceModels/compressible/LES/SpalartAllmaras/SpalartAllmaras.H
+++ b/src/turbulenceModels/compressible/LES/SpalartAllmaras/SpalartAllmaras.H
@@ -49,7 +49,7 @@ namespace LESModels
 {
 
 /*---------------------------------------------------------------------------*\
-                           Class SpalartAllmaras Declaration
+                       Class SpalartAllmaras Declaration
 \*---------------------------------------------------------------------------*/
 
 class SpalartAllmaras
@@ -74,6 +74,9 @@ class SpalartAllmaras
 
     // Private member functions
 
+        //- Update sub-grid scale fields
+        void updateSubGridScaleFields();
+
         tmp<volScalarField> fv1() const;
         tmp<volScalarField> fv2() const;
         tmp<volScalarField> fv3() const;
diff --git a/src/turbulenceModels/compressible/LES/dynOneEqEddy/dynOneEqEddy.C b/src/turbulenceModels/compressible/LES/dynOneEqEddy/dynOneEqEddy.C
index f6194e48823a52c9fbb9a612d6eb47c25313116c..7e9b3d9b7ba2844b6c90fb69cf91007e743f3a5a 100644
--- a/src/turbulenceModels/compressible/LES/dynOneEqEddy/dynOneEqEddy.C
+++ b/src/turbulenceModels/compressible/LES/dynOneEqEddy/dynOneEqEddy.C
@@ -43,6 +43,13 @@ addToRunTimeSelectionTable(LESModel, dynOneEqEddy, dictionary);
 
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
+void dynOneEqEddy::updateSubGridScaleFields(const volSymmTensorField& D)
+{
+    muSgs_ = ck_(D)*rho()*sqrt(k_)*delta();
+    muSgs_.correctBoundaryConditions();
+}
+
+
 dimensionedScalar dynOneEqEddy::ck_(const volSymmTensorField& D) const
 {
     volScalarField KK = 0.5*(filter_(magSqr(U())) - magSqr(filter_(U())));
@@ -90,6 +97,8 @@ dynOneEqEddy::dynOneEqEddy
     filterPtr_(LESfilter::New(U.mesh(), coeffDict())),
     filter_(filterPtr_())
 {
+    updateSubGridScaleFields(dev(symm(fvc::grad(U))));
+
     printCoeffs();
 }
 
@@ -119,8 +128,7 @@ void dynOneEqEddy::correct(const tmp<volTensorField>& tgradU)
 
     bound(k_, dimensionedScalar("0", k_.dimensions(), 1.0e-10));
 
-    muSgs_ = ck_(D)*rho()*sqrt(k_)*delta();
-    muSgs_.correctBoundaryConditions();
+    updateSubGridScaleFields(D);
 }
 
 
diff --git a/src/turbulenceModels/compressible/LES/dynOneEqEddy/dynOneEqEddy.H b/src/turbulenceModels/compressible/LES/dynOneEqEddy/dynOneEqEddy.H
index 4f5ec19b70c879bee35eef58c5957b7f50aeba94..a32dacddfdb60399483f9af047167285a6f70ede 100644
--- a/src/turbulenceModels/compressible/LES/dynOneEqEddy/dynOneEqEddy.H
+++ b/src/turbulenceModels/compressible/LES/dynOneEqEddy/dynOneEqEddy.H
@@ -82,6 +82,9 @@ class dynOneEqEddy
 
     // Private Member Functions
 
+        //- Update sub-grid scale fields
+        void updateSubGridScaleFields(const volSymmTensorField& D);
+
         //- Calculate ck, ce by filtering the velocity field U.
         dimensionedScalar ck_(const volSymmTensorField& D) const;
         dimensionedScalar ce_(const volSymmTensorField& D) const;
diff --git a/src/turbulenceModels/compressible/LES/lowReOneEqEddy/lowReOneEqEddy.C b/src/turbulenceModels/compressible/LES/lowReOneEqEddy/lowReOneEqEddy.C
index 3783677eaf52d754e67ae3481113c5cebfaff396..b5670ad2451aa1e9d6b2379925341f0829826a40 100644
--- a/src/turbulenceModels/compressible/LES/lowReOneEqEddy/lowReOneEqEddy.C
+++ b/src/turbulenceModels/compressible/LES/lowReOneEqEddy/lowReOneEqEddy.C
@@ -41,6 +41,19 @@ namespace LESModels
 defineTypeNameAndDebug(lowReOneEqEddy, 0);
 addToRunTimeSelectionTable(LESModel, lowReOneEqEddy, dictionary);
 
+// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
+
+void lowReOneEqEddy::updateSubGridScaleFields()
+{
+    // High Re eddy viscosity
+    muSgs_ = ck_*rho()*sqrt(k_)*delta();
+
+    // low Re no corrected eddy viscosity
+    muSgs_ -= (mu()/beta_)*(scalar(1) - exp(-beta_*muSgs_/mu()));
+    muSgs_.correctBoundaryConditions();
+}
+
+
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
 lowReOneEqEddy::lowReOneEqEddy
@@ -73,6 +86,8 @@ lowReOneEqEddy::lowReOneEqEddy
         )
     )
 {
+    updateSubGridScaleFields();
+
     printCoeffs();
 }
 
@@ -101,13 +116,7 @@ void lowReOneEqEddy::correct(const tmp<volTensorField>& tgradU)
 
     bound(k_, k0());
 
-    // High Re eddy viscosity
-    muSgs_ = ck_*rho()*sqrt(k_)*delta();
-
-    // low Re no corrected eddy viscosity
-    muSgs_ -= (mu()/beta_)*(scalar(1) - exp(-beta_*muSgs_/mu()));
-
-    muSgs_.correctBoundaryConditions();
+    updateSubGridScaleFields();
 }
 
 
diff --git a/src/turbulenceModels/compressible/LES/lowReOneEqEddy/lowReOneEqEddy.H b/src/turbulenceModels/compressible/LES/lowReOneEqEddy/lowReOneEqEddy.H
index a36ec44860574e0f722098a6187aa0814e78083e..9820905a4182df49a0ceb30ac13438cd615908bf 100644
--- a/src/turbulenceModels/compressible/LES/lowReOneEqEddy/lowReOneEqEddy.H
+++ b/src/turbulenceModels/compressible/LES/lowReOneEqEddy/lowReOneEqEddy.H
@@ -77,6 +77,9 @@ class lowReOneEqEddy
 
     // Private Member Functions
 
+        //- Update sub-grid scale fields
+        void updateSubGridScaleFields();
+
         // Disallow default bitwise copy construct and assignment
         lowReOneEqEddy(const lowReOneEqEddy&);
         lowReOneEqEddy& operator=(const lowReOneEqEddy&);
diff --git a/src/turbulenceModels/compressible/LES/oneEqEddy/oneEqEddy.C b/src/turbulenceModels/compressible/LES/oneEqEddy/oneEqEddy.C
index 65457c035970e6814bdcf2e98daba5567ffea003..414aba5b0322630f5497275c856118fce3387823 100644
--- a/src/turbulenceModels/compressible/LES/oneEqEddy/oneEqEddy.C
+++ b/src/turbulenceModels/compressible/LES/oneEqEddy/oneEqEddy.C
@@ -41,6 +41,15 @@ namespace LESModels
 defineTypeNameAndDebug(oneEqEddy, 0);
 addToRunTimeSelectionTable(LESModel, oneEqEddy, dictionary);
 
+// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
+
+void oneEqEddy::updateSubGridScaleFields()
+{
+    muSgs_ = ck_*rho()*sqrt(k_)*delta();
+    muSgs_.correctBoundaryConditions();
+}
+
+
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
 oneEqEddy::oneEqEddy
@@ -64,6 +73,8 @@ oneEqEddy::oneEqEddy
         )
     )
 {
+    updateSubGridScaleFields();
+
     printCoeffs();
 }
 
@@ -95,8 +106,7 @@ void oneEqEddy::correct(const tmp<volTensorField>& tgradU)
 
     bound(k_, k0());
 
-    muSgs_ = ck_*rho()*sqrt(k_)*delta();
-    muSgs_.correctBoundaryConditions();
+    updateSubGridScaleFields();
 }
 
 
diff --git a/src/turbulenceModels/compressible/LES/oneEqEddy/oneEqEddy.H b/src/turbulenceModels/compressible/LES/oneEqEddy/oneEqEddy.H
index 6568724fd2d23d3c7d08cb7e46282025275b0f0a..2a9bb7459107f5cd1800d9d90c7435f3f159f10d 100644
--- a/src/turbulenceModels/compressible/LES/oneEqEddy/oneEqEddy.H
+++ b/src/turbulenceModels/compressible/LES/oneEqEddy/oneEqEddy.H
@@ -80,6 +80,9 @@ class oneEqEddy
 
     // Private Member Functions
 
+        //- Update sub-grid scale fields
+        void updateSubGridScaleFields();
+
         // Disallow default bitwise copy construct and assignment
         oneEqEddy(const oneEqEddy&);
         oneEqEddy& operator=(const oneEqEddy&);
diff --git a/src/turbulenceModels/compressible/RAS/RASModel/RASModel.C b/src/turbulenceModels/compressible/RAS/RASModel/RASModel.C
index 60d3dc3e841f40607dccb0292a8466bf7b7a3bda..f52646af28a00030bfee40c0d013ff12d55a01ba 100644
--- a/src/turbulenceModels/compressible/RAS/RASModel/RASModel.C
+++ b/src/turbulenceModels/compressible/RAS/RASModel/RASModel.C
@@ -88,7 +88,7 @@ RASModel::RASModel
         dimensioned<scalar>::lookupOrAddToDict
         (
             "kappa",
-            subDict("wallFunctionCoeffs"),
+            wallFunctionDict_,
             0.4187
         )
     ),
@@ -97,7 +97,7 @@ RASModel::RASModel
         dimensioned<scalar>::lookupOrAddToDict
         (
             "E",
-            subDict("wallFunctionCoeffs"),
+            wallFunctionDict_,
             9.0
         )
     ),
diff --git a/src/turbulenceModels/compressible/RAS/SpalartAllmaras/SpalartAllmaras.C b/src/turbulenceModels/compressible/RAS/SpalartAllmaras/SpalartAllmaras.C
index 74f5d8c5ab9c077a5afc11781764d7ab14d87db7..fe78e344caacb2e4cf34997c8e9a2dac9c0c907a 100644
--- a/src/turbulenceModels/compressible/RAS/SpalartAllmaras/SpalartAllmaras.C
+++ b/src/turbulenceModels/compressible/RAS/SpalartAllmaras/SpalartAllmaras.C
@@ -63,8 +63,7 @@ tmp<volScalarField> SpalartAllmaras::fv2
     const volScalarField& fv1
 ) const
 {
-    return 1.0 - chi/(1.0 + chi*fv1);
-    //return 1.0/pow3(scalar(1) + chi/Cv2);
+    return 1.0/pow3(scalar(1) + chi/Cv2_);
 }
 
 
diff --git a/src/turbulenceModels/incompressible/LES/DeardorffDiffStress/DeardorffDiffStress.C b/src/turbulenceModels/incompressible/LES/DeardorffDiffStress/DeardorffDiffStress.C
index 0e3004edd71252cd74e1fe835072c06ab6509ac8..271b7c0b929849e23d7093034ffc75509b9f2ad5 100644
--- a/src/turbulenceModels/incompressible/LES/DeardorffDiffStress/DeardorffDiffStress.C
+++ b/src/turbulenceModels/incompressible/LES/DeardorffDiffStress/DeardorffDiffStress.C
@@ -41,6 +41,15 @@ namespace LESModels
 defineTypeNameAndDebug(DeardorffDiffStress, 0);
 addToRunTimeSelectionTable(LESModel, DeardorffDiffStress, dictionary);
 
+// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
+
+void DeardorffDiffStress::updateSubGridScaleFields(const volScalarField& K)
+{
+    nuSgs_ = ck_*sqrt(K)*delta();
+    nuSgs_.correctBoundaryConditions();
+}
+
+
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
 DeardorffDiffStress::DeardorffDiffStress
@@ -72,6 +81,8 @@ DeardorffDiffStress::DeardorffDiffStress
         )
     )
 {
+    updateSubGridScaleFields(0.5*tr(B_));
+
     printCoeffs();
 }
 
@@ -121,8 +132,7 @@ void DeardorffDiffStress::correct(const tmp<volTensorField>& tgradU)
     K = 0.5*tr(B_);
     bound(K, k0());
 
-    nuSgs_ = ck_*sqrt(K)*delta();
-    nuSgs_.correctBoundaryConditions();
+    updateSubGridScaleFields(K);
 }
 
 
diff --git a/src/turbulenceModels/incompressible/LES/DeardorffDiffStress/DeardorffDiffStress.H b/src/turbulenceModels/incompressible/LES/DeardorffDiffStress/DeardorffDiffStress.H
index bdffcf061ce062f85ffc7e491e01d8ab171c8225..67d422d64b961cf7c42222cb5cfccc42d81c8453 100644
--- a/src/turbulenceModels/incompressible/LES/DeardorffDiffStress/DeardorffDiffStress.H
+++ b/src/turbulenceModels/incompressible/LES/DeardorffDiffStress/DeardorffDiffStress.H
@@ -81,6 +81,9 @@ class DeardorffDiffStress
 
     // Private Member Functions
 
+        //- Update sub-grid scale fields
+        void updateSubGridScaleFields(const volScalarField& K);
+
         // Disallow default bitwise copy construct and assignment
         DeardorffDiffStress(const DeardorffDiffStress&);
         DeardorffDiffStress& operator=(const DeardorffDiffStress&);
diff --git a/src/turbulenceModels/incompressible/LES/LRRDiffStress/LRRDiffStress.C b/src/turbulenceModels/incompressible/LES/LRRDiffStress/LRRDiffStress.C
index 3b915025e9e7756155c4f252076cae3e8c3ebedc..3931684b6a128e3b58547d0788ebc633b8b0a5a0 100644
--- a/src/turbulenceModels/incompressible/LES/LRRDiffStress/LRRDiffStress.C
+++ b/src/turbulenceModels/incompressible/LES/LRRDiffStress/LRRDiffStress.C
@@ -41,6 +41,15 @@ namespace LESModels
 defineTypeNameAndDebug(LRRDiffStress, 0);
 addToRunTimeSelectionTable(LESModel, LRRDiffStress, dictionary);
 
+// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
+
+void LRRDiffStress::updateSubGridScaleFields(const volScalarField& K)
+{
+    nuSgs_ = ck_*sqrt(K)*delta();
+    nuSgs_.correctBoundaryConditions();
+}
+
+
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
 LRRDiffStress::LRRDiffStress
@@ -81,6 +90,8 @@ LRRDiffStress::LRRDiffStress
         )
     )
 {
+    updateSubGridScaleFields(0.5*tr(B_));
+
     printCoeffs();
 }
 
@@ -131,8 +142,7 @@ void LRRDiffStress::correct(const tmp<volTensorField>& tgradU)
     K = 0.5*tr(B_);
     bound(K, k0());
 
-    nuSgs_ = ck_*sqrt(K)*delta();
-    nuSgs_.correctBoundaryConditions();
+    updateSubGridScaleFields(K);
 }
 
 
diff --git a/src/turbulenceModels/incompressible/LES/LRRDiffStress/LRRDiffStress.H b/src/turbulenceModels/incompressible/LES/LRRDiffStress/LRRDiffStress.H
index 55bb7c5d480d1ed3fd72c9ec6c5ce36b543445cb..586d4a9f5ded9308fe5097d9412e799a702958c1 100644
--- a/src/turbulenceModels/incompressible/LES/LRRDiffStress/LRRDiffStress.H
+++ b/src/turbulenceModels/incompressible/LES/LRRDiffStress/LRRDiffStress.H
@@ -80,6 +80,9 @@ class LRRDiffStress
 
     // Private Member Functions
 
+        //- Update sub-grid scale fields
+        void updateSubGridScaleFields(const volScalarField& K);
+
         // Disallow default bitwise copy construct and assignment
         LRRDiffStress(const LRRDiffStress&);
         LRRDiffStress& operator=(const LRRDiffStress&);
diff --git a/src/turbulenceModels/incompressible/LES/Smagorinsky/Smagorinsky.C b/src/turbulenceModels/incompressible/LES/Smagorinsky/Smagorinsky.C
index 043590831667334eb65a688e771ac6f5b5977a2f..d19c2c789815deff39debdfce58d51921b72dfa0 100644
--- a/src/turbulenceModels/incompressible/LES/Smagorinsky/Smagorinsky.C
+++ b/src/turbulenceModels/incompressible/LES/Smagorinsky/Smagorinsky.C
@@ -41,6 +41,15 @@ namespace LESModels
 defineTypeNameAndDebug(Smagorinsky, 0);
 addToRunTimeSelectionTable(LESModel, Smagorinsky, dictionary);
 
+// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
+
+void Smagorinsky::updateSubGridScaleFields(const volTensorField& gradU)
+{
+    nuSgs_ = ck_*delta()*sqrt(k(gradU));
+    nuSgs_.correctBoundaryConditions();
+}
+
+
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
 Smagorinsky::Smagorinsky
@@ -62,7 +71,9 @@ Smagorinsky::Smagorinsky
             0.094
         )
     )
-{}
+{
+    updateSubGridScaleFields(fvc::grad(U));
+}
 
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
@@ -70,9 +81,7 @@ Smagorinsky::Smagorinsky
 void Smagorinsky::correct(const tmp<volTensorField>& gradU)
 {
     GenEddyVisc::correct(gradU);
-
-    nuSgs_ = ck_*delta()*sqrt(k(gradU));
-    nuSgs_.correctBoundaryConditions();
+    updateSubGridScaleFields(gradU());
 }
 
 
diff --git a/src/turbulenceModels/incompressible/LES/Smagorinsky/Smagorinsky.H b/src/turbulenceModels/incompressible/LES/Smagorinsky/Smagorinsky.H
index eba420101db2c0e1598478fb430c1765cb6f4510..13966f48831effaa7a8f4a39f8ab41b4431dbb91 100644
--- a/src/turbulenceModels/incompressible/LES/Smagorinsky/Smagorinsky.H
+++ b/src/turbulenceModels/incompressible/LES/Smagorinsky/Smagorinsky.H
@@ -77,6 +77,9 @@ class Smagorinsky
 
     // Private Member Functions
 
+        //- Update sub-grid scale fields
+        void updateSubGridScaleFields(const volTensorField& gradU);
+
         // Disallow default bitwise copy construct and assignment
         Smagorinsky(const Smagorinsky&);
         Smagorinsky& operator=(const Smagorinsky&);
diff --git a/src/turbulenceModels/incompressible/LES/SpalartAllmaras/SpalartAllmaras.C b/src/turbulenceModels/incompressible/LES/SpalartAllmaras/SpalartAllmaras.C
index a6d7b44bb573f616008bb08e8b12df30509c8138..11fd61b9570ceb01863596bc69990e64a059e641 100644
--- a/src/turbulenceModels/incompressible/LES/SpalartAllmaras/SpalartAllmaras.C
+++ b/src/turbulenceModels/incompressible/LES/SpalartAllmaras/SpalartAllmaras.C
@@ -41,6 +41,15 @@ namespace LESModels
 defineTypeNameAndDebug(SpalartAllmaras, 0);
 addToRunTimeSelectionTable(LESModel, SpalartAllmaras, dictionary);
 
+// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
+
+void SpalartAllmaras::updateSubGridScaleFields()
+{
+    nuSgs_.internalField() = fv1()*nuTilda_.internalField();
+    nuSgs_.correctBoundaryConditions();
+}
+
+
 // * * * * * * * * * * * * Protected Member Functions  * * * * * * * * * * * //
 
 tmp<volScalarField> SpalartAllmaras::fv1() const
@@ -52,8 +61,7 @@ tmp<volScalarField> SpalartAllmaras::fv1() const
 
 tmp<volScalarField> SpalartAllmaras::fv2() const
 {
-    volScalarField chi = nuTilda_/nu();
-    return 1/pow3(scalar(1) + chi/Cv2_);
+    return 1/pow3(scalar(1) + nuTilda_/(Cv2_*nu()));
 }
 
 
@@ -266,7 +274,10 @@ SpalartAllmaras::SpalartAllmaras
         ),
         mesh_
     )
-{}
+{
+    updateSubGridScaleFields();
+}
+
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
@@ -306,8 +317,7 @@ void SpalartAllmaras::correct(const tmp<volTensorField>& gradU)
     bound(nuTilda_, dimensionedScalar("zero", nuTilda_.dimensions(), 0.0));
     nuTilda_.correctBoundaryConditions();
 
-    nuSgs_.internalField() = fv1()*nuTilda_.internalField();
-    nuSgs_.correctBoundaryConditions();
+    updateSubGridScaleFields();
 }
 
 
diff --git a/src/turbulenceModels/incompressible/LES/SpalartAllmaras/SpalartAllmaras.H b/src/turbulenceModels/incompressible/LES/SpalartAllmaras/SpalartAllmaras.H
index b813075b1d0462925fcf8fa3acd359bb4719de79..60dfbcc555e978f691d601734b0d10a0a8912ba0 100644
--- a/src/turbulenceModels/incompressible/LES/SpalartAllmaras/SpalartAllmaras.H
+++ b/src/turbulenceModels/incompressible/LES/SpalartAllmaras/SpalartAllmaras.H
@@ -59,6 +59,9 @@ class SpalartAllmaras
 {
     // Private member functions
 
+        //- Update sub-grid scale fields
+        void updateSubGridScaleFields();
+
         // Disallow default bitwise copy construct and assignment
         SpalartAllmaras(const SpalartAllmaras&);
         SpalartAllmaras& operator=(const SpalartAllmaras&);
diff --git a/src/turbulenceModels/incompressible/LES/SpalartAllmarasIDDES/IDDESDelta/IDDESDelta.C b/src/turbulenceModels/incompressible/LES/SpalartAllmarasIDDES/IDDESDelta/IDDESDelta.C
index ef02e484560b11f8654a705478ee03e092fae2f5..3f3aa7699bb335fdebb01684e02f9b32de037ac4 100644
--- a/src/turbulenceModels/incompressible/LES/SpalartAllmarasIDDES/IDDESDelta/IDDESDelta.C
+++ b/src/turbulenceModels/incompressible/LES/SpalartAllmarasIDDES/IDDESDelta/IDDESDelta.C
@@ -44,7 +44,7 @@ void Foam::IDDESDelta::calcDelta()
     const Vector<label>& directions = mesh().directions();
     label nD = (directions.nComponents + cmptSum(directions))/2;
 
-    // - Init hwn as wall distant.
+    // initialise hwn as wall distance
     volScalarField hwn = wallDist(mesh()).y();
 
     scalar deltamaxTmp = 0.;
diff --git a/src/turbulenceModels/incompressible/LES/dynMixedSmagorinsky/dynMixedSmagorinsky.C b/src/turbulenceModels/incompressible/LES/dynMixedSmagorinsky/dynMixedSmagorinsky.C
index c0fb5160d3aad23382c24431985f4663a209e899..43f684d2286d87fbeb803b41e3311cfa76d88a80 100644
--- a/src/turbulenceModels/incompressible/LES/dynMixedSmagorinsky/dynMixedSmagorinsky.C
+++ b/src/turbulenceModels/incompressible/LES/dynMixedSmagorinsky/dynMixedSmagorinsky.C
@@ -113,7 +113,7 @@ tmp<fvVectorMatrix> dynMixedSmagorinsky::divDevBeff(volVectorField& U) const
 void dynMixedSmagorinsky::correct(const tmp<volTensorField>& gradU)
 {
     scaleSimilarity::correct(gradU);
-    dynSmagorinsky::correct(gradU);
+    dynSmagorinsky::correct(gradU());
 }
 
 
diff --git a/src/turbulenceModels/incompressible/LES/dynOneEqEddy/dynOneEqEddy.C b/src/turbulenceModels/incompressible/LES/dynOneEqEddy/dynOneEqEddy.C
index e447211bece161c2e6a456c97c7b7455aac70a49..4342712d806132771a79c7763b7ce5aeb0291147 100644
--- a/src/turbulenceModels/incompressible/LES/dynOneEqEddy/dynOneEqEddy.C
+++ b/src/turbulenceModels/incompressible/LES/dynOneEqEddy/dynOneEqEddy.C
@@ -43,6 +43,13 @@ addToRunTimeSelectionTable(LESModel, dynOneEqEddy, dictionary);
 
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
+void dynOneEqEddy::updateSubGridScaleFields(const volSymmTensorField& D)
+{
+    nuSgs_ = ck(D)*sqrt(k_)*delta();
+    nuSgs_.correctBoundaryConditions();
+}
+
+
 dimensionedScalar dynOneEqEddy::ck(const volSymmTensorField& D) const
 {
     volScalarField KK = 0.5*(filter_(magSqr(U())) - magSqr(filter_(U())));
@@ -120,6 +127,8 @@ dynOneEqEddy::dynOneEqEddy
     filterPtr_(LESfilter::New(U.mesh(), coeffDict())),
     filter_(filterPtr_())
 {
+    updateSubGridScaleFields(symm(fvc::grad(U)));
+
     printCoeffs();
 }
 
@@ -155,8 +164,7 @@ void dynOneEqEddy::correct(const tmp<volTensorField>& gradU)
 
     bound(k_, k0());
 
-    nuSgs_ = ck(D)*sqrt(k_)*delta();
-    nuSgs_.correctBoundaryConditions();
+    updateSubGridScaleFields(D);
 }
 
 
diff --git a/src/turbulenceModels/incompressible/LES/dynOneEqEddy/dynOneEqEddy.H b/src/turbulenceModels/incompressible/LES/dynOneEqEddy/dynOneEqEddy.H
index b8cb1da31236fcf7ff813c91cbb527795d11f4bf..17ed2c62adb6e2df1322a4cbfa531557c3219cf7 100644
--- a/src/turbulenceModels/incompressible/LES/dynOneEqEddy/dynOneEqEddy.H
+++ b/src/turbulenceModels/incompressible/LES/dynOneEqEddy/dynOneEqEddy.H
@@ -87,6 +87,9 @@ class dynOneEqEddy
 
     // Private Member Functions
 
+        //- Update sub-grid scale fields
+        void updateSubGridScaleFields(const volSymmTensorField& D);
+
         //- Calculate ck, ce by filtering the velocity field U.
         dimensionedScalar ck(const volSymmTensorField& D) const;
         dimensionedScalar ce(const volSymmTensorField& D) const;
diff --git a/src/turbulenceModels/incompressible/LES/dynSmagorinsky/dynSmagorinsky.C b/src/turbulenceModels/incompressible/LES/dynSmagorinsky/dynSmagorinsky.C
index 6d1f711956477f55cf12bb905c50b49a4754bdc4..e260a6d16d81154d59b53d18934e44895ab6ae83 100644
--- a/src/turbulenceModels/incompressible/LES/dynSmagorinsky/dynSmagorinsky.C
+++ b/src/turbulenceModels/incompressible/LES/dynSmagorinsky/dynSmagorinsky.C
@@ -43,6 +43,13 @@ addToRunTimeSelectionTable(LESModel, dynSmagorinsky, dictionary);
 
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
+void dynSmagorinsky::updateSubGridScaleFields(const volSymmTensorField& D)
+{
+    nuSgs_ = cD(D)*sqr(delta())*sqrt(magSqr(D));
+    nuSgs_.correctBoundaryConditions();
+}
+
+
 dimensionedScalar dynSmagorinsky::cD(const volSymmTensorField& D) const
 {
     volSymmTensorField LL = dev(filter_(sqr(U())) - (sqr(filter_(U()))));
@@ -111,6 +118,8 @@ dynSmagorinsky::dynSmagorinsky
     filterPtr_(LESfilter::New(U.mesh(), coeffDict())),
     filter_(filterPtr_())
 {
+    updateSubGridScaleFields(dev(symm(fvc::grad(U))));
+
     printCoeffs();
 }
 
@@ -128,12 +137,10 @@ void dynSmagorinsky::correct(const tmp<volTensorField>& gradU)
     LESModel::correct(gradU);
 
     volSymmTensorField D = dev(symm(gradU));
-    volScalarField magSqrD = magSqr(D);
 
-    k_ = cI(D)*sqr(delta())*magSqrD;
+    k_ = cI(D)*sqr(delta())*magSqr(D);
 
-    nuSgs_ = cD(D)*sqr(delta())*sqrt(magSqrD);
-    nuSgs_.correctBoundaryConditions();
+    updateSubGridScaleFields(D);
 }
 
 
diff --git a/src/turbulenceModels/incompressible/LES/dynSmagorinsky/dynSmagorinsky.H b/src/turbulenceModels/incompressible/LES/dynSmagorinsky/dynSmagorinsky.H
index 2fa29ff41a89a221bc6f5a2b28c33c110fb8bb1c..39a6636572c5207855943c1dc731cbd6bfc8811e 100644
--- a/src/turbulenceModels/incompressible/LES/dynSmagorinsky/dynSmagorinsky.H
+++ b/src/turbulenceModels/incompressible/LES/dynSmagorinsky/dynSmagorinsky.H
@@ -96,6 +96,9 @@ class dynSmagorinsky
 
     // Private Member Functions
 
+        //- Update sub-grid scale fields
+        void updateSubGridScaleFields(const volSymmTensorField& D);
+
         //- Calculate coefficients cD, cI from filtering velocity field
         dimensionedScalar cD(const volSymmTensorField& D) const;
         dimensionedScalar cI(const volSymmTensorField& D) const;
diff --git a/src/turbulenceModels/incompressible/LES/kOmegaSSTSAS/kOmegaSSTSAS.C b/src/turbulenceModels/incompressible/LES/kOmegaSSTSAS/kOmegaSSTSAS.C
index 3460137709af70d6b0ca1a33a68ed12d6d2ca84c..b4aca6c7f3160c0bec350b7918c76038b4a50231 100644
--- a/src/turbulenceModels/incompressible/LES/kOmegaSSTSAS/kOmegaSSTSAS.C
+++ b/src/turbulenceModels/incompressible/LES/kOmegaSSTSAS/kOmegaSSTSAS.C
@@ -44,6 +44,13 @@ addToRunTimeSelectionTable(LESModel, kOmegaSSTSAS, dictionary);
 
 // * * * * * * * * * * * * Protected Member Functions  * * * * * * * * * * * //
 
+void kOmegaSSTSAS::updateSubGridScaleFields(const volScalarField& S2)
+{
+    nuSgs_ == a1_*k_/max(a1_*omega_, F2()*sqrt(S2));
+    nuSgs_.correctBoundaryConditions();
+}
+
+
 tmp<volScalarField> kOmegaSSTSAS::F1(const volScalarField& CDkOmega) const
 {
     volScalarField CDkOmegaPlus = max
@@ -304,6 +311,8 @@ kOmegaSSTSAS::kOmegaSSTSAS
         mesh_
     )
 {
+    updateSubGridScaleFields(magSqr(symm(fvc::grad(U))));
+
     printCoeffs();
 }
 
@@ -325,7 +334,8 @@ void kOmegaSSTSAS::correct(const tmp<volTensorField>& gradU)
     volVectorField gradK = fvc::grad(k_);
     volVectorField gradOmega = fvc::grad(omega_);
     volScalarField L = sqrt(k_)/(pow(Cmu_, 0.25)*(omega_ + omegaSmall_));
-    volScalarField CDkOmega = (2.0*alphaOmega2_)*(gradK & gradOmega)/(omega_ + omegaSmall_);
+    volScalarField CDkOmega =
+        (2.0*alphaOmega2_)*(gradK & gradOmega)/(omega_ + omegaSmall_);
     volScalarField F1 = this->F1(CDkOmega);
     volScalarField G = nuSgs_*2.0*S2;
 
@@ -375,7 +385,8 @@ void kOmegaSSTSAS::correct(const tmp<volTensorField>& gradU)
            *max
             (
                 dimensionedScalar("zero",dimensionSet(0, 0 , -2, 0, 0),0. ),
-                zetaTilda2_*kappa_*S2*(L/Lvk2(S2))- 2.0/alphaPhi_*k_*grad_omega_k
+                zetaTilda2_*kappa_*S2*(L/Lvk2(S2))
+              - 2.0/alphaPhi_*k_*grad_omega_k
             )
         );
 
@@ -384,9 +395,7 @@ void kOmegaSSTSAS::correct(const tmp<volTensorField>& gradU)
     }
     bound(omega_, omega0_);
 
-    // Re-calculate viscosity
-    nuSgs_ == a1_*k_/max(a1_*omega_, F2()*sqrt(S2));
-    nuSgs_.correctBoundaryConditions();
+    updateSubGridScaleFields(S2);
 }
 
 
diff --git a/src/turbulenceModels/incompressible/LES/kOmegaSSTSAS/kOmegaSSTSAS.H b/src/turbulenceModels/incompressible/LES/kOmegaSSTSAS/kOmegaSSTSAS.H
index 56e395ff4cc422c71d99847e7079b656b5b893f3..e5b03aef68b1f009a4a7b94e5a4f9f348b1c133b 100644
--- a/src/turbulenceModels/incompressible/LES/kOmegaSSTSAS/kOmegaSSTSAS.H
+++ b/src/turbulenceModels/incompressible/LES/kOmegaSSTSAS/kOmegaSSTSAS.H
@@ -62,6 +62,9 @@ class kOmegaSSTSAS
 {
     // Private member functions
 
+        //- Update sub-grid scale fields
+        void updateSubGridScaleFields(const volScalarField& D);
+
         // Disallow default bitwise copy construct and assignment
         kOmegaSSTSAS(const kOmegaSSTSAS&);
         kOmegaSSTSAS& operator=(const kOmegaSSTSAS&);
@@ -237,7 +240,8 @@ public:
         //  i.e. the additional term in the filtered NSE.
         virtual tmp<fvVectorMatrix> divDevBeff(volVectorField& U) const;
 
-        //- Solve the turbulence equations (k-w) and correct the turbulence viscosity
+        //- Solve the turbulence equations (k-w) and correct the turbulence
+        //  viscosity
         virtual void correct(const tmp<volTensorField>& gradU);
 
         //- Read turbulenceProperties dictionary
diff --git a/src/turbulenceModels/incompressible/LES/locDynOneEqEddy/locDynOneEqEddy.C b/src/turbulenceModels/incompressible/LES/locDynOneEqEddy/locDynOneEqEddy.C
index a195723af76e8e8cbf69b24aea0750b3ca8913d2..7d34bbb981fca78aeb8e459390139fe5c403592d 100644
--- a/src/turbulenceModels/incompressible/LES/locDynOneEqEddy/locDynOneEqEddy.C
+++ b/src/turbulenceModels/incompressible/LES/locDynOneEqEddy/locDynOneEqEddy.C
@@ -43,6 +43,17 @@ addToRunTimeSelectionTable(LESModel, locDynOneEqEddy, dictionary);
 
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
+void locDynOneEqEddy::updateSubGridScaleFields
+(
+    const volSymmTensorField& D,
+    const volScalarField& KK
+)
+{
+    nuSgs_ = ck(D, KK)*sqrt(k_)*delta();
+    nuSgs_.correctBoundaryConditions();
+}
+
+
 volScalarField locDynOneEqEddy::ck
 (
     const volSymmTensorField& D,
@@ -108,6 +119,9 @@ locDynOneEqEddy::locDynOneEqEddy
     filterPtr_(LESfilter::New(U.mesh(), coeffDict())),
     filter_(filterPtr_())
 {
+    volScalarField KK = 0.5*(filter_(magSqr(U)) - magSqr(filter_(U)));
+    updateSubGridScaleFields(symm(fvc::grad(U)), KK);
+
     printCoeffs();
 }
 
@@ -146,8 +160,7 @@ void locDynOneEqEddy::correct(const tmp<volTensorField>& gradU)
 
     bound(k_, k0());
 
-    nuSgs_ = ck(D, KK)*sqrt(k_)*delta();
-    nuSgs_.correctBoundaryConditions();
+    updateSubGridScaleFields(D, KK);
 }
 
 
diff --git a/src/turbulenceModels/incompressible/LES/locDynOneEqEddy/locDynOneEqEddy.H b/src/turbulenceModels/incompressible/LES/locDynOneEqEddy/locDynOneEqEddy.H
index 6b142c4e377755fe3ae5d889a96d9bc9a4f4d93a..4848c6492ed62d76cc5965e9002983673f21f487 100644
--- a/src/turbulenceModels/incompressible/LES/locDynOneEqEddy/locDynOneEqEddy.H
+++ b/src/turbulenceModels/incompressible/LES/locDynOneEqEddy/locDynOneEqEddy.H
@@ -96,6 +96,13 @@ class locDynOneEqEddy
 
     // Private Member Functions
 
+        //- Update sub-grid scale fields
+        void updateSubGridScaleFields
+        (
+            const volSymmTensorField& D,
+            const volScalarField& KK
+        );
+
         //- Calculate ck, ce by filtering the velocity field U.
         volScalarField ck
         (
diff --git a/src/turbulenceModels/incompressible/LES/oneEqEddy/oneEqEddy.C b/src/turbulenceModels/incompressible/LES/oneEqEddy/oneEqEddy.C
index da55eeb949897eb44c0cd8043e7ac84e0f033fab..d6a5de4ed496d8cff12681fe41284a21a3f9976d 100644
--- a/src/turbulenceModels/incompressible/LES/oneEqEddy/oneEqEddy.C
+++ b/src/turbulenceModels/incompressible/LES/oneEqEddy/oneEqEddy.C
@@ -41,6 +41,16 @@ namespace LESModels
 defineTypeNameAndDebug(oneEqEddy, 0);
 addToRunTimeSelectionTable(LESModel, oneEqEddy, dictionary);
 
+
+// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
+
+void oneEqEddy::updateSubGridScaleFields()
+{
+    nuSgs_ = ck_*sqrt(k_)*delta();
+    nuSgs_.correctBoundaryConditions();
+}
+
+
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
 oneEqEddy::oneEqEddy
@@ -76,6 +86,8 @@ oneEqEddy::oneEqEddy
         )
     )
 {
+    updateSubGridScaleFields();
+
     printCoeffs();
 }
 
@@ -103,8 +115,7 @@ void oneEqEddy::correct(const tmp<volTensorField>& gradU)
 
     bound(k_, k0());
 
-    nuSgs_ = ck_*sqrt(k_)*delta();
-    nuSgs_.correctBoundaryConditions();
+    updateSubGridScaleFields();
 }
 
 
diff --git a/src/turbulenceModels/incompressible/LES/oneEqEddy/oneEqEddy.H b/src/turbulenceModels/incompressible/LES/oneEqEddy/oneEqEddy.H
index 65b01ca4792794f8e8983781ae5c01e8c1caf381..c060f82d67b743245518b777799c11759904328f 100644
--- a/src/turbulenceModels/incompressible/LES/oneEqEddy/oneEqEddy.H
+++ b/src/turbulenceModels/incompressible/LES/oneEqEddy/oneEqEddy.H
@@ -83,6 +83,9 @@ class oneEqEddy
 
     // Private Member Functions
 
+        //- Update sub-grid scale fields
+        void updateSubGridScaleFields();
+
         // Disallow default bitwise copy construct and assignment
         oneEqEddy(const oneEqEddy&);
         oneEqEddy& operator=(const oneEqEddy&);
diff --git a/src/turbulenceModels/incompressible/LES/spectEddyVisc/spectEddyVisc.C b/src/turbulenceModels/incompressible/LES/spectEddyVisc/spectEddyVisc.C
index 28a563b4c6c3ba88b6d098881aa6ae174f81b6e0..4d8a7edc44100e51eec6e3771aca832dbb85588c 100644
--- a/src/turbulenceModels/incompressible/LES/spectEddyVisc/spectEddyVisc.C
+++ b/src/turbulenceModels/incompressible/LES/spectEddyVisc/spectEddyVisc.C
@@ -41,6 +41,25 @@ namespace LESModels
 defineTypeNameAndDebug(spectEddyVisc, 0);
 addToRunTimeSelectionTable(LESModel, spectEddyVisc, dictionary);
 
+// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
+
+void spectEddyVisc::updateSubGridScaleFields(const volTensorField& gradU)
+{
+    volScalarField Re = sqr(delta())*mag(symm(gradU))/nu();
+    for (label i=0; i<5; i++)
+    {
+        nuSgs_ =
+            nu()
+           /(
+                 scalar(1)
+               - exp(-cB_*pow(nu()/(nuSgs_ + nu()), 1.0/3.0)*pow(Re, -2.0/3.0))
+            );
+    }
+
+    nuSgs_.correctBoundaryConditions();
+}
+
+
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
 spectEddyVisc::spectEddyVisc
@@ -101,6 +120,8 @@ spectEddyVisc::spectEddyVisc
     )
 {
     printCoeffs();
+
+    updateSubGridScaleFields(fvc::grad(U));
 }
 
 
@@ -121,20 +142,7 @@ tmp<volScalarField> spectEddyVisc::k() const
 void spectEddyVisc::correct(const tmp<volTensorField>& gradU)
 {
     GenEddyVisc::correct(gradU);
-
-    volScalarField Re = sqr(delta())*mag(symm(gradU))/nu();
-
-    for (label i=0; i<5; i++)
-    {
-        nuSgs_ =
-            nu()
-           /(
-               scalar(1)
-               - exp(-cB_*pow(nu()/(nuSgs_ + nu()), 1.0/3.0)*pow(Re, -2.0/3.0))
-            );
-    }
-
-    nuSgs_.correctBoundaryConditions();
+    updateSubGridScaleFields(gradU());
 }
 
 
diff --git a/src/turbulenceModels/incompressible/LES/spectEddyVisc/spectEddyVisc.H b/src/turbulenceModels/incompressible/LES/spectEddyVisc/spectEddyVisc.H
index 715b65c4b55a5eb7eb1a777b542f013c687cf6e7..709c9ef07c0c107a291f77b1bca9af5e4cc7843c 100644
--- a/src/turbulenceModels/incompressible/LES/spectEddyVisc/spectEddyVisc.H
+++ b/src/turbulenceModels/incompressible/LES/spectEddyVisc/spectEddyVisc.H
@@ -85,6 +85,9 @@ class spectEddyVisc
 
     // Private Member Functions
 
+        //- Update sub-grid scale fields
+        void updateSubGridScaleFields(const volTensorField& gradU);
+
         // Disallow default bitwise copy construct and assignment
         spectEddyVisc(const spectEddyVisc&);
         spectEddyVisc& operator=(const spectEddyVisc&);
diff --git a/src/turbulenceModels/incompressible/RAS/SpalartAllmaras/SpalartAllmaras.C b/src/turbulenceModels/incompressible/RAS/SpalartAllmaras/SpalartAllmaras.C
index 8da6cd8d618b8e84c7262a05f17a298764bbdef6..d1fa78134adc98d6fdc5fe20818f6bb5b51bb89e 100644
--- a/src/turbulenceModels/incompressible/RAS/SpalartAllmaras/SpalartAllmaras.C
+++ b/src/turbulenceModels/incompressible/RAS/SpalartAllmaras/SpalartAllmaras.C
@@ -63,8 +63,7 @@ tmp<volScalarField> SpalartAllmaras::fv2
     const volScalarField& fv1
 ) const
 {
-    return 1.0 - chi/(1.0 + chi*fv1);
-    //return 1.0/pow3(scalar(1) + chi/Cv2);
+    return 1.0/pow3(scalar(1) + chi/Cv2_);
 }
 
 
diff --git a/wmake/rules/SunOS64Gcc/X b/wmake/rules/SunOS64Gcc/X
new file mode 100644
index 0000000000000000000000000000000000000000..5d1f9c5cc54b4689118c6f1f54f0a2d6d7a29827
--- /dev/null
+++ b/wmake/rules/SunOS64Gcc/X
@@ -0,0 +1,3 @@
+XFLAGS     =
+XINC       = $(XFLAGS) -I/usr/X11R6/include
+XLIBS      = -L/usr/X11R6/lib64 -lXext -lX11
diff --git a/wmake/rules/SunOS64Gcc/c b/wmake/rules/SunOS64Gcc/c
new file mode 100644
index 0000000000000000000000000000000000000000..80bb80f32f7f8fbcde52fb290d9ec0ec7f0ea603
--- /dev/null
+++ b/wmake/rules/SunOS64Gcc/c
@@ -0,0 +1,16 @@
+.SUFFIXES: .c .h
+
+cWARN        = -Wall
+
+cc          = gcc -m64
+
+include $(RULES)/c$(WM_COMPILE_OPTION)
+
+cFLAGS      = $(GFLAGS) $(cWARN) $(cOPT) $(cDBUG) $(LIB_HEADER_DIRS) -fPIC
+
+ctoo        = $(WM_SCHEDULER) $(cc) $(cFLAGS) -c $$SOURCE -o $@
+
+LINK_LIBS   = $(cDBUG)
+
+LINKLIBSO   = $(cc) -shared
+LINKEXE     = $(cc) -Xlinker -z -Xlinker nodefs
diff --git a/wmake/rules/SunOS64Gcc/c++ b/wmake/rules/SunOS64Gcc/c++
new file mode 100644
index 0000000000000000000000000000000000000000..36b5c29b20b6297dcc3d42dcc5b46342cd34a116
--- /dev/null
+++ b/wmake/rules/SunOS64Gcc/c++
@@ -0,0 +1,21 @@
+.SUFFIXES: .C .cxx .cc .cpp
+
+c++WARN     = -Wall -Wno-strict-aliasing -Wextra -Wno-unused-parameter -Wold-style-cast
+
+CC          = g++ -m64
+
+include $(RULES)/c++$(WM_COMPILE_OPTION)
+
+ptFLAGS     = -DNoRepository -ftemplate-depth-40
+
+c++FLAGS    = $(GFLAGS) $(c++WARN) $(c++OPT) $(c++DBUG) $(ptFLAGS) $(LIB_HEADER_DIRS) -fPIC
+
+Ctoo        = $(WM_SCHEDULER) $(CC) $(c++FLAGS) -c $$SOURCE -o $@
+cxxtoo      = $(Ctoo)
+cctoo       = $(Ctoo)
+cpptoo      = $(Ctoo)
+
+LINK_LIBS   = $(c++DBUG)
+
+LINKLIBSO   = $(CC) $(c++FLAGS) -shared
+LINKEXE     = $(CC) $(c++FLAGS)
diff --git a/wmake/rules/SunOS64Gcc/c++Debug b/wmake/rules/SunOS64Gcc/c++Debug
new file mode 100644
index 0000000000000000000000000000000000000000..19bdb9c3346fc7a69380dfedd6e7911fe220a965
--- /dev/null
+++ b/wmake/rules/SunOS64Gcc/c++Debug
@@ -0,0 +1,2 @@
+c++DBUG    = -ggdb3 -DFULLDEBUG
+c++OPT      = -O0 -fdefault-inline
diff --git a/wmake/rules/SunOS64Gcc/c++Opt b/wmake/rules/SunOS64Gcc/c++Opt
new file mode 100644
index 0000000000000000000000000000000000000000..4cb95b5b3a9781b6508214a4ea55cf0930d2c9f4
--- /dev/null
+++ b/wmake/rules/SunOS64Gcc/c++Opt
@@ -0,0 +1,2 @@
+c++DBUG     = 
+c++OPT      = -O3
diff --git a/wmake/rules/SunOS64Gcc/c++Prof b/wmake/rules/SunOS64Gcc/c++Prof
new file mode 100644
index 0000000000000000000000000000000000000000..3bda4dad55e898a8198f6e8bfe21e8d829d7230a
--- /dev/null
+++ b/wmake/rules/SunOS64Gcc/c++Prof
@@ -0,0 +1,2 @@
+c++DBUG    = -pg
+c++OPT     = -O2
diff --git a/wmake/rules/SunOS64Gcc/cDebug b/wmake/rules/SunOS64Gcc/cDebug
new file mode 100644
index 0000000000000000000000000000000000000000..72b638f458220e329d52b59e3566a3c807101f9d
--- /dev/null
+++ b/wmake/rules/SunOS64Gcc/cDebug
@@ -0,0 +1,2 @@
+cDBUG       = -ggdb -DFULLDEBUG
+cOPT        = -O1 -fdefault-inline -finline-functions
diff --git a/wmake/rules/SunOS64Gcc/cOpt b/wmake/rules/SunOS64Gcc/cOpt
new file mode 100644
index 0000000000000000000000000000000000000000..aaaebef3d3e351358499981b5d4ef1dd2caace7b
--- /dev/null
+++ b/wmake/rules/SunOS64Gcc/cOpt
@@ -0,0 +1,2 @@
+cDBUG       = 
+cOPT        = -O3 -fno-gcse
diff --git a/wmake/rules/SunOS64Gcc/cProf b/wmake/rules/SunOS64Gcc/cProf
new file mode 100644
index 0000000000000000000000000000000000000000..ca3ac9bf5f0cd61fe99e0f05fa1bd4bdf9fa6cf7
--- /dev/null
+++ b/wmake/rules/SunOS64Gcc/cProf
@@ -0,0 +1,2 @@
+cDBUG       = -pg
+cOPT        = -O2
diff --git a/wmake/rules/SunOS64Gcc/general b/wmake/rules/SunOS64Gcc/general
new file mode 100644
index 0000000000000000000000000000000000000000..70ee588d82de5943cd89d28acc2703bf3476940b
--- /dev/null
+++ b/wmake/rules/SunOS64Gcc/general
@@ -0,0 +1,11 @@
+CPP        = /lib/cpp $(GFLAGS)
+LD         = ld -64
+
+PROJECT_LIBS = -l$(WM_PROJECT) -liberty -lnsl -lsocket -L$(FOAM_LIBBIN)/dummy -lPstream 
+
+include $(GENERAL_RULES)/standard
+
+include $(RULES)/X
+include $(RULES)/c
+include $(RULES)/c++
+include $(GENERAL_RULES)/cint
diff --git a/wmake/rules/SunOS64Gcc/mplib b/wmake/rules/SunOS64Gcc/mplib
new file mode 100644
index 0000000000000000000000000000000000000000..8a84b4014695e82f55b709ed5144f4b528412137
--- /dev/null
+++ b/wmake/rules/SunOS64Gcc/mplib
@@ -0,0 +1,3 @@
+PFLAGS     = 
+PINC       = 
+PLIBS      = 
diff --git a/wmake/rules/SunOS64Gcc/mplibFJMPI b/wmake/rules/SunOS64Gcc/mplibFJMPI
new file mode 100644
index 0000000000000000000000000000000000000000..2d6c16797a8df9aa3aa92ca12cfbaedb873e1af3
--- /dev/null
+++ b/wmake/rules/SunOS64Gcc/mplibFJMPI
@@ -0,0 +1,3 @@
+PFLAGS     =
+PINC       = -I$(MPI_ARCH_PATH)/include/sparcv9/mpi -DMPIPP_H
+PLIBS      = -L$(MPI_ARCH_PATH)/lib/sparcv9 -lmpi_f -L/opt/FSUNf90/lib/sparcv9 -lfjgmp64 -L/opt/FJSVpnidt/lib -lfjidt -ljrm -lfj90i -lfj90f -lfj90fmt  -lelf
diff --git a/wmake/rules/SunOS64Gcc/mplibOPENMPI b/wmake/rules/SunOS64Gcc/mplibOPENMPI
new file mode 100644
index 0000000000000000000000000000000000000000..834d2d3e22aaebee233a19b139b6d99a4d457cf7
--- /dev/null
+++ b/wmake/rules/SunOS64Gcc/mplibOPENMPI
@@ -0,0 +1,3 @@
+PFLAGS     = -DOMPI_SKIP_MPICXX
+PINC       = -I$(MPI_ARCH_PATH)/include
+PLIBS      = -L$(MPI_ARCH_PATH)/lib -lmpi
diff --git a/wmake/wmake b/wmake/wmake
index 61307c11802b4dd4f011ab1bb428f9354d6609b3..911e7fbc30561127055b155247ec9c1a4b0d0dcc 100755
--- a/wmake/wmake
+++ b/wmake/wmake
@@ -163,8 +163,9 @@ then
         exit $?
     elif [ ! -d $MakeDir ]
     then
-        $make -k -f $WM_DIR/MakefileApps \
-            FOAM_APPS="`find . -maxdepth 1 \( -type d -a ! -name "." -a ! -name "Optional" -a ! -name "Make" \)  -printf "%f "`"
+        #FOAM_APPS=`find . -maxdepth 1 \( -type d -a ! -name "." -a ! -name "Optional" -a ! -name "Make" \)  -printf "%f "`
+        FOAM_APPS=`for d in *; do if [ -d "$d" -a "$d" != "Optional" -a "$d" != "Make" ]; then echo "$d"; fi; done | xargs`
+        $make -k -f $WM_DIR/MakefileApps FOAM_APPS="$FOAM_APPS"
         exit $?
     fi